0x00前言
本文章数据集来自Mandiant对某APT组织样本的整理,分析结果仅做学习探讨之用。
0x01
在本文开始之前,我们首先要明白为什么要做恶意样本的聚类分析。针对APT活动而言,我们需要知道一点,单纯的被动防御是没有胜算的,必须要学会主动防御。什么是主动防御呢?由于APT攻击的特性,总是一点点进行渗透,不会一下子造成大动静,我们要做的就是从其前期的攻击行为中归纳出攻击者的特征、行为,才能帮助我们可以进行更好的防御。而对恶意软件的聚类分析,就是其中不可或缺的一环。通过聚类,我们可以知道哪些恶意软件是属于同一家族的,知道他们可能是同属于某个APT组织等等,这样就方便我们之后针对性地防御、溯源。
那么如何进行恶意软件的聚类分析呢?
最简单的,也是最容易想到的就是通过主机名。我们知道,被投递的恶意软件都必不可少的一个功能就是将窃取的信息回传到攻击者掌控的主机上。一般而言,这些回连的主机名都是硬编码在恶意软件中的。举个简单的例子,我们如果发现有两个恶意软件,都会回连到cfxvrdf@231$$%.dd域名(这个域名不常见又毫无规律可言),那么在相当大的概率上可以断定这两个软件出自同一拨攻击者之手。
根据这一简单的原理,接下来我们将分布介绍如何进行基于回连域名的恶意软件聚类可视化分析。
0x02
第一步是明确如何从二进制文件中提取出主机名。
这里我们使用的是python库pefile从二进制文件中提取可打印的字符串
然后使用正则表达式进行匹配,从字符串中提取主机名。
提取出主机名之后就需要进行可视化聚类操作了。
0x03
第二步开始前,我们先来了解什么是二分网络。
二分网络,是一个所有节点可以划分为两个分区的网络,其中任何一个部分都不包含内部连接。这种类型的网络可以方便展现恶意软件样本之间的共享属性。
如上所示,A表示恶意软件,P表示回连域名。上图中可以看到A1有P1域名和P2域名,A3也有P1和P2域名,如果P1和P2还是不常见的较为特殊的形式,那么我们就可以在很大程度上认为A1和A3是属于统一家族的,可以将它们归类在一起。
再进一步看,如果从P的角度来看A,P1连到A1,A3,P2连到A1,A3;我们自然也可以将P1,P2聚类在一起。
对照着我们的研究而言,我们可以针对域名做聚类,也可以针对二进制文件做聚类,当然,也可以将两者统一在一起。如果用画图进行可视化表示的话,那么我们就可以画出三张图来。
那么问题来了,怎么画图呢?
这里我们使用NetworkX进行画图。具体用法很简单,这里就用几行简单的代码进行说明。
载入networkx库,然后在nodes列表中定义了5个节点,在for循环中调用add_node方法添加节点,然后调用add_edge方法在hello和word两个节点间添加一条边。
最后调用write_dot以dot格式将网络保存。
然后我们使用GraphViz对dot文件进行解析,将其呈现为png文件,命令如下
打开net.png如下所示
最简单的可视化方法就是这么简单,当然还可以加上其他参数,使得绘出的图中添加边或节点的属性、颜色,线段粗细等等。
0x04
学习了可视化的方法之后,我们就可以来进行正式的归类工作了。其实只是在前面的代码的基础上进行自动的建立网络的工作。
如果从二进制文件中提取处了域名,将调用add_node将其添加为节点,然后在恶意软件节点与提取出的域名之间建立边。
这样画出来的网络就是我们的第一张图,图中可以体现恶意软件之间的聚类以及从中提取出的域名。另外,可以画出两种图,一张显示恶意软件之间的关系,一张用于显示域名之间的关系。所以需要添加以下代码
0x05
然后我们进行测试
python test.py …/data a.dot b.dot c.dot
参数依次为恶意文件所在文件夹的路径,以及三张图的dot文件保存位置
运行中的过程如下
然后分别将dot文件解析为png格式的文件
第一张图如下所示
部分放大的局部如下
蓝色椭圆为域名,黑色椭圆为恶意样本。图中将所有从中提取new.new域名的文件都连在了一起。
B.png效果如下
可以很明显看到,将恶意样本根据共享的回连域名特征聚类在一起
C.png如下所示
可以看到,上图体现了域名之间的关系。
0x06
除了域名之外,我们可以直接对可打印字符串作为特征,进行恶意样本之间的聚类。
首先自然就是提取字符串的函数
这里为了进一步提高效率,可以在提取字符串之前,先判断文件是否为可执行文件,判断函数的逻辑很简单,就是看最开始的magic byte是否为MZ
0x07
提取出字符串之后,我们怎么进行归类呢?或者换句话说,满足怎样的条件,我们在两个恶意样本之间添加一条边呢?
这里给出的方法是使用Jaccard系数。
Jaccard系数是一种量化相似性的方法。其计算公式如下
即两个集合A和B交集元素的个数在A、B并集中所占的比例
举个简单的例子:
比如A和B对于三本书的评价为A(1,1,0)和B(1,0,1)。PS:1代表喜欢,0代表不喜欢。可以得到J ≈ 0.3,这就说明两人相似度不高
使用jaccard系数后,会生成一个归一化后的值,这样恶意软件样本之间的相似性比较可以放在相同的尺度上进行。一般取值在0~1.
代码实现如下
这里我们默认设定,Jaccard系数超过0.8则认为A与B相似
首先存储所有从文件中提取的字符串到集合中,并将每个恶意软件通过add_node作为节点加入图中。然后遍历所有恶意软件对,计算其jaccard距离,如果值大于0.8,则在这两个恶意软件之间增加一条边。
最后将dot文件保存。
使用如下
python test.py …/data a.dot
参数分别为恶意软件所在文件夹和要保存的dot文件的位置
运行过程如下
同样将dot文件解析为png图片后如下所示
放大后
以上图为例,可以看到恶意家族很好的聚类在了一起。
这里要说明一下,我们用的样本是已经被Mandiant打好标签了的,而我们在聚类前是不知道上图中的五个文件同属于GREENCAT_s的,在聚类之后与Mandiant打好的标签进行比较,我们可以看出聚类的效果相当不错。
0x08
本文仅是针对安全中最简单的字符串(及域名)特征提取与数据科学结合在一起所在的抛砖引玉的工作,不过相信读者也就可以从中认识到在现在这个时代掌握数据科学对网络安全的重要性。本文代码主体来自http://www.malwaredatascience.com/,由于成文需要有部分改动。
0x09参考
1.《Malware data science–attack detection and attribution》
2.https://zhuanlan.zhihu.com/p/27241148
3.http://blog.sciencenet.cn/blog-404069-338143.html