查询 25 次,耗时 0.2429 秒

Windows 可疑 PE 样本的静态分诊与动态调试:从哈希、导入表到 API 断点的防御分析流程

180647004

New member

180647004 Rep
0
0
0
Rep
0
180647004 Vouches
Vouches
0
1 MONTH
1 1 MONTH OF SERVICE
180647004 获得
0
0
0
获得
0
180647004 凭证
0
0
0
凭证
0
主题
4
点赞
0
HakB
1 月
在社区成长 1 月
LEVEL 1 1 XP
 
一、背景与分析目标

在日常应急响应中,我们经常会拿到一个来源不明的 EXE 或 DLL。此时最重要的并不是立即运行样本,也不是贸然尝试“脱壳”,而是先回答几个防御分析问题:文件是否被篡改或加壳?可能创建哪些文件、进程和注册表项?是否存在网络通信?有没有持久化、凭据访问或进程注入迹象?哪些特征可以转化为 IOC 或检测规则?

本文给出一套适用于 Windows PE 文件的标准化分析流程,涵盖静态分诊、受控动态观察和 x64dbg API 断点调试。所有操作仅限于合法取得的样本、授权靶场或自行构造的测试程序,重点是还原行为与提取防御线索,而不是绕过商业软件授权。

二、基本原理

PE 文件由 DOS 头、NT 头、节表、导入表、导出表、资源、重定位等结构组成。静态分析通过检查这些结构、字符串和反汇编代码,在不执行文件的情况下推测行为。动态分析则在隔离环境中运行样本,观察实际发生的文件、注册表、进程和网络活动。

两种方法必须结合:静态结果可能受到混淆、动态解析 API、加壳和无效代码干扰;动态执行又可能受时间延迟、环境检测、缺少参数或未覆盖代码路径影响。因此,合理顺序应当是:保存原始证据、计算哈希、静态分诊、建立行为基线、受控运行、断点验证、整理 IOC。

三、前置条件与实验环境

建议准备以下环境:

1. 一台不承载真实业务的分析主机,最好使用 VMware 或 VirtualBox 虚拟机。
2. Windows 10/11 分析虚拟机,可安装 FLARE-VM,或手动安装 PE-bear、Detect It Easy、Ghidra、x64dbg、Process Monitor、Process Explorer、TCPView、Wireshark、FLOSS、capa 和 Sysinternals 工具集。
3. 快照功能。开始分析前创建干净快照,结束后直接回滚。
4. 默认断网;如必须观察网络行为,使用 Host-only 网络配合 INetSim、FakeNet-NG 等模拟服务,不允许样本访问公网。
5. 关闭共享剪贴板、拖放、共享目录和 USB 自动连接。不要在分析机中保存真实账号、浏览器凭据、SSH 密钥或办公文档。

建议建立目录:

C:\\Lab\\case001\\original
C:\\Lab\\case001\\working
C:\\Lab\\case001\\logs
C:\\Lab\\case001\\dumps

将原始文件设为只读,只对副本开展分析。分析记录中应包含获取时间、来源、原始文件名、文件大小和哈希值。

四、步骤一:计算哈希并确认文件属性

使用系统自带 certutil:

certutil -hashfile C:\\Lab\\case001\\original\\sample.exe SHA256
certutil -hashfile C:\\Lab\\case001\\original\\sample.exe MD5

也可使用 PowerShell:

Get-FileHash C:\\Lab\\case001\\original\\sample.exe -Algorithm SHA256

SHA-256 用于唯一标识样本和后续关联;MD5 主要用于兼容旧平台,不应作为完整性安全保证。然后检查数字签名:

sigcheck64.exe -nobanner -a -h -i C:\\Lab\\case001\\original\\sample.exe

需要注意:存在签名并不等于安全。应核对签名是否有效、证书链是否可信、签名时间是否合理、签名主体与软件来源是否一致。无签名也不能直接判定为恶意。

五、步骤二:检查 PE 结构与加壳迹象

使用 Detect It Easy 或 PE-bear 打开副本,重点查看:

1. 编译架构是 x86、x64 还是 .NET。
2. 入口点位于哪个节,是否落在非常规节中。
3. 节名称、虚拟大小、原始大小和权限是否异常。
4. 是否出现同时可写、可执行的节,即 W+X 权限。
5. 导入表是否异常精简,只剩 LoadLibrary、GetProcAddress 等少量函数。
6. 资源中是否嵌入体积较大的二进制数据。
7. 节熵是否偏高。高熵可能表示压缩、加密或打包,但也可能是图片、音视频等正常资源。

典型可疑组合包括:入口点节高熵、节权限为 RWX、导入表极少、文件尾部有较大 overlay。不过这些只是线索,不能单独作为恶意结论。

