本文讨论内容涉及如何使用SSDEEP、python调用SSDEEP和SSDEEP的计算块最大的大小。
背景
安全分析里经常会遇到一个场景,当一个文件被人为有意或无意地操作变化变成了一个新的文件,例如,有意的情况有作者改动文本内容、恶意代码自动填充垃圾字节等变化;无意的情况有传输出错、磁盘存储出错等。如何衡量这些文件的是否发生变化,如何有效比较两个文件是否有差异是否相似,成了取证分析和病毒分析里经常要面对的问题。
针对上面的场景,业内比较程序办法是采用模糊哈希进行比较,模糊哈希算法又叫基于内容分割的分片哈希算法(context triggered piecewise hashing, CTPH),主要用于文件的相似性比较。
2006年,Jesse Kornblum 提出CTPH,并给出一个名为spamsum的算法实例。随后,Jason Sherman开发了ssdeep工具以实现这一算法。该算法最初用于取证,后来被用于恶意代码检测,最近又有用于开源软件漏洞挖掘等。
模糊哈希的主要原理是,使用一个弱哈希计算文件局部内容,在特定条件下对文件进行分片,然后使用一个强哈希对文件每片计算哈希值,取这些值的一部分 并连接起来,与分片条件一起构成一个模糊哈希结果。使用一个字符串相似性对比算法判断两个模糊哈希值的相似度有多少,从而判断两个文件的相似程度。
对文件的部分变化(包括在多处修改、增加、删除部分内容),使用模糊哈希均能发现与源文件的相似关系,是目前判断相似性较好的一种方法。
安装
无论是Ubuntu的apt-get还是OS X上的brew都可以直接安装,也有相应的Windows版本。
brew install ssdeep
计算单个文件的SSDEEP哈希
ssdeep -b webshell.php
会的到一个结果由“计算块的大小:长哈希:短哈希,文件名”的结果
3:sYrXkI6xmFqXDKaHFXVe4KUNvVXFUNvedrM:sYrpWEaHFP3G8M,"test.py"
批量比对筛选相似度90以上的的结果,result.txt存放了一些ssdeep结果。
ssdeep -t 90 -bm result.txt webshell/*
python接口
pip install ssdeep
任何可以被二进制都可以进行计算,包括支持从文件输入进行扫描。
https://python-ssdeep.readthedocs.io/en/latest/index.html#
主要函数是ssdeep.hash_from_file()
>>> ssdeep.hash_from_file('/etc/resolv.conf')
'3:S3yE29cFrrMOoiECAaHJgvn:S3m+COoiUCuvn'
相似度比较
>>> import ssdeep
>>> hash1 = ssdeep.hash('Also called fuzzy hashes, Ctph can match inputs that have homologies.')
>>> hash1
'3:AXGBicFlgVNhBGcL6wCrFQEv:AXGHsNhxLsr2C'
>>> hash2 = ssdeep.hash('Also called fuzzy hashes, CTPH can match inputs that have homologies.')
>>> hash2
'3:AXGBicFlIHBGcL6wCrFQEv:AXGH6xLsr2C'
>>> ssdeep.compare(hash1, hash2)
22
compare函数会返回一个0-100的值,值越大越相似,100表示完全一样。
最大长度结果
ssdeep计算的哈希值的最大长度的任何信息。
根据源码的头文件fuzzy.h
及其documentation的描述。
存在一个常量FUZZY_MAX_RESULT
,它定义了148
ASCII字符/字节的哈希值的最大长度:
#define SPAMSUM_LENGTH 64
#define FUZZY_MAX_RESULT (2 * SPAMSUM_LENGTH + 20)