病毒分析流程及特征提取

0x10 病毒分析的过程

0x11 样本分析

0x12 行为分析

0x13 查杀方法

##0x20 病毒特征的提取

0x21 为什么要提取病毒特征?

简单而直白:最直接的判断所感染的东西是否为病毒,为了更好的对病毒进行查杀。

0x22 病毒特征提取的方法

0x220 利用哈希值作为病毒的特征

比如计算出病毒的MD5,这样只要遇到相同MD5的文件,就可以将其判定为病毒,这也是目前云查杀所倚重的方式。
这种方式最大的缺点是,病毒与特征之间是一对一的关系,即便病毒仅仅发生了一个字节的变化,那么这个特征也就失效了。

0x221 选取病毒内部的特征字符串

比如“熊猫烧香”里面的whboy还有其它一些特色字符,只要发现目标程序中有这些字符,则判定为病毒。这种方式相对于利用哈希值作为特征,具有更好的通杀性,但是如果病毒作者修改了自身的名称,那也就能够轻易躲避掉这种查杀方式了。

0x222 双重校验和

其实这种方法类似于上述方法的集合,也就是在病毒文件内部选取两个位置(这两个位置可以是特色字符也可以是特色代码),计算这两段位置的哈希值作为特征。这种方法的好处是,不论选取多长的特征,那么最终生成的哈希值是固定的,这样就便于存储。

0x223 选取病毒内部的特色代码

事实上0到2这几种方式,都是比较初级的方法,接下来以几个实列,说明怎么才是一个相对较好的病毒特征。

实列一

有位朋友在文章的最后,选取了这样一条特征码:

1
2
3
Ghijkl Nopqrstu Wxy #特征值
4768696A6B6C204E6F70717273747520577879 #对应的hex

其实这条特征选取的就是病毒体内的特色字符串,将其转化为ASCII码的形式作为特征。但是这类以病毒“名称”作为特征的方法,最大的问题是通用性不好,病毒只要稍微修改一下自身的名称,那么这条特征也就失效了。利用病毒名称作为特征,也仅仅是比利用哈希值作为特征要稍微强一些。而我们其实还是希望能够利用最少的特征匹配到更多的文件,要具备通用性,还要尽可能地没有误报。所以可以考虑利用病毒体内比较有特色的代码作为特征,举例来说,对于这个病毒而言,它有这样一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.00403651: C645F84F mov b,[ebp][-8],04F ;'O'
.00403655: C645F970 mov b,[ebp][-7],070 ;'p'
.00403659: C645FA65 mov b,[ebp][-6],065 ;'e'
.0040365D: C645FB6E mov b,[ebp][-5],06E ;'n'
#下面一段
.00403899: C645A457 mov b,[ebp][-05C],057 ;'W'
.0040389D: C645A572 mov b,[ebp][-05B],072 ;'r'
.004038A1: C645A669 mov b,[ebp][-05A],069 ;'i'
.004038A5: C645A774 mov b,[ebp][-059],074 ;'t'
.004038A9: C645A865 mov b,[ebp][-058],065 ;'e'
.004038AD: C645A946 mov b,[ebp][-057],046 ;'F'
.004038B1: C645AA69 mov b,[ebp][-056],069 ;'i'
.004038B5: C645AB6C mov b,[ebp][-055],06C ;'l'
.004038B9: C645AC65 mov b,[ebp][-054],065 ;'e'

特征选取

其实这里就可以把第一段代码中的C645F84FC645F970C645FA65C645FB6E作为特征。

通用性考虑

考虑到通用性,还需要把地址,比如“b,[ebp][-8]”中的“[-8]”,也就是十六进制的F8利用通配符代替,因此这条特征最终可以这样写:

C645??4FC645??70C645??65C645??6E

那么这就是一条通杀性比较强的特征了。

在我每天分析的病毒样本中,利用这种逐个字符放到缓冲区的情况,还是比较常见的,因此这是非常好的特征,能够应对千千万万的未知病毒了。
这个木马中类似的写法还有不少,可以多提取几条,用“or”连接。假设程序中一共有五个地方采用了这种形式,那么可以取舍一下,比如出现三次就报毒,这样通杀性就更强了。
另外,如果程序是利用自己发明的算法生成的文件名,那么这个算法所对应的十六进制代码,也可以提取出来作为特征,这也是很强的特征。可以很好地查杀这一类的木马病毒。而且一般来说还不会造成误报。
当然了,这种方法有个前提,就是目标文件没有被加壳,如果是加壳的情况,那么就需要结合自动脱壳程序或者sandbox来首先脱壳,再进行特征提取并查杀了。
这里既然提到了sandbox,那么我还想讲讲另一种动态的查杀方法,也就是结合sandbox所跑出来的日志文件,选取合适的特征。举个例子来说,之前遇到过一种叫做“永恒之石”的勒索病毒,可以跑出类似这样一段日志:

1
2
3
4
5
6
7
8
System.IO.Directory.CreateDirectory("C:\\Program Files\\Microsoft Updates")
...
System.String.Intern()["\\svchost.exe"]
...
System.String.Concat()["C:\\Program Files\\Microsoft Updates\\svchost.exe"]
...
Stetem.IO.FileExists("C:\\Program Files\\Microsoft Updates\\svchost.exe")
...

这段日志所监控到的是,病毒在C:\Program Files\目录里面创建了名为Microsoft Updates的文件夹,然后在其中又创建了名为svchost.exe的文件(实际上svchost.exe就是病毒自身复制过去隐藏的)。其实这就是非常可疑的行为了,正常程序不会这么干,那么就可以写出这样的特征:

1
2
3
4
5
createDir = System.IO.Directory.CreateDirectory("C:\Program Files\Microsoft Updates")
createFile = System.String.Concat()["C:\Program Files\Microsoft Updates\svchost.exe"]
Detect = **createDir -> createFile

也就是只要出现Detect这样的序列,那么就直接报毒了。当然了,为了严谨起见,可以多选取几个类似于这样的特征。
以上就是我在实际工作中积累的一些经验,希望能够对大家有所帮助。

Comments

2018-02-17

⬆︎TOP