第二十课:恶意代码分析实战(一)——静态分析一个木马样本
各位同学,欢迎来到实战环节。前面我们聊了很多理论,什么PE结构、汇编指令、加壳原理……说实话,光看书不练手,永远成不了逆向工程师。今天我们就拿一个真实的木马样本开刀,走一遍完整的分析流程。
我个人习惯是,拿到一个可疑样本,先别急着双击运行。你想想看,万一是个勒索病毒,双击完你的毕业论文就没了。所以第一步,永远是静态分析。
1. 查壳:看看对方穿了什么“马甲”
查壳就像看一个人穿没穿外套。没穿外套的(无壳程序),我们直接看内部逻辑;穿了外套的(加壳程序),得先扒掉这层皮。
常用的查壳工具有几个:Exeinfo PE、Detect It Easy (DIE)、PEiD。我个人偏爱DIE,因为它更新勤快,识别率高。
操作很简单:把样本拖进DIE,几秒钟就出结果。
实战案例:我拿到一个名为“svch0st.exe”的样本,拖进DIE后显示:
UPX 0.89.6 - 1.02 / 1.05 - 2.90 -> Markus & Laszlo
嗯,UPX加壳,经典老壳。UPX是开源压缩壳,好处是脱壳工具遍地都是。
2. 查字符串:寻找“犯罪证据”
脱完壳之后,下一步就是查字符串。字符串是恶意代码的“自白书”,里面往往藏着关键信息。
用Strings工具或者直接在IDA里看。我习惯用IDA的字符串窗口(Shift+F12),一目了然。
在刚才那个样本里,我找到了这些有意思的字符串:
| 字符串内容 | 可能含义 |
|---|---|
http://malware-c2.example.com/command |
C2服务器地址,用于接收指令 |
SOFTWARE\Microsoft\Windows\CurrentVersion\Run |
注册表自启动项,实现持久化 |
keylog_%d.txt |
键盘记录文件,说明有键盘钩子 |
CreateRemoteThread |
远程线程注入,典型的进程注入手法 |
看到这些字符串,我心里基本有数了:这是一个远控木马,带键盘记录功能,会写注册表实现自启动,还会注入其他进程。
3. 查导入表:看它调用了哪些“危险函数”
导入表(Import Table)记录了程序调用了哪些系统API。恶意代码再狡猾,最终也得通过Windows API干坏事。
在IDA或PE-bear里查看导入表。重点关注以下几类API:
- 进程操作:
OpenProcess、CreateRemoteThread、WriteProcessMemory——典型的进程注入三件套 - 网络通信:
socket、connect、send、recv——建立C2连接 - 文件操作:
CreateFile、WriteFile——写日志文件或释放载荷 - 注册表操作:
RegOpenKeyEx、RegSetValueEx——实现持久化
在样本里,我看到了CreateRemoteThread和WriteProcessMemory同时出现。这基本实锤了——它要往别的进程里注入代码。
避坑指南:我曾经遇到一个样本,导入表里干干净净,只有几个常规的DLL。当时我还纳闷,这玩意儿怎么干活?后来才发现,它用了动态加载——运行时通过LoadLibrary和GetProcAddress获取API地址。所以,别只看静态导入表,还要留意代码里有没有动态加载的痕迹。
动态分析:看它运行时干了什么
静态分析只能看到“静态证据”,但程序跑起来之后的行为,才是关键。动态分析,说白了就是让木马在受控环境里“表演”,我们在一旁录像。
1. 监控文件行为
用Process Monitor (Procmon)监控文件操作。设置过滤条件:进程名为样本名,操作类型选CreateFile、WriteFile。
运行样本后,我看到它创建了以下文件:
C:\Users\admin\AppData\Roaming\svchost.exe——把自己复制到Roaming目录,伪装成系统进程C:\Users\admin\AppData\Local\Temp\keylog_001.txt——键盘记录文件
2. 监控注册表行为
同样用Procmon,过滤注册表操作。重点关注RegSetValue事件。
样本在HKCU\Software\Microsoft\Windows\CurrentVersion\Run下添加了一个键值:
键名: WindowsUpdate
键值: C:\Users\admin\AppData\Roaming\svchost.exe
嗯,经典的Run键自启动。每次用户登录,这个木马就会自动运行。
3. 监控网络行为
用Wireshark或Fiddler抓包。我习惯用Wireshark,过滤条件设为ip.addr == 恶意IP。
样本运行后,立即向malware-c2.example.com:8080发送了一个HTTP POST请求,内容是一段Base64编码的数据。解码后是:
{"machine_id": "DESKTOP-ABC123", "username": "admin", "os": "Windows 10"}
这是典型的“上线包”——木马向C2服务器报告自己的身份和环境信息。
编写Yara规则:给这个木马“画像”
分析完了,不能白干。我们要写一条Yara规则,以后遇到类似的样本,能自动识别出来。
Yara规则的核心是特征匹配。我们可以从刚才的分析中提取特征:
- 字符串特征:C2地址、注册表路径、文件名
- 代码特征:特定的字节序列(比如UPX脱壳后的入口点特征)
- PE结构特征:导入表里特定的API组合
下面是我为这个木马写的Yara规则:
rule Trojan_Win32_RemoteAccess_Keylogger
{
meta:
description = "Detects a remote access trojan with keylogging capability"
author = "Your Name"
date = "2025-01-15"
hash = "a1b2c3d4e5f6..." // 样本的MD5
strings:
$c2_url = "http://malware-c2.example.com/command"
$reg_run = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"
$keylog_file = "keylog_%d.txt"
$api_create_remote_thread = "CreateRemoteThread"
$api_write_process_memory = "WriteProcessMemory"
condition:
// 至少匹配3个字符串,并且包含两个关键API
(uint16(0) == 0x5A4D) and // 检查MZ头
(uint16(locatesignature()) == 0x4550) and // 检查PE头
(2 of ($c2_url, $reg_run, $keylog_file)) and
(all of ($api_create_remote_thread, $api_write_process_memory))
}
规则解读:
uint16(0) == 0x5A4D:检查文件开头是不是MZ头,确保是PE文件2 of ($c2_url, $reg_run, $keylog_file):至少匹配2个字符串特征all of ($api_create_remote_thread, $api_write_process_memory):必须同时匹配这两个API
这样写的好处是:既能避免误报(单个字符串可能出现在正常软件中),又能保证检出率。
本章知识体系
下面这张图总结了本章的核心流程,从拿到样本到编写检测规则,每一步都环环相扣:
这张图把整个流程串起来了。你从左上角的“静态分析”开始,一路走到右下角的“输出检测规则”。每一步都有对应的工具和方法,缺一不可。
好了,这一课的内容就到这里。静态分析、动态分析、Yara规则编写,这三板斧你掌握了吗?下次遇到可疑样本,别急着双击,先按这个流程走一遍。相信我,你会爱上这种“破案”的感觉。