简单概念
PE文件中将导入表信息抽象出来的哈希即为导入表哈希,该值与模块名、模块中的函数名以及函数顺序相关。
利用该值可以捕获同源的样本,使用价值可以参考Mandiant的这篇文章。
VirusTotal中可以利用关键字imphash来搜索样本,其工作原理与本文提到的python模块pefile与yara工具得出的结果相同。
例如:imphash:91c8172effccd3ed565854517f1bf6fd
python模块pefile中imphash实现
def get_imphash(self):
impstrs = []
exts = ["ocx", "sys", "dll"]
#判断有无导入表
if not hasattr(self, "DIRECTORY_ENTRY_IMPORT"):
return ""
#遍历导入表
for entry in self.DIRECTORY_ENTRY_IMPORT:
#将导入表的模块名转化为小写
if isinstance(entry.dll, bytes):
libname = entry.dll.decode().lower()
else:
libname = entry.dll.lower()
#去掉扩展名,提取模块名
parts = libname.rsplit(".", 1)
#判断是否是 这三个后缀 ocx, sys, dll 若是则去掉
if len(parts) > 1 and parts[1] in exts:
libname = parts[0]
entry_dll_lower = entry.dll.lower()
#提取函数名
for imp in entry.imports:
funcname = None
#若是序号导入则 将函数名转化为 ord+序号 如:ord4
if not imp.name:
funcname = ordlookup.ordLookup(
entry_dll_lower, imp.ordinal, make_name=True
)
if not funcname:
raise PEFormatError(
f"Unable to look up ordinal {entry.dll}:{imp.ordinal:04x}"
)
else:
funcname = imp.name
if not funcname:
continue
if isinstance(funcname, bytes):
funcname = funcname.decode()
#拼接 将模块名与函数名合并 并添加到 impstrs 列表中
impstrs.append("%s.%s" % (libname.lower(), funcname.lower()))
#将列表转化为字符串以","为分隔符并计算md5
return md5(",".join(impstrs).encode()).hexdigest()
md5前得到的字符串壳参考如下:
“ws2_32.gethostname,ws2_32.gethostbyname,ws2_32.inet_ntoa,wintrust.winverifytrust,wintrust.wthelperprovdatafromstatedata,crypt32.certgetnamestringw,riched20.ord4”
其实知道这里就可以编写与VirusTotal兼容的导入表实现了
利用pefile获取导入表哈希
使用pefile获取导入表哈希(使用的样本md5:5ed9d3341034c227b46a2b393b1b70bd):
virustotal中的样本:
VT连接: https://www.virustotal.com/gui/file/43c5182f830865247d98f53dd488b02c3235d25d0c2179f48b3f8adcf6fa8e38/details
利用yara获取导入表哈希
import "console"
import "pe"
rule impHash
{
condition:
//false加上就不会打印 规则名与样本路径
console.log(pe.imphash()) and false
}
使用yara获取导入表哈希:
参考: yara文档