读完本篇你将能:建立恶意软件分析的安全环境(沙箱隔离),掌握静态分析的五步法(文件识别→字符串搜索→PE结构分析→反编译→行为推断),使用 FLOSS 提取加密字符串,识别加壳与混淆,理解恶意软件的常见行为模式(持久化、横向移动、C2通信),并能用 Ghidra 完成一个简单恶意样本的完整静态分析报告。
前面三篇(汇编、静态工具、动态调试)是逆向的"武器",本篇和下一篇是"战场"——把学到的工具和方法用在真实的恶意软件分析上。恶意软件分析分为静态和动态两条路径:静态分析不运行样本,通过文件结构、字符串、反编译代码推断行为;动态分析则在隔离环境中运行样本,观察实际行为。两条路径互补,通常先静态后动态。
恶意软件分析的第一条铁律:绝不在主机上直接运行未知样本。分析环境必须严格隔离——一旦样本逃逸,你的主机可能成为僵尸网络的一部分,甚至丢失数据。
如果不想自己搭环境,可以使用在线沙箱服务。它们会在隔离环境中运行样本并自动生成分析报告。注意:提交到公共沙箱的样本会被共享给其他分析人员,不要提交含敏感信息的文件。
| 沙箱 | 特点 | 地址 |
|---|---|---|
| VirusTotal | 多引擎扫描 + 社区评论 | virustotal.com |
| Joe Sandbox | 深度行为分析 + 反病毒绕过 | joesandbox.com |
| Any.Run | 交互式沙箱 + 实时操作 | any.run |
| Hybrid Analysis | 免费 + 详细报告 | hybrid-analysis.com |
静态分析有一套成熟的方法论,按照"从外到内、从浅到深"的顺序逐步深入。每一步都有明确的产出和判断标准,如果某一步已经能得出结论,就不需要继续深入。
| 步骤 | 方法 | 工具 | 产出 |
|---|---|---|---|
| 1. 文件识别 | 类型、大小、哈希、熵值 | file / exiftool / die | 文件指纹 + 是否加壳 |
| 2. 字符串搜索 | 明文字符串 + 加密字符串 | strings / FLOSS | 行为线索 + API/URL/IP |
| 3. PE/ELF 结构 | 节区、导入表、导出表 | peview / readelf / r2 | 功能推断 + 依赖库 |
| 4. 反编译 | 汇编 → 伪 C 代码 | Ghidra / IDA / r2 pdc | 核心逻辑还原 |
| 5. 行为推断 | 综合分析 + 关联映射 | YARA / 知识库 | 分析报告 + 检测规则 |
拿到样本的第一步是"身份鉴定"——这是什么类型的文件?多大?哈希值是多少?有没有加壳?这些信息决定了后续分析的方向。
熵(Entropy)衡量数据的随机性。正常程序的代码和数据有一定规律,熵值在 4-6 之间。加壳或加密后的文件数据高度随机,熵值接近 8.0(最大熵)。通过熵值可以快速判断样本是否加壳。
| 熵值范围 | 含义 | 常见场景 |
|---|---|---|
| 0 - 3 | 低熵,高度结构化 | 文本、配置文件 |
| 4 - 6 | 中等熵,正常可执行文件 | 未加壳的 EXE/DLL |
| 7 - 8 | 高熵,数据高度随机 | 加壳、加密、压缩 |
字符串是静态分析中最有价值的信息来源——URL、IP 地址、注册表路径、错误提示、加密密钥都可能以字符串形式存在。简单的 strings 命令只能提取明文字符串,而恶意软件经常把字符串加密后运行时解密,这就需要 FLOSS。
FLOSS(FLARE Obfuscated String Solver)是 Mandiant 开源的工具,可以自动识别并提取恶意软件中经过简单加密/混淆的字符串。它通过模拟执行、栈字符串解码、静态解密等多种方法,找出 strings 命令看不到的隐藏字符串。
strings 能找到大量有意义的字符串(URL、路径、错误信息),说明它没有强加密,分析难度较低。如果 strings 几乎找不到有意义的字符串,说明样本可能加壳或使用了字符串加密,需要先用 FLOSS 或动态分析获取更多信息。PE(Portable Executable)是 Windows 可执行文件的标准格式。分析 PE 结构可以快速推断程序的功能——通过导入表知道它调用了哪些系统 API,通过节区信息判断是否加壳,通过资源段查找嵌入的 payload。
导入表(Import Table)列出了程序从哪些 DLL 导入了哪些函数。通过分析导入的 API,可以大致推断程序的功能方向。
| 可疑 API | DLL | 暗示行为 |
|---|---|---|
| CreateRemoteThread | kernel32.dll | 进程注入 |
| WinExec / ShellExecute | kernel32 / shell32 | 执行命令/程序 |
| RegSetValueEx | advapi32.dll | 注册表持久化 |
| connect / send / recv | ws2_32.dll | 网络通信 / C2 |
| IsDebuggerPresent | kernel32.dll | 反调试 |
| CryptEncrypt / CryptDecrypt | advapi32.dll | 加密 / 勒索 |
| GetAsyncKeyState | user32.dll | 键盘记录 |
加壳(Packing)是恶意软件最常用的自我保护手段之一——将原始代码加密或压缩,运行时在内存中解密还原。加壳后的文件用静态分析几乎看不到有价值的信息,需要先脱壳才能继续分析。
| 壳类型 | 代表 | 识别特征 |
|---|---|---|
| 压缩壳 | UPX、ASPack、PECompact | 节区名为 UPX0/UPX1、高熵、导入函数少 |
| 加密壳 | Themida、VMProtect、Enigma | 虚拟机保护、多段加密、反调试 |
| 自定义壳 | APT 组织自研 | 无已知签名、独特的加载逻辑 |
脱壳(或确认未加壳)后,就可以用 Ghidra 深入分析代码了。恶意软件的反编译分析和普通程序不同——你需要从成千上万行混淆的伪代码中,识别出核心恶意行为。分析的关键是"先广后深"——先建立全局认知,再聚焦关键函数。
在反编译代码中,以下模式需要特别关注——它们是恶意软件的"指纹",看到就要警觉。
| 行为模式 | 代码特征 | 对应恶意行为 |
|---|---|---|
| 字符串拼接构建 API 名 | 大量 strcat / 逐个字符赋值 | 隐藏导入函数名 |
| GetModuleHandle + GetProcAddress | 动态获取 API 地址 | 隐藏导入表 |
| XOR / ADD / SUB 循环 | 对字节数组做循环运算 | 字符串/配置解密 |
| 注册表 Run 键操作 | RegOpenKey + RegSetValueEx | 开机自启持久化 |
| socket + connect 循环 | 带 sleep 的网络连接重试 | C2 信标通信 |
| CreateToolhelp32Snapshot | 遍历进程列表 | 进程注入目标选择 |
任务:找一个已知的恶意软件样本(可从 theZoo 或 malware-samples 仓库获取,选简单的木马或后门),完成静态分析第一步:(1) 计算 MD5、SHA1、SHA256 哈希;(2) 用 file 命令识别文件类型;(3) 用 ent 计算熵值判断是否加壳;(4) 用 strings 提取明文字符串,找出 URL、IP、注册表路径等可疑内容;(5) 用 pev 或 radare2 分析导入表,列出前 10 个可疑 API。把结果整理成一个简单的表格。
任务:选择一个 UPX 加壳的恶意样本:(1) 用 DIE 或 pescan 确认是 UPX 加壳;(2) 用 upx -d 脱壳;(3) 对比脱壳前后的字符串数量和导入表变化;(4) 用 Ghidra 导入脱壳后的文件,自动分析后找出 3 个最可疑的函数(基于导入表 xref);(5) 阅读这 3 个函数的反编译伪代码,用自己的话描述每个函数的功能。截取反编译窗口截图。
任务:选择一个中等复杂度的恶意样本(如 Remcos RAT、AsyncRAT 等公开样本),完成完整静态分析并撰写分析报告。报告需包含:(1) 文件基本信息(哈希、类型、大小、熵值);(2) 加壳/保护分析;(3) 字符串分析结果(含 FLOSS 提取的加密字符串);(4) 导入表分析与功能推断;(5) 核心功能模块分析(至少 5 个关键函数的伪代码解读);(6) 持久化机制、C2 通信方式、恶意行为总结;(7) YARA 检测规则(自己写一条)。
参考资源:MalwareTech 的挑战题、flare-on 挑战赛题目、theZoo 样本库、VX Underground 样本集。注意:所有样本必须在隔离环境中操作,绝不可在主机直接运行。
本篇学了恶意软件的静态分析——不运行样本,通过文件结构、字符串、反编译推断行为。下一篇学恶意软件动态分析——在隔离的沙箱环境中真的运行样本,用工具监控它的一举一动:进程创建、文件操作、注册表修改、网络通信、行为监控。动态分析能看到静态分析看不到的东西(如解密后的 C2 地址、运行时加载的 payload),但风险也更高,需要严格的环境隔离。静态 + 动态结合,才是完整的恶意软件分析方法论。
关注本公众号,持续获取网络安全 Kali 学习系列更新。如果觉得有帮助,欢迎点赞、在看、分享给同样在学习网络安全的朋友。