六、步骤三:提取字符串和能力特征

普通 strings 容易漏掉栈字符串或简单编码内容,建议结合 FLOSS:

floss.exe C:\\Lab\\case001\\working\\sample.exe > C:\\Lab\\case001\\logs\\floss.txt

重点搜索以下类型的字符串:

http、https、User-Agent、IP 地址、域名、命名管道、互斥体名称、临时目录、注册表路径、计划任务参数、PowerShell 参数、错误提示、PDB 路径和调试日志。

然后使用 capa 进行能力识别:

capa.exe C:\\Lab\\case001\\working\\sample.exe > C:\\Lab\\case001\\logs\\capa.txt

capa 的输出可用于快速定位“创建进程”“修改注册表”“分配可执行内存”“连接网络”等能力,但规则命中只是辅助证据。尤其是安装器、游戏保护模块、浏览器和安全软件,也可能使用一些看似敏感的 API。

七、步骤四:分析导入表并建立行为假设

可在 PE-bear、Ghidra 或 dumpbin 中查看导入函数:

dumpbin /imports C:\\Lab\\case001\\working\\sample.exe

常见行为与 API 的对应关系如下:

文件操作:CreateFileW、WriteFile、DeleteFileW、MoveFileExW。
注册表操作:RegCreateKeyExW、RegSetValueExW、RegDeleteValueW。
进程操作:CreateProcessW、ShellExecuteExW、OpenProcess。
内存操作:VirtualAlloc、VirtualProtect、WriteProcessMemory。
网络操作:WinHttpOpen、WinHttpConnect、InternetOpenW、connect、send、recv。
服务操作:OpenSCManagerW、CreateServiceW、StartServiceW。

如果同时出现 OpenProcess、VirtualAllocEx、WriteProcessMemory 和 CreateRemoteThread,应将“可能存在远程进程内存操作”列为高优先级验证项,但不能仅凭导入表认定发生了进程注入,因为函数可能没有被调用,也可能用于合法调试或管理功能。

八、步骤五:使用 Ghidra 定位关键调用

在 Ghidra 中导入样本并完成自动分析。先从 Symbol Tree 的 Imports 定位敏感 API,再查看交叉引用。例如对 RegSetValueExW 查看 References,即可找到调用位置。

分析每个调用点时记录:

1. 函数参数从哪里产生。
2. 注册表键名或文件路径是否由字符串拼接得到。
3. 调用前是否存在条件判断。
4. 返回值是否影响后续流程。
5. 是否通过 GetProcAddress 动态获取真实 API。

对于 x64 程序,Windows x64 调用约定中前四个整数或指针参数通常依次放在 RCX、RDX、R8、R9,其余参数位于栈上。理解这一点有助于在反编译结果不清晰时手工恢复参数。

九、步骤六:建立动态监控基线

恢复干净快照后,先不要运行样本。启动 Process Monitor,设置过滤条件:

Process Name is sample.exe → Include
Operation is Process Create → Include
Operation begins with RegSet → Include
Operation is CreateFile → Include
Operation is WriteFile → Include

清空旧事件后开始捕获。同时打开 Process Explorer、TCPView 或 Wireshark。记录运行前的进程列表、网络连接和关键目录状态。如果需要比较文件系统与注册表变化,可使用 Regshot 分别获取运行前和运行后的快照。

建议将样本副本改为简单文件名,但保留原始名称记录。不要使用管理员权限启动,除非样本在普通权限下无法触发,并且分析目标确实需要验证提权后的行为。

十、步骤七:受控运行与行为记录

在网络完全隔离或连接 FakeNet-NG 的条件下运行样本。观察至少以下内容:

1. 是否产生子进程,子进程命令行是什么。
2. 是否向 AppData、ProgramData、Temp 或启动目录写入文件。
3. 是否修改 Run、RunOnce、Services、Scheduled Tasks 等持久化相关位置。
4. 是否创建命名管道、互斥体或本地监听端口。
5. 是否尝试域名解析、HTTP 请求或 TLS 连接。
6. 进程退出后是否仍有子进程、服务或文件残留。

运行时间不要只看几秒。部分程序会延迟执行,但也不建议无限等待。可分别记录启动后 30 秒、2 分钟和 5 分钟的状态。若样本出现破坏文件、加密文件或大量创建进程等迹象,应立即暂停虚拟机,不要尝试在真实主机上复现。

十一、步骤八:使用 x64dbg 设置 API 断点

当 Procmon 显示样本写入了某个文件,但静态分析无法确认数据来源时,可以在 x64dbg 中进行验证。加载样本后,在命令栏设置断点,例如:

bp kernelbase.CreateFileW
bp kernelbase.WriteFile
bp advapi32.RegSetValueExW
bp kernelbase.CreateProcessW

