聊聊怎样才算是好的病毒特征
最近在网上看了不少朋友的病毒分析文章,感觉写得都非常不错。他们的分析过程已经非常完美,无懈可击,有的朋友甚至还会在文章的后面附上病毒的查杀方法,甚至还专门为病毒写了特征,用于查杀。这都是有别于我刚开始写病毒分析文章时候的一些特色所在(或者说大家在文章的写法上也是愈加成熟)。不过说到这个病毒特征,我看了大家选取的位置不免有些感慨,因为假设按照我最初的眼光来看,这些特征无疑都是很不错的,但是经过了这段时间以来的摸爬滚打,我渐渐也对病毒特征有了自己的理解,因此就打算专门来和大家聊聊这个话题。
我曾经在自学阶段,写过一篇文章,专门讨论选取病毒特征的几种方法,这里不妨再给大家回顾一下:
1、利用哈希值作为病毒特征
比如计算出病毒的MD5,这样只要遇到相同MD5的文件,就可以将其判定为病毒,这也是目前云查杀所倚重的方式。这种方式最大的缺点是,病毒与特征之间是一对一的关系,即便病毒仅仅发生了一个字节的变化,那么这个特征也就失效了。
2、选取病毒内部的特征字符串
比如“熊猫烧香”里面的whboy还有其它一些特色字符,只要发现目标程序中有这些字符,则判定为病毒。这种方式相对于利用哈希值作为特征,具有更好的通杀性,但是如果病毒作者修改了自身的名称,那也就能够轻易躲避掉这种查杀方式了。
3、选取病毒内部的特色代码
这种方法我在接下来会通过一个实际的例子分析一下。
4、双重校验和
其实这种方法类似于上述方法的集合,也就是在病毒文件内部选取两个位置(这两个位置可以是特色字符也可以是特色代码),计算这两段位置的哈希值作为特征。这种方法的好处是,不论选取多长的特征,那么最终生成的哈希值是固定的,这样就便于存储。
以上回顾的这四种方式,是我当初在自学时候所总结的,也是目前的杀毒软件所倚重的方法。但事实上,这几种方法还是比较初级比较简单的,下面我想结合一个具体的例子来给大家讲讲,什么才是相对较好的病毒特征。
有位朋友在文章的最后,选取了这样一条特征码:
【Ghijkl Nopqrstu Wxy】对应hex 【4768696A6B6C204E6F70717273747520577879】
其实这条特征选取的就是病毒体内的特色字符串,将其转化为ASCII码的形式作为特征。但是这类以病毒“名称”作为特征的方法,最大的问题是通用性不好,病毒只要稍微修改一下自身的名称,那么这条特征也就失效了。利用病毒名称作为特征,也仅仅是比利用哈希值作为特征要稍微强一些。而我们其实还是希望能够利用最少的特征匹配到更多的文件,要具备通用性,还要尽可能地没有误报。所以可以考虑利用病毒体内比较有特色的代码作为特征,举例来说,对于这个病毒而言,它有这样一段代码:
.00403651: C645F84F mov b,[-8],04F ;'O'
.00403655: C645F970 mov b,[-7],070 ;'p'
.00403659: C645FA65 mov b,[-6],065 ;'e'
.0040365D: C645FB6E mov b,[-5],06E ;'n'
或者:
.00403899: C645A457 mov b,[-05C],057 ;'W'
.0040389D: C645A572 mov b,[-05B],072 ;'r'
.004038A1: C645A669 mov b,[-05A],069 ;'i'
.004038A5: C645A774 mov b,[-059],074 ;'t'
.004038A9: C645A865 mov b,[-058],065 ;'e'
.004038AD: C645A946 mov b,[-057],046 ;'F'
.004038B1: C645AA69 mov b,[-056],069 ;'i'
.004038B5: C645AB6C mov b,[-055],06C ;'l'
.004038B9: C645AC65 mov b,[-054],065 ;'e'
其实这里就可以把第一段代码中的“C645F84FC645F970C645FA65C645FB6E”作为特征,考虑到通用性,还需要把地址,比如“b,[-8]”中的“[-8]”,也就是十六进制的F8利用通配符代替,因此这条特征最终可以这样写“C645??4FC645??70C645??65C645??6E”
那么这就是一条通杀性比较强的特征了。在我每天分析的病毒样本中,利用这种逐个字符放到缓冲区的情况,还是比较常见的,因此这是非常好的特征,能够应对千千万万的未知病毒了。
这个木马中类似的写法还有不少,可以多提取几条,用“or”连接。假设程序中一共有五个地方采用了这种形式,那么可以取舍一下,比如出现三次就报毒,这样通杀性就更强了。
另外,如果程序是利用自己发明的算法生成的文件名,那么这个算法所对应的十六进制代码,也可以提取出来作为特征,这也是很强的特征。可以很好地查杀这一类的木马病毒。而且一般来说还不会造成误报。
当然了,这种方法有个前提,就是目标文件没有被加壳,如果是加壳的情况,那么就需要结合自动脱壳程序或者sandbox来首先脱壳,再进行特征提取并查杀了。
这里既然提到了sandbox,那么我还想讲讲另一种动态的查杀方法,也就是结合sandbox所跑出来的日志文件,选取合适的特征。举个例子来说,之前遇到过一种叫做“永恒之石”的勒索病毒,可以跑出类似这样一段日志:
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就是病毒自身复制过去隐藏的)。其实这就是非常可疑的行为了,正常程序不会这么干,那么就可以写出这样的特征:
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这样的序列,那么就直接报毒了。当然了,为了严谨起见,可以多选取几个类似于这样的特征。
以上就是我在实际工作中积累的一些经验,希望能够对大家有所帮助。
感觉文中提到的杀毒方法都很LOW
误报以及查杀率都不高
我想象中理想的杀毒应该是HOOK掉系统的函数
然后接管函数的调用判断是否危险病毒操作 不过这样的工作量也很大而且界定是否危险动作也很难处理
反正就这样吧 我又不做杀毒软件.. 大部分病毒库都是对一些特征检测,有时候找特征确实挺费劲 比如加壳的。 无阻 发表于 2017-5-25 22:39
感觉文中提到的杀毒方法都很LOW
误报以及查杀率都不高
你这种判断是否有危险动作,这是所有杀毒软件最基本的,也是沙箱干的事情,这些只能给病毒判分,并不能判断其是不是病毒,要判断病毒还得利用楼主说的方法。 看来楼主 是个 反病毒工程师。以后写病毒 会多注意你所涉及的内容 无阻 发表于 2017-5-25 22:39
感觉文中提到的杀毒方法都很LOW
误报以及查杀率都不高
其实你说的方法 我感觉很好。但是 也正如你所说的
工作量大。
误杀率高。
一些正常程序 用 某些 驱动API或者 管理内存 都可能被杀 标记一下晚点看,谢谢分析。 好深奥啊,看的迷迷糊糊 深有启发写得很好 很多自己的东西,详细看看有收获。 确实很有帮助 谢谢分享学习。一直想做病毒来着。{:1_908:}