1. 恶意文件的传统检测方法
恶意文件检测在机器学习方法流行之前,一直是杀毒引擎的黑箱技术,很少为外界所周知。对于一般粗浅的应用者而言,最简单的做法是有两种:
1. 寻找各种开源的病毒库或者威胁情报网站,收集恶意文件的MD5值,作为黑名单使用。
2. 同时集成各种知名的杀毒软件或者沙箱,然后保存每个杀毒软件或沙箱对恶意文件的执行结果,然后综合所有的执行结果做综合判定:设置判定规则,或者用机器学习的方法做模型判定。
2. 机器学习的恶意文件检测
那么更智能的机器学习方法如何做恶意文件检测呢?论文《Deep Neural Network Based Malware Detection Using Two Dimensional Binary Program Features》给出了使用深度学习检测恶意程序的具体方法,在论文中他们描述了具体的特征提取方法,并在约40万程序上进行了测试,检出率达到95%,误报率为0.1%。
随后《Web安全之强化学习与GAN》一书总结了上述论文的特征提取方法,以及如何用Python工具做具体的实现。这里作为读书笔记记录如此,便于以后温故而知新。
2.1 PE首部特征提取
2.1.1 特征直方图
本质上PE文件也是二进制文件,可以当作一连串字节组成的文件。字节直方图又称为ByteHistogram,它的核心思想是,定义一个长度为256维的向量,每个向量依次为0x00,0x01一直到0xFF,分别代表 PE文件中0x00,0x01一直到0xFF对应的个数。例如经过统计,0x01有两个,0x03和0x05对应的各一个,假设直方图维度为8,所以对应的直方图为:[0,2,0,1,0,0,1,0,0]
Python中实现自己直方图非常方便,主要是numPy提供了一个非常强大的函数:
numpy.bincount(x, weights=None, minlength=None)
numpy.bincount专门用于以字节为单位统计个数,比如统计0~7出现的个数:
>>> np.bincount(np.array([0, 1, 1, 3, 2, 1, 7])) array([1, 3, 1, 1, 0, 0, 0, 1], dtype=int32)
其中, minlength参数用于指定返回的统计数组的最小长度,不足最小长度的会自动补0,比如统计0~7出现的个数,但是指定minlength为10:
>>> np.bincount(np.array([0, 1, 1, 3, 2, 1, 7]),minlength=10) array([1, 3, 1, 1, 0, 0, 0, 1, 0, 0], dtype=int32)
实际使用时,单纯统计直方图非常容易过拟合,因为字节直方图对于PE文件的二进制特征过于依赖,PE文件增加一个无意义的0字节都会改变直方图;另外PE文件中不同字节的数量可能差别很大,数 量占优势的字节可能会大大弱化其他字节对结果的影响,所以需要对直方图进行标准化处理。一种常见的处理方式是,增加一个维度的变量&#