不同系统版本中 API 可能位于 KernelBase.dll,也可能通过 kernel32.dll 转发。若符号断点失败,可在模块列表中定位实际导出地址。

命中 CreateFileW 时,x64 程序的 RCX 通常指向文件路径。可在 Dump 窗口中跟随 RCX,并按 Unicode 字符串查看。命中 WriteFile 时,常见参数为:RCX 是文件句柄,RDX 是缓冲区地址,R8 是写入长度。此时只需要检查缓冲区内容并记录调用栈,不要修改执行流程。

命中 RegSetValueExW 时,重点查看 RDX 指向的值名称、R9 中的数据类型,以及栈上的数据地址和长度。命中 CreateProcessW 时,可检查 RCX 和 RDX 对应的程序路径及命令行。由于部分参数允许为空,应结合调用栈和内存窗口判断。

每次断点命中都应记录模块地址、相对偏移、线程 ID、参数、返回地址和调用栈。模块启用 ASLR 后,绝对地址每次可能不同,报告中优先记录“模块名+相对偏移”。

十二、结果整理与 IOC 提取

最终报告建议分为四类:

文件 IOC:SHA-256、落地文件名、文件路径、文件大小和签名信息。
网络 IOC:域名、IP、URL 路径、端口、User-Agent、证书指纹。
主机 IOC:注册表键、服务名、计划任务名、互斥体、命名管道。
行为证据:进程树、命令行、API 调用、Procmon 事件和抓包时间线。

IOC 必须注明来源。例如“字符串中发现域名”与“动态运行实际连接域名”的证据强度不同。不要把未触发的字符串直接写成已发生行为。对于可能变化的 IP 地址和云服务域名,也不应脱离上下文直接封禁。

十三、风险与注意事项

1. 禁止在宿主机、办公电脑或生产网络直接运行未知样本。
2. 虚拟机不是绝对安全边界,应及时更新虚拟化软件并关闭不必要的集成功能。
3. 不要将真实恶意样本上传到公开代码仓库、普通网盘或不受控的在线分析站点。样本可能包含客户信息或尚未公开的攻击数据。
4. 对来源不明的 DLL,不要直接双击或随意使用系统 rundll32 调用。优先静态分析,并在明确导出函数和参数后于隔离环境验证。
5. 时间戳、PDB 路径、节名称均可能伪造,只能作为辅助线索。
6. 调试器下未触发行为不代表样本安全。环境检测、权限不足、缺少配置、日期条件和外部指令都可能导致行为差异。
7. 分析完成后导出日志、截图和报告,随后回滚快照,不要继续使用已运行过样本的虚拟机处理其他工作。

十四、常见问题

问题一:静态工具显示高熵,是否可以直接判定加壳?

不能。压缩资源、加密配置和媒体内容都可能导致高熵。应结合入口点位置、导入表规模、节权限、运行时内存变化和已知壳特征综合判断。

问题二:Procmon 事件太多,如何快速过滤?

先按进程名过滤,再只保留 Process Create、WriteFile、CreateFile、RegSetValue 等关键操作。对样本产生的子进程,应将子进程名称或 PID 一并加入过滤条件,否则容易漏掉真正执行行为的进程。

问题三:API 断点一直不命中是什么原因?

样本可能使用了其他 API、直接系统调用、动态解析函数,或者关键代码尚未执行。可以先查看 Procmon 的实际行为,再对对应模块设置断点;也可以对 GetProcAddress 设置断点,观察运行时解析了哪些函数。

问题四:动态分析没有发现网络连接,是否说明样本不联网?

不一定。它可能需要命令行参数、配置文件、特定时间、管理员权限或远端指令,也可能检测到虚拟环境。报告应写成“本次执行路径中未观察到网络连接”,而不是绝对断言。

问题五:是否应该一开始就尝试脱壳?

不建议。先做静态和动态分诊,确认样本确实存在运行时解压或代码释放,再决定是否需要内存转储和导入表修复。很多分析目标仅通过 API 断点、行为日志和内存字符串就能完成,盲目脱壳会增加时间成本并破坏证据链。

十五、总结

高质量的 PE 样本分析不是简单地运行几个工具,而是通过可重复的证据链验证假设。推荐固定采用“哈希与签名→PE 结构→字符串与能力→导入表→反编译交叉引用→动态基线→受控运行→API 断点→IOC 整理”的顺序。静态分析负责提出问题,动态分析负责观察事实,调试器负责解释关键参数与数据来源。只要坚持隔离环境、最小权限、完整记录和谨慎下结论,即使面对加壳或行为复杂的样本,也能逐步形成可信、可复核并能直接支持防御检测的分析报告。
 
顶部