1. 静态分析PE文件基础
任务目标
对一个已知恶意样本(sample.exe)执行静态分析:使用DIE(Detect It Easy)识别其编译器/加壳器,并通过解析PE导入表判断样本可能的功能。本案例聚焦于静态分析的基础流程,不涉及动态执行。
环境准备
- 操作系统:Windows 10/11 或 Linux(以下命令以Linux为例,Windows下使用对应GUI或命令行版本)
- 工具:
die(Detect It Easy,命令行版本)、python3、pefile库(pip install pefile) - 样本:一个已知的恶意PE文件(如远程访问木马RAT样本),本案例使用
sample.exe作为占位文件名
实现步骤与代码
第一步,使用DIE识别加壳器/编译器。第二步,使用Python的pefile库提取导入表并输出关键信息。以下代码完成导入表提取与功能推断:
import pefile
import sys
def analyze_imports(file_path):
"""提取PE导入表并输出关键DLL与函数,推断可能功能"""
try:
pe = pefile.PE(file_path)
except Exception as e:
print(f"[!] 无法解析PE文件: {e}")
return
print(f"[*] 文件: {file_path}")
print(f"[*] 入口点地址: 0x{pe.OPTIONAL_HEADER.AddressOfEntryPoint:X}")
print(f"[*] 镜像基址: 0x{pe.OPTIONAL_HEADER.ImageBase:X}")
# 节区信息(辅助判断加壳:异常节区名或熵值高)
print("\n[*] 节区列表:")
for section in pe.sections:
name = section.Name.decode('utf-8', errors='replace').rstrip('\x00')
entropy = section.get_entropy()
print(f" {name:10s} 虚拟大小: 0x{section.Misc_VirtualSize:X} 熵: {entropy:.2f}")
# 导入表
if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
print("\n[*] 导入表:")
suspicious_funcs = []
for entry in pe.DIRECTORY_ENTRY_IMPORT:
dll_name = entry.dll.decode('utf-8', errors='replace')
print(f" DLL: {dll_name}")
for imp in entry.imports:
if imp.name:
func_name = imp.name.decode('utf-8', errors='replace')
print(f" {func_name}")
# 收集敏感API用于功能推断
if any(kw in func_name.lower() for kw in ['socket', 'send', 'recv', 'url', 'http', 'connect', 'createprocess', 'winhttp', 'internetopen']):
suspicious_funcs.append(f"{dll_name}!{func_name}")
else:
print(f" (序号: {imp.ordinal})")
if suspicious_funcs:
print("\n[+] 发现敏感API调用:")
for f in suspicious_funcs:
print(f" {f}")
else:
print("\n[-] 未发现明显网络/进程操作相关API")
else:
print("\n[-] 无导入表(可能已加壳或纯资源型样本)")
pe.close()
if __name__ == "__main__":
if len(sys.argv) != 2:
print("用法: python3 analyze_pe.py <样本路径>")
sys.exit(1)
analyze_imports(sys.argv[1])
DIE命令行识别加壳器(若样本已加壳,导入表通常被压缩或加密,此时上述脚本可能只显示少量系统DLL):
die -d sample.exe # 深度扫描模式
运行与验证
- 保存上述代码为
analyze_pe.py,在样本所在目录执行:python3 analyze_pe.py sample.exe - 观察输出:若样本未加壳,导入表应列出完整DLL和函数;若加壳,节区熵值通常高于7.0且导入表仅包含
LoadLibraryA/GetProcAddress等少量API。 - 结合DIE结果判断:DIE显示“Microsoft Visual C++ 6.0”且导入表包含
ws2_32.dll的socket/send/recv,则高度怀疑是网络通信型恶意代码;若DIE显示“UPX”或“ASPack”,则需先脱壳再分析。
通过条件:能正确输出样本的编译器/加壳器类型,并基于导入表列出至少3个关键API调用,且能据此给出功能倾向(如网络后门、键盘记录、下载器)。若样本加壳导致导入表不可见,则通过节区熵值和DIE结果说明加壳事实,并指出需脱壳后继续分析。
常见问题
- DIE检测为“未知”:尝试
die -d深度扫描,或使用die -e显示熵值辅助判断;若仍无法识别,可能为自定义壳或编译语言较新。 - 导入表为空:样本可能加壳或使用延迟导入。加壳样本需先脱壳(如UPX可用
upx -d);延迟导入需在运行时解析,静态分析阶段可跳过。 - 误报风险:某些合法软件也调用
socket或CreateProcess,需结合样本来源、数字签名、节区异常等综合判断,不可仅凭单个API定论。