欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

利用机器学习进行恶意代码分类

来源:本站整理 作者:bindog 时间:2015-08-20 TAG: 我要投稿

 最近在Kaggle上微软发起了一个 恶意代码分类的比赛 ,并提供了超过500G的数据(解压后)。有意思的是,取得第一名的队伍三个人都不是搞安全出身的,所采用的方法与我们常见的方法存在很大不同,展现了机器学习在安全领域的巨大潜力。在仔细读完他们的代码和相关的论文后,我简单的进行了一些总结与大家分享。

需要指出的是,(1)比赛的主题是恶意代码的分类,不是病毒查杀(2)比赛采用的方法是纯静态分析的方法,不涉及行为分析等动态分析方法。

因此这不意味着这个方法能够取代现有的方法,但是了解它能够为安全研究人员提供一个崭新的思路,至于能否在工业界应用仍待进一步研究。

0x01 总览

背景

80年代末期,随着恶意代码的诞生,反恶意代码软件(或称反病毒软件)随之诞生。这个时期的恶意代码所采用的技术较为简单,这使得对应的检测技术也较为容易,早期的反病毒软件大都单一的采用特征匹配的方法,简单的利用特征串完成检测。随着恶意代码技术的发展,恶意代码开始在传播过程中进行变形以躲避查杀,此时同一个恶意代码的变种数量急剧提升,形态较本体也发生了较大的变化,反病毒软件已经很难提取出一段代码作为恶意代码的特征码。在这种情况下,广谱特征码随之诞生,广谱特征码将特征码进行了分段,通过掩码字节对需要进行比较的和不需要进行比较的区段进行划分。然而无论是特征码扫描还是广谱特征,都需要在获得恶意代码样本后,进行特征的提取,随后才能进行检测,这使得对恶意代码的查杀具有一定的滞后性,始终走在恶意代码的后面。为了针对变种病毒和未知病毒,启发式扫描应运而生,启发式扫描利用已有的经验和知识对未知的二进制代码进行检测,这种技术抓住了恶意代码具有普通二进制文件所不具有的恶意行为,例如非常规读写文件,终结自身,非常规切入零环等等。启发式扫描的重点和难点在于如何对恶意代码的恶意行为特征进行提取。特征码扫描、查找广谱特征、启发式扫描,这三种查杀方式均没有实际运行二进制文件,因此均可归为恶意代码静态检测的方法。随着反恶意代码技术的逐步发展,主动防御技术、云查杀技术已越来越多的被安全厂商使用,但恶意代码静态检测的方法仍是效率最高,被运用最广泛的恶意代码查杀技术。

数据格式

微软提供的数据包括训练集、测试集和训练集的标注。其中每个恶意代码样本(去除了PE头)包含两个文件,一个是十六进制表示的 .bytes 文件,另一个是利用IDA反汇编工具生成的 .asm 文件。如下图所示

方法简述

Kaggle比赛中最重要的环节就是特征工程,特征的好坏直接决定了比赛成绩。在这次Kaggle的比赛中冠军队伍选取了三个“黄金”特征:恶意代码图像、 OpCode n-gram 和 Headers 个数,其他一些特征包括 ByteCode n-gram ,指令频数等。机器学习部分采用了随机森林算法,并用到了 xgboost 和 pypy 加快训练速度。

本文主要关注恶意代码图像和 OpCode n-gram ,以及随机森林算法的应用。

0x02 恶意代码图像

这个概念最早是2011年由加利福尼亚大学的 Nataraj 和 Karthikeyan 在他们的论文 Malware Images: Visualization and Automatic Classification 中提出来的,思路非常新颖,把一个二进制文件以灰度图的形式展现出来,利用图像中的纹理特征对恶意代码进行聚类。此后,有许多研究人员在这个思路基础上进行了改进和探索。就目前发表的文章来看,恶意代码图像的形式并不固定,研究人员可根据实际情况进行调整和创新。

国内这方面的研究较少,去年在通信学报上有一篇 《基于纹理指纹的恶意代码变种检测方法研究》 ,是由北京科技大学的韩晓光博士和北京启明星辰研究院等合作发表的,目测也是仅有的一篇。

本节介绍最简单的一种恶意代码图像绘制方法。对一个二进制文件,每个字节范围在00~FF之间,刚好对应灰度图0~255(0为黑色,255为白色)。将一个二进制文件转换为一个矩阵(矩阵元素对应文件中的每一个字节,矩阵的大小可根据实际情况进行调整),该矩阵又可以非常方便的转换为一张灰度图。

python代码如下

#!python
import numpy
from PIL import Image
import binascii
def getMatrixfrom_bin(filename,width):
  with open(filename, 'rb') as f:
    content = f.read()
  hexst = binascii.hexlify(content)  #将二进制文件转换为十六进制字符串
  fh = numpy.array([int(hexst[i:i+2],16) for i in range(0, len(hexst), 2)])  #按字节分割
  rn = len(fh)/width
  fh = numpy.reshape(fh[:rn*width],(-1,width))  #根据设定的宽度生成矩阵
  fh = numpy.uint8(fh)
  return fh
filename = "your_bin_filename"
im = Image.fromarray(getMatrixfrom_bin(filename,512)) #转换为图像
im.save("your_img_filename.png")

利用该代码生成的几种病毒样本图像如下所示

用肉眼可看出,同一个家族的恶意代码图像在纹理上存在一定的相似性,不同的恶意代码家族是有一定区别的。如何用计算机发现和提取这些纹理的相似特征用以分类呢?这就需要用到计算机视觉里的一些技术了。在 Nataraj 和 Karthikeyan 的论文中采用的是 GIST特征 , GIST特征 常用于场景分类任务(如城市、森林、公路和海滩等),用一个五维的感知维度来代表一个场景的主要内容(详情请参考文献[xx])。简单来说,输入图像,输出为对应的GIST描述符,如下图所示

[1] [2] [3] [4]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载