20242312 2026-2027-1 《网络与系统攻防技术》实验四实验报告
20242312 2026-2027-1 《网络与系统攻防技术》实验四实验报告
姓名:周梓濠
学号:20242312
实验名称:恶意代码分析与取证
1.基础知识
1.1 静态分析与动态分析
静态分析是不运行样本,直接读文件本身:文件格式、PE 结构、导入表、字符串、反汇编出来的指令。一旦样本加了壳,看到的全是解压程序的代码,原始逻辑被藏在后面。
动态分析是把样本放进隔离的虚拟机里跑,观察进程、网络连接、注册表和文件系统的变化。它能绕开加壳直接看行为,但样本往往带环境检测,一看是虚拟机就休眠,得到的结果未必完整。实际做样本分析一般是先静态摸结构,再动态验证行为,两边互补。
1.2 PE 文件与节区
Windows 下的可执行文件用 PE(Portable Executable)格式。开头是 DOS 头,偏移 0x3C 处指向 NT 头;NT 头里的 FileHeader 记录目标机器和节区数量,OptionalHeader 记录子系统和入口点地址;后面紧跟节表,描述每个节区的位置与属性。
常见节区有 .text(代码)、.data(已初始化数据)、.rdata(只读数据,字符串常量多在这里)、.rsrc(资源)、.reloc(重定位)。正常编译出来的程序节区数量和名字都比较规整,加壳之后往往被改成 UPX0、UPX1 这类名字,数量也会减少——壳把原始的几个节压成一两个。反过来,节区数量变回来就是脱壳成功的标志之一。本次 RaDa.exe 是 3 个节区,脱壳后变成 4 个,判断就靠这个。
1.3 加壳与脱壳
壳分两类。压缩壳(UPX、ASPack、PECompact)主要目的是减小体积、顺带隐藏代码,脱起来相对容易;加密壳(Themida、VMProtect)会做代码虚拟化和反调试。RaDa.exe 用的是 UPX,属于前者。
脱壳的思路有三条:用专用工具一键脱(UPX 自带的 -d、超级巡警这类脱壳机);手工跟到入口点,等壳把原始代码解压完、跳到 OEP(Original Entry Point)时把内存 dump 下来;内存 dump 之后还要修导入表(IAT),否则程序跑不起来。对静态分析来说,只要代码段被还原、IDA 能正常反汇编,这一步就算完成。
1.4 IRC 协议与僵尸网络
IRC(Internet Relay Chat)是 1988 年出现的文本聊天协议,标准的客户端/服务器结构。客户端连上服务器后先发 NICK 设昵称,再发 USER 报用户名,服务器回 001–004 几条欢迎信息,注册完成,之后用 JOIN #频道 进频道、PRIVMSG 发消息。
它被早期僵尸网络大量用作命令控制通道,原因:协议简单、有现成的服务器软件、支持频道广播(一条指令全体 bot 都能收到)、流量看着像普通聊天。典型运作方式是 bot 上线后 JOIN 一个带密码的私有频道,攻击者在频道里发指令,bot 执行完把结果 PRIVMSG 回去。
服务器端有两条信息对取证特别有用。353(RPL_NAMREPLY)是频道成员名单,服务器用它把频道里所有昵称广播一遍;251、255 之类的 numerics 会报服务器状态,其中包含 current global users,也就是全网在线人数。统计僵尸网络规模基本就靠这几个字段。
僵尸网络(botnet)指一批被同一控制端控制的感染主机。这些主机叫"僵尸"或"肉鸡",控制端叫 C&C(Command and Control)。用途包括 DDoS、群发垃圾邮件、窃取凭据、点击欺诈、当代理跳板,近些年更多是投放勒索软件和挖矿。
1.5 蜜罐流量取证的顺序
蜜罐是故意暴露出来的诱捕主机,正常情况下不该有人访问它,所以凡是发往它的流量都可以按攻击看待。分析抓包文件通常按这个顺序走:先看协议分层(Statistics → Protocol Hierarchy),知道 TCP、UDP 各占多少、有没有异常协议;再看会话统计(Conversations),知道有哪些 IP 和它通信、各传了多少字节;然后用显示过滤器按字段精确定位,比如 tcp.flags==0x2 只看 SYN、smb.nt_status==0xC000006D 只看登录失败;最后对关键会话用 Follow → TCP Stream 把载荷按方向拼成明文读一遍,这比逐个包翻字段快得多。
命令行侧有对应工具:tcpdump 做粗过滤和字段抽取,tcpflow 把每条 TCP 会话还原成独立文件,tshark 做字段级提取和统计。
1.6 本次流量中出现的漏洞
- Code Red(2001):IIS 4.0/5.0 的
.ida、.idqISAPI 过滤器存在缓冲区溢出。蠕虫发超长的GET /default.ida?NNNNNN…请求压垮栈,成功后篡改网页,留下HELLO! Welcome to http://www.worm.com! Hacked By Chinese!,并在C:\下写notworm.LMTH标记文件表示已感染。 - Code Red II:Code Red 的变种,改用 Unicode 编码的 shellcode 绕过字符过滤,并在
C:\inetpub\scripts下留root.exe、cmd.exe后门。 - Slammer/Sapphire(2003):SQL Server 2000 的 1434/UDP 监视器服务溢出,整个蠕虫只有 376 字节,一个 UDP 包就能完成感染,传播速度极快。
- NetBIOS 与 SMB(139、445):空会话枚举共享、
IPC$匿名连接、SAMR远程枚举账户、弱口令暴力破解,以及通过ADMIN$投放 psexec 服务程序。 - FrontPage 扩展:
_vti_bin、_vti_inf.html这些页面会泄露服务器版本和扩展配置,也能被用来上传。 - 远程控制软件端口:4899 是 Radmin 的默认端口,5631/5632 是 pcAnywhere。攻击者扫到这类端口开放,会尝试弱口令接管。
2.实验内容
2.1 实验任务
一、恶意代码文件类型标识、脱壳与字符串提取
对提供的 RaDa 恶意代码样本进行文件类型识别、脱壳与字符串提取,以获得 RaDa 的编写作者。具体要求:
- 使用文件格式和类型识别工具,给出 RaDa 样本的文件格式、运行平台和加壳工具;
- 使用超级巡警脱壳机等脱壳软件,对 RaDa 样本进行脱壳处理;
- 使用字符串提取工具,对脱壳后的样本进行分析,从中发现 RaDa 的编写作者是谁。
二、crackme 逆向
使用 IDA Pro 静态或动态分析 crackme1.exe 与 crackme2.exe,寻找特定输入,使其能够输出成功信息。
三、RaDa 样本分析
分析自制恶意代码样本 RaDa,并撰写报告回答八个问题:(1)二进制文件的摘要,包括可以帮助识别同一样本的基本信息;(2)这个二进制文件的目的;(3)它具有的不同特性;(4)其中采用的防止被分析或逆向工程的技术;(5)对样本分类并给出理由;(6)过去已有的具有相似功能的其他工具;(7)能否调查出开发者,以及在什么环境和限定条件下;(8)给出至少 5 种检测该恶意软件的方法。
四、取证分析实践
数据源是 Snort 收集的蜜罐主机 5 天网络流量,已去除不相关流量,IP 与其他敏感信息做过混淆。蜜罐主机 IP 为 172.16.134.191。回答七个问题:(1)IRC 是什么,客户端加入 IRC 网络时发送什么消息,IRC 一般用哪些 TCP 端口;(2)僵尸网络是什么,通常用于什么;(3)蜜罐与哪些 IRC 服务器通信过;(4)观察期内多少不同主机访问了以 209.196.44.172 为服务器的僵尸网络;(5)哪些 IP 被用于攻击蜜罐主机;(6)攻击者尝试攻击了哪些安全漏洞;(7)哪些攻击成功了,如何成功的。
2.2 实验方案与验证方法
| 实验内容 | 实现方案 | 验证方法 |
|---|---|---|
| 文件类型与查壳 | file 读 PE 头,Detect It Easy 做熵值分析与特征段匹配 |
两条结论互相印证,3 sections 与 UPX[modified] 都能对上 |
| 脱壳 | 用超级巡警之虚拟机自动脱壳器跟踪 OEP 脱壳,回传到 Kali 再用 file 检查 |
节区数由 3 变 4,md5sum 前后必然不同 |
| 字符串与作者 | IDA 跳转到指定地址读明文,strings -el 交叉验证 |
两处地址给出同两个人名,与版本信息里的 2004年9月 时间一致 |
| crackme1 与 crackme2 | 用 IDA 看函数调用图与 main 流程图,找出 argc 与 strcmp 的条件 |
按条件构造参数运行,得到成功提示 |
| RaDa 样本八问 | 五组关键字符串拼行为链,逐条给出判断依据 | 每个结论都能指到具体字符串或指令 |
| 僵尸网络取证 | Wireshark 显示过滤器、tcpflow 拆流、tcpdump 与 tshark 统计 |
同一问题用两到三种口径统计,数字能互相解释 |
2.3 实验环境与文件
| 项目 | 配置 |
|---|---|
| 分析主机(Windows) | Windows 11 |
| 分析主机(Linux) | VMware 上的 Kali Linux,IP 192.168.64.128,主机名 zhouzihao |
| Linux 工作目录 | ~/lab4 |
| 样本文件 | RaDa.exe、RaDa_unpacked.exe、crackme1.exe、crackme2.exe、botnet_pcap_file.dat |
| 主要工具 | Detect It Easy 3.10、超级巡警之虚拟机自动脱壳器、IDA Pro、Wireshark、file、md5sum、exiftool、tcpflow 1.6.1、tcpdump、tshark |
3.实验过程
3.1 实验一:RaDa 的文件类型识别、脱壳与字符串提取
(1)确认文件格式
先用 file 读 PE 头。这个命令不看扩展名,只看文件头的魔数和字段,所以能识破改扩展名的伪装。
cd ~/lab4
file RaDa.exe
输出:
RaDa.exe: PE32 executable for MS Windows 4.00 (GUI), Intel i386, 3 sections
这里有四个信息点:PE32 是 32 位可执行文件;for MS Windows 4.00 (GUI) 表示面向 Windows、图形界面子系统;Intel i386 是 x86 架构;3 sections 是节区数量。最后这个数字后面判断脱壳是否成功要用到。

图1:file 命令识别 RaDa.exe 的文件类型。
(2)查壳
file 只能看出它是个 PE,看不出加没加壳。换 Detect It Easy 再看一次,DIE 除了读 PE 头,还会算熵值、匹配特征段,对加壳的判断比 file 准。
打包工具显示 UPX[modified],下面的启发式判断写着 Compressed or packed data[EntryPoint + Imports like UPX (v0.94-1.93) + Sectio…]。

图2:Detect It Easy 的识别结果,PE32、VB6 编译、UPX 加壳。
UPX[modified] 里那个 modified 值得留意,说明壳头被人改过,不是标准 UPX 的输出。这也是后面脱壳机识别出来的版本是一个区间、而不是单一版本号的原因。
(3)脱壳
用超级巡警之虚拟机自动脱壳器打开 RaDa.exe,它给出的识别结果是:
MD5: CAAA6985A43225A0B3ADD54F44A0D4C7
UPX 0.89.6 - 1.02 / 1.05 - 1.22 -> Markus & Laszlo

图3:脱壳器识别出 UPX 0.89.6-1.02,并给出 MD5。
点"脱壳",工具跟踪 OEP 完成后输出:
Unpacked again by tracing OEP...
Unpack successfully!
Output path: D:\Administrator\Downloads\RaDa_unpacked.exe

图4:脱壳成功,输出 RaDa_unpacked.exe。
把脱壳后的文件传回 Kali,再验一次:
file RaDa_unpacked.exe
节区从 3 个变成 4 个,说明 UPX 解压后原始节区被还原出来了。顺手算一下前后的哈希:原文件 caaa6985a43225a0b3add54f44a0d4c7,脱壳后 02bfa8e6d4ed8ed8049004fdad840d2a

图5:脱壳后节区由 3 个变为 4 个。
(4)字符串提取与作者
用 IDA 打开 RaDa_unpacked.exe,按 G 键跳转到地址 00403F7A。这里是初始化代码里拼接程序信息的位置,能看到明文:
Raul Siles && David Perez
再跳到 00403FD4,可以看到版本信息里的时间 2004年9月。
如果不用 IDA,在命令行也能提到这两个字符串,只是 VB6 的 Unicode 存储需要加参数:
strings -el RaDa_unpacked.exe | grep -i -A1 -B1 "Siles"
实验一完成b( ̄▽ ̄)d 。
3.2 实验二:crackme1 与 crackme2 的逆向
(1)执行原文件
直接跑,看它对不同参数个数的反应:
D:\...\test> ./crackme1.exe
I think you are missing something.
D:\...\test> ./crackme1.exe 1
Pardon? What did you say?
D:\...\test> ./crackme1.exe 1 2
I think you are missing something.

图6:crackme1 在 0 个、1 个、2 个参数下的三种提示。
分析:不给参数和给两个参数,提示是同一句"缺东西";给一个参数,提示变成"你说什么"。这说明程序判断的不是"参数够不够",而是参数个数是否恰好等于 2(argv[0] 加一个参数)。等于 2 才继续往下比内容,否则一律当成缺参数。
(2)定位校验逻辑
IDA 载入后先看函数调用图(View → Graphs → Function calls)。main 下面挂了 _fprintf、_strcmp、_puts、_putchar、__alloca 这几个调用,其中 _strcmp 最可疑,它在比较字符串,通常就是口令校验。

图7:crackme1 的函数调用图,main 调用了 strcmp。
双击进入 main 的图形视图,逻辑一目了然:

图8:crackme1 的 main 流程图,可见 argc 判断与 strcmp("I know the secret")。
翻译成 C 大致是这样:
int main(int argc, char *argv[])
{
if (argc != 2) {
printf("I think you are missing something.\n");
return -1;
}
if (strcmp(argv[1], "I know the secret") != 0) {
printf("Pardon? What did you say?\n");
return -1;
}
printf("You know how to speak to programs, Mr. Reverse-Engineer\n");
return 0;
}
cmp [ebp+argc], 2 对应第一个判断,strcmp(Str2, "I know the secret") 对应第二个。要输出成功信息,第 1 个参数必须严格等于 I know the secret。
(3)构造输入并验证
D:\...\test> ./crackme1.exe "I know the secret"
You know how to speak to programs, Mr. Reverse-Engineer

图9:输入正确参数后输出成功信息。
参数里有空格,必须加引号,否则会被 shell 拆成三个参数,程序又回到"参数个数不对"的分支。
(4)crackme2 多了一道文件名校验
crackme2 直接跑,输出和 crackme1 一样是 I think you are missing something.,但把参数改对之后仍然失败,提示变成了:
I have an identity problem. On your own now.
这句"身份有问题"是关键线索。回到 IDA 看它的 main 流程图:

图10:crackme2 的 main 流程图,多了一次对 argv[0] 的 strcmp。
和 crackme1 相比,它在 argc 判断之后多了一次 strcmp:
loc_4012D5:
mov eax, [ebp+argv]
push offset Str2 ; "crackmeplease.exe"
push dword ptr [eax] ; Str1 = argv[0]
call _strcmp
test eax, eax
jz short loc_401341 ; 相等才继续
...
printf("I have an identity problem. On your own now.\n");
也就是说,程序要求 argv[0] 必须等于 crackmeplease.exe,所以要先改名再运行。注意:必须在 cmd 里跑,不能在 PowerShell 里跑。PowerShell 传的 argv[0] 带 ./ 前缀(./crackmeplease.exe),和 crackmeplease.exe 不相等,校验必失败;cmd 里 argv[0] 就是文件名本身。
D:\...\test> ren crackme2.exe crackmeplease.exe
D:\...\test> crackmeplease.exe "I know the secret"
We have a little secret: Chocolate

图11:在 cmd 下改名并输入正确参数,得到 Chocolate。
成功信息是 We have a little secret: Chocolate。
实验二完成b( ̄▽ ̄)d 。
3.3 实验三:RaDa 样本分析
(1)二进制文件摘要
| 项目 | 值 |
|---|---|
| 文件名 | RaDa.exe |
| 文件大小 | 20.50 KiB(加壳后) |
| 文件类型 | PE32 executable(GUI),Intel i386,Windows |
| 节区数 | 3(加壳)/ 4(脱壳后) |
| 编译器 | Visual Basic 6.0(MSVBVM60 运行时) |
| 加壳工具 | UPX 0.89.6–1.02,壳头被修改(UPX[modified]) |
| MD5(原始) | caaa6985a43225a0b3add54f44a0d4c7 |
| MD5(脱壳后) | 02bfa8e6d4ed8ed8049004fdad840d2a |
| 编译时间 | UTC 2004-10-29 23:59:58(北京时间 10-30 07:59:58),原始值 0x4182D97E |
| 硬编码 C&C | http://10.10.10.10/RaDa |
| 署名 | Raul Siles && David Perez |
三条命令一次跑完就能拿到主要信息:
cd ~/lab4
file RaDa.exe
md5sum RaDa.exe
exiftool RaDa.exe | grep "Time Stamp"

图12:样本的基本信息,文件类型、MD5、编译时间戳。
MD5 是最有用的一条。文件名可以改,扩展名可以改,MD5 改不了。把 caaa6985a43225a0b3add54f44a0d4c7 丢进 VirusTotal 或任何一个样本库,能直接关联到同家族的其他样本、历史报告和分析文章。
(2)文件的目的
五组字符串拼起来,行为链就完整了。
第一组是 C&C 地址:
mov edx, offset aHttp10_10_10_1 ; "http://10.10.10.10/RaDa"

图13:硬编码的 C&C 地址 http://10.10.10.10/RaDa。
第二组是指令与回传接口:
mov edx, offset aRada_commands_ ; "RaDa_commands.html"
mov edx, offset aCgiBin ; "cgi-bin"
mov edx, offset aDownload_cgi ; "download.cgi"
mov edx, offset aUpload_cgi ; "upload.cgi"

图14:指令文件与 CGI 上传下载接口。
第三组是工作目录 C:\RaDa\tmp:

图15:临时工作目录 C:\RaDa\tmp。
第四组是注册表自启项:
mov edx, offset aHklmSoftwareMi ; "HKLM\Software\Microsoft\Windows\Current..."
mov edx, offset aRada ; "RaDa"
mov edx, offset aReg_sz ; "REG_SZ"

图16:写入注册表 Run 项,值为 REG_SZ。
第五组是自身落地路径:
mov edx, offset aCRadaBin ; "C:\RaDa\bin"
...
push offset aRada_exe ; "RaDa.exe"

图17:拼接自身路径 C:\RaDa\bin\RaDa.exe。
结论很清楚:这是一个基于 HTTP 的远程控制后门。运行时先把自己复制到 C:\RaDa\bin\RaDa.exe,在注册表 HKLM\Software\Microsoft\Windows\CurrentVersion\Run 下写一个名为 RaDa 的自启项,然后周期性访问 http://10.10.10.10/RaDa/RaDa_commands.html 取指令,用 cgi-bin/download.cgi 下载文件、upload.cgi 上传文件,临时数据放在 C:\RaDa\tmp。它不做破坏,只负责驻留、听指令、传文件,典型的受控端角色。
用 HTTP 而不是自建协议是有意的:80 端口几乎不会被防火墙拦,流量混在正常 Web 访问里也不显眼。
(3)具有的特性
- 自我复制。把自身写到
C:\RaDa\bin\RaDa.exe,不依赖原始投放位置,用户删掉下载目录里的样本也不影响它运行。 - 注册表持久化。写入 Run 键,开机自动加载。
- HTTP 协议通信。用 80 端口做 C&C,能穿绝大多数企业防火墙,代理环境下也能工作。
- 指令文件驱动。控制端不需要和 bot 保持长连接,只要改服务器上的
RaDa_commands.html,bot 下次轮询就取到新指令。 - 双向文件传输。
download.cgi往下投文件,upload.cgi往上偷文件,具备窃密和二次投放能力。 - 体积小、有壳。20 KB 出头,UPX 压缩,便于通过邮件附件、网页下载等方式传播,也增加静态分析成本。
- VB6 编写。依赖
MSVBVM60.dll。
(4)防止被分析的技术
加壳是最主要的一层。UPX 把原始代码压缩,IDA 直接打开只能看到解压程序(stub),看不到任何业务逻辑,必须先脱壳。壳头还被改过(DIE 报 UPX[modified]),通用的 upx -d 未必能直接脱,需要专用脱壳机或手工跟 OEP。
符号剥离也是一层。脱壳后的函数全是 sub_404FB0 这种自动命名,没有可读的函数名,得靠调用关系、字符串交叉引用去推每个函数干什么。
VB6 运行时在客观上也提高了阅读门槛。VB 程序大量通过 __vbaStrCopy、__vbaStrCat、__vbaStrMove 这类运行时函数操作字符串,反汇编里全是间接调用和栈上参数搬运,比 C 编译出来的代码啰嗦得多,读起来费劲。
此外,字符串以 Unicode 存储会过滤掉一部分只用 strings 默认参数的分析者,不加 -el 什么都提不到。
(5)样本分类
分类为后门,更准确地说是基于 HTTP 的远程控制木马。
第一,它不具备自我传播能力。到达新主机只能靠使用者自己运行(邮件附件、下载诱导)。病毒和蠕虫的核心特征是自主复制传播,它没有。
第二,它的核心行为是驻留加等待指令。落盘、写自启、轮询指令文件,这三个动作构成一个完整的后门闭环,与病毒(感染文件)、蠕虫(网络自我复制)、木马下载器(只负责拉取载荷)都不同。
第三,它保留了完整的交互能力。有上传、有下载、有指令,控制端可以持续操作被控主机,这是后门区别于一次性载荷的关键。
(6)相似功能的其他工具
| 工具 | 年代 | 相似点 | 差异 |
|---|---|---|---|
| Back Orifice 2000(BO2K) | 1999 | 远程控制、文件传输、插件化 | 用自有 UDP 协议,有 GUI 控制端 |
| SubSeven | 1999–2003 | 后门 + 文件管理 + 屏幕/键盘监控 | 功能更杂,走 IRC 或自定义端口 |
| NetBus | 1998 | 简单远控、端口固定 | 功能少,特征明显易查杀 |
| pcAnywhere | 商业软件 | 合法远程桌面 | 正规产品,靠弱口令被滥用 |
| Gh0st / Poison Ivy | 2008 年后 | RAT,C&C 上线、文件管理 | 用了更隐蔽的协议与加密 |
| Meterpreter | 2004 年后 | 内存驻留、文件传输、命令执行 | 属于渗透框架,能力更强 |
从技术上看,RaDa 属于 BO2K 那一代的思路:小体积、单文件、固定端口或固定 URL、注册表自启。它比 BO2K 更现代的一点是用 HTTP 做信道,这也是后来大量商业木马和 APT 样本的通用做法。
(7)能否调查出开发者
可以,但只能到"署名级",到不了"身份级"。毕竟名不一定是真实的,需要联网搜索验证hhh。
依据:00403F7A 处的初始化代码里有明文 Raul Siles && David Perez。
调查需要两个环境:一是虚拟机(装 IDA 和 strings),取出样本自身的署名、版本、编译时间、VB6 特征;二是联网的环境,拿 MD5 和字符串去搜 VirusTotal、网页存档,看看此人是否真实存在。
限定条件有3条:① 壳得脱得掉,否则字符串是压缩状态,strings 提不出来;② 字符串不能加密;③ 署名不等于身份,落到具体的人还要联网查证。
(8)至少五种检测方法
方法一:基于特征码
最直接的一层。把 MD5 caaa6985a43225a0b3add54f44a0d4c7 加入黑名单,文件一落地就命中。更通用的是 YARA 规则,取几段有辨识度的字节做特征,比如 UPX 壳头加 RaDa_commands.html 这个字符串组合:
rule RaDa_Backdoor {
meta:
description = "RaDa HTTP backdoor"
strings:
$s1 = "RaDa_commands.html" ascii wide
$s2 = "http://10.10.10.10/RaDa" ascii wide
$s3 = "C:\\RaDa\\bin" ascii wide
condition:
uint16(0) == 0x5A4D and 2 of ($s*)
}
优点是快、误报低;缺点是一改字节就失效。
方法二:基于静态字符串与导入表
不依赖完整哈希,只看程序里有没有这些字符串。C:\RaDa\bin、C:\RaDa\tmp、RaDa_commands.html、upload.cgi、http://10.10.10.10/RaDa 这五个里命中两个以上就高度可疑。导入表里如果同时出现 MSVBVM60 的字符串函数、URLDownloadToFile/WinInet 系列、以及注册表操作 API,组合起来也是很强的信号。这一层能抓到改了壳、改了哈希但没改逻辑的变种。
方法三:基于网络流量
在出口做 HTTP 检测。请求 URI 里出现 /RaDa/RaDa_commands.html、/RaDa/cgi-bin/upload.cgi、/RaDa/cgi-bin/download.cgi 的直接告警;目的 IP 是 10.10.10.10 的重点看(这里虽是内网地址,真实环境里可能是任意公网 IP)。更通用的是行为特征:某台主机以固定周期(比如每分钟一次)访问同一个很小的 HTML 文件,返回内容每次不同但长度相近。优点是能发现未知变种,因为信道模式很难改;缺点是走 HTTPS 就看不见内容。
方法四:基于主机行为与注册表监控
监控 HKLM\Software\Microsoft\Windows\CurrentVersion\Run 的新增项,凡是值指向 C:\ 根目录下某个非系统目录(如 C:\RaDa\bin\RaDa.exe)的都应该告警。同时监控文件系统:C:\RaDa 目录被创建、C:\RaDa\tmp 下文件数快速增减(说明正在上传或下载)。用 Sysmon 配几条规则就能覆盖,误报率低,因为正常软件很少往 C 盘根目录写自己的可执行文件。
方法五:基于沙箱动态分析
把样本丢进沙箱跑几分钟,看它实际做了什么:有没有创建 C:\RaDa、有没有写 Run 键、有没有对外发起 HTTP 请求、请求的 URI 是什么。这一层能直接给出行为报告,不需要人工逆向。缺点是样本可能检测沙箱而不触发,也可能因为缺少 VB6 运行库直接崩掉。本次在 Windows 11 上就是这种情况。

图18:脱壳后的样本在当前系统无法直接执行。
方法六(补充):基于内存与进程行为
如果样本已经运行起来,可以查进程的模块加载(有没有加载 MSVBVM60.dll 且路径异常)、查进程的网络连接(netstat -ano 里有没有周期性连同一 IP:80 的短连接)、查父进程链。内存扫描则可以绕过加壳,直接从进程空间 dump 出解压后的代码再比对特征。
六种方法各有侧重:前两种查"文件长什么样",第三、四种查"它做了什么",第五、六种查"跑起来之后的状态"。实际部署时是分层叠加的,单靠任何一种都会漏。
实验三完成b( ̄▽ ̄)d 。
3.4 实验四:僵尸网络流量取证
(1)IRC 与端口
- IRC 全称 Internet Relay Chat,是 1988 年就有的、基于文本的实时聊天协议。客户端连到服务器,再进不同的频道和多人聊天。它协议简单、有现成的服务器软件、还能把一条消息广播给整个频道,所以早期僵尸网络普遍拿它当命令控制通道:控制者在频道里发一句指令,所有 bot 同时收到。
- 客户端连上服务器要先注册,发
NICK给自己起昵称、发USER填用户名和主机名,服务器设了连接口令的话前面还得加一条PASS。服务器确认昵称没被占用,回001~004欢迎码,这个客户端才算进了网络。要注意「加入网络」和「加入频道」是两步:注册完再发JOIN #频道名才进具体频道,聊天用PRIVMSG。 - 明文 IRC 传统上占 6660~6669 这一段,其中 6667 最常用,基本等于默认端口;走 TLS 加密的用 6697,也有服务器用 7000。
(2)僵尸网络
- 僵尸网络(botnet)指攻击者攻陷一批主机、植入受控程序之后,通过命令与控制服务器(C&C)集中操纵形成的网络。被控的主机叫 bot 或肉鸡,操纵者叫 botmaster。它和普通蠕虫的区别在于数量大、能同时动作、指令还能随时换。
- 常见用途有 DDoS 打带宽、群发垃圾邮件和钓鱼、窃取账号与浏览器凭据、点击欺诈刷广告、当代理跳板隐藏真实来源、静默挖矿,以及投放勒索软件和继续扫描扩张。
(3)蜜罐连过哪些 IRC 服务器
在 Wireshark 里打开 botnet_pcap_file.dat,用显示过滤器只看蜜罐主动发起的 IRC 连接请求:
ip.src==172.16.134.191 and tcp.dstport==6667 and tcp.flags==0x2
tcp.flags==0x2 是只取 SYN 包。SYN 是 TCP 三次握手的第一个包,一个 SYN 对应一次"我要连你",把重传和数据包都排除掉之后,剩下的目的 IP 就是它主动连过的服务器。

图19:蜜罐发往 6667 端口的 SYN 包,Destination 列即服务器列表。
去重后一共 5 个:
| # | IRC 服务器 IP |
|---|---|
| 1 | 209.126.161.29 |
| 2 | 66.33.65.58 |
| 3 | 217.199.175.10 |
| 4 | 63.241.174.144 |
| 5 | 209.196.44.172 |
一台主机在观察期内连了五个不同的 IRC 服务器,这本身就是异常,正常聊天用户不会这样。合理推断是 bot 内置了一张服务器列表,当前一个连不上就轮询下一个,这是僵尸网络客户端提高存活率的常见做法。
(4)多少主机访问了这个僵尸网络
有三种方法检验:
一:服务器公布的在线用户数
IRC 服务器会定期向客户端广播服务器状态,其中包含 current global users。用过滤器定位这一帧:
irc.response contains "global users"

图20:Wireshark 中定位到 global users 字段。
把字段单独提出来看得更清楚:
tshark -r botnet_pcap_file.dat -Y 'irc.response contains "global users"' -V | grep -A1 "global users"
结果是 global users: 4752 Max: 4765。

图21:服务器报告的在线用户数为 4752。
这个数字是服务器自己维护的计数,不依赖抓包是否完整,是三者里最可信的。
二:统计 JOIN 与 QUIT 的主机名
日志里每台 bot 上线会发 JOIN、下线会发 QUIT,两者都带主机标识。先用 tcpflow 把这条会话的载荷还原成文本文件:
cd ~/lab4
tcpflow -r botnet_pcap_file.dat "host 209.196.44.172 and port 6667"
ls -l 209.196.044.172*
tcpflow 的命名规则是"源 IP.源端口-目的 IP.目的端口",每段补齐位数,所以生成的文件名是 209.196.044.172.06667-172.016.134.191.01152。

图22:tcpflow 拆分出的 TCP 流文件。
然后统计:
F=209.196.044.172.06667-172.016.134.191.01152
cat $F | grep -a JOIN | cut -d '@' -f 2 | cut -d ' ' -f 1 | sort | uniq > join_hosts
cat $F | grep -a QUIT | cut -d '@' -f 2 | cut -d ' ' -f 1 | sort | uniq > quit_hosts
wc -l join_hosts quit_hosts
cat join_hosts quit_hosts | sort -u | wc -l

图23:JOIN/QUIT 统计结果。
得到 JOIN 主机 4793 个、QUIT 主机 4923 个,合并去重后 5581 个。
三:统计频道昵称
服务器用 353(RPL_NAMREPLY)广播频道成员名单,一行里带多个昵称:
cat $F | grep -a '^:irc5.aol.com 353' \
| sed 's/^.*353 [^ ]* [^ ]* #[^ ]* ://' \
| tr ' ' '\n' | tr -d '\r' | awk 'NF' | sort -u | wc -l

图24:按昵称去重统计。
得到 3462。
三种方法得到的结果分别是 4752、5581、3462。差异是因为统计对象不同:4752 是服务器当前在线人数,是某一时刻的快照;5581 是观察期内出现过的主机总数,包含中途上线又下线的,所以比快照大;3462 只统计了有昵称且在频道名单里出现过的,会漏掉没有昵称的,也会把中途换昵称的重复计,所以最小。
结论取 4752。服务器计数最接近同时在线规模,而且不受抓包丢包影响。
(5)攻击蜜罐的 IP
cd ~/lab4
tcpdump -n -nn -r botnet_pcap_file.dat 'dst host 172.16.134.191' \
| awk '{print $3}' | cut -d '.' -f 1-4 | sort -u > 20242312_实验四.txt
wc -l 20242312_实验四.txt

图25:统计结果,165 个不同源 IP。
165 个。完整清单已作为附件提交(20242312_实验四.txt),图 26 是清单开头部分。

图26:攻击 IP 清单(节选)。
(6)攻击了哪些漏洞
先用协议分层看整体构成(Statistics → Protocol Hierarchy):

图27:协议分层,TCP 占 99.66%,UDP 占 0.34%。
流量几乎全是 TCP,UDP 只有零星一点。再分别统计 TCP 和 UDP 端口。
tcpdump -r botnet_pcap_file.dat -nn 'src host 172.16.134.191 and tcp[tcpflags] == 0x12' \
| cut -d ' ' -f 3 | cut -d '.' -f 5 | sort -u
0x12 是 SYN(0x02)加 ACK(0x10)。结果:135、139、445、25、4899、80。

图28:TCP 端口统计结果。
UDP 无连接,只能看打过来的目的端口:
tcpdump -r botnet_pcap_file.dat -nn 'dst host 172.16.134.191 and udp' \
| cut -d ' ' -f 5 | cut -d '.' -f 5 | cut -d ':' -f 1 | sort -u
结果:137、1434、28431。

图29:UDP 端口统计结果。
端口与漏洞的对应关系:
| 端口 | 协议/服务 | 对应攻击 |
|---|---|---|
| 80/TCP | HTTP(IIS) | Code Red、Code Red II、FrontPage 扩展探测 |
| 135/TCP | RPC/DCOM | 端点映射探测,为后续 DCOM 攻击做准备 |
| 139/TCP | NetBIOS 会话服务 | 共享枚举、空会话、SMB 查点 |
| 445/TCP | SMB over TCP | 账户枚举、弱口令爆破、ADMIN$ 投放、psexec |
| 25/TCP | SMTP | 端口探活,未见实际利用 |
| 4899/TCP | Radmin 远程控制 | 弱口令接管、远程命令执行 |
| 137/UDP | NBNS | NetBIOS 名称查询,收集主机名、MAC、工作组 |
| 1434/UDP | SQL Server 监视器 | Slammer 蠕虫 |
| 28431/UDP | 非标准端口 | 疑似自定义通信,未见破坏行为 |
(7)哪些攻击成功了
UDP 137(NBNS)
65 个请求、64 个响应,涉及 64 个外部 IP,几乎是一对一的问答。响应里能读出蜜罐的完整身份:

图30:NBNS 响应中包含主机名、工作组与 MAC。
可以看到 PC0191<00>(工作站服务)、PC0191<20>(文件服务器服务)、PC0191<03>(信使服务)、SBM<00>(工作组名)、IWAM_PC0191,网卡 MAC 是 00:05:69:00:01:e2,OUI 属于 VMware,符合虚拟蜜罐的特征。
这一轮没有造成破坏,但它把主机名、工作组、MAC 全交出去了。攻击者拿到这些信息,接下来就可以针对性地打 139 和 445,找共享、猜账户。
UDP 1434(Slammer)
50 个会话、47 个 IP。每个包都是 376 字节,内容里有 h.dllhel32hkernQhounthickChGetTf、hws2_f、sockf、send 这些拼接过的 API 名:

图31:1434 端口的 376 字节 Slammer 载荷。
376 字节是 Slammer 的标志性特征,整个蠕虫就一个 UDP 包,不需要回连,也不落盘。从流量看只有单包发送,没有看到后续的感染扩散,判断为扫描或感染未遂。
TCP 25
3 个会话、1 个 IP。三次握手完成后没有传任何数据,包长度都是 0:

图32:25 端口只有握手,没有 SMTP 命令交互。
这是典型的 Connect 扫描,只探端口开不开,不继续谈。SMTP 本身没有被利用。
TCP 80
1181 个会话、7 个 IP。把每个 IP 的请求方法统计出来:

图33:80 端口 7 个攻击 IP 的请求数与请求方法。
| 源 IP | 请求数 | 方法 | 性质 |
|---|---|---|---|
| 24.197.194.106 | 954 | HEAD×947、GET×6、POST×1 | 大规模扫描 + 疑似后门上传 |
| 210.22.204.101 | 11 | GET | Code Red II 变种 |
| 68.169.174.108 | 4 | GET | 页面探测 |
| 66.8.163.125 | 1 | OPTIONS | 探测服务器允许的方法 |
| 218.25.147.83 | 1 | GET | Code Red |
| 213.23.49.158 | 1 | HEAD | 版本探测 |
| 192.130.71.66 | 1 | HEAD | 版本探测 |
HEAD 请求只取响应头不取正文,用来读 Server: 字段判断 IIS 版本,是扫描器的标准动作。954 次 HEAD 加 1 次 POST,说明 24.197.194.106 是在批量刷 URL 找可利用的路径,最后那次 POST 很可能是在往 root.exe 或 cmd.exe 上传内容。
追踪 210.22.204.101 的会话,能看到完整的 Code Red II 载荷:

图34:210.22.204.101 的请求,/NULL.IDA 加 Unicode 编码的 shellcode。
GET /NULL.IDA?CCCC… 后面跟着一长串 %u00a0%u838b%u0094%u0000%u408b…,这是把机器码用 Unicode 编码后塞进 URL,绕过 IIS 对特殊字符的过滤。这是 Code Red II 的典型手法。
追踪 218.25.147.83 的会话:

图35:218.25.147.83 的会话中出现了 notworm.LMTH 与 Hacked By Chinese。
请求是 GET /default.ida?NNNNNN…,标准的 Code Red 溢出。但真正关键的是响应里出现了:
c:\notworm.LMTH
<title>HELLO! Welcome to http://www.worm.com! Hacked By Chinese!</title>
notworm.LMTH 是 Code Red 用来标记"这台机器我已经处理过了"的文件,Hacked By Chinese! 是它篡改网页时写入的内容。这两样东西出现在响应里,说明蠕虫代码在蜜罐上确实执行了,并且走到了写标记文件、篡改页面的分支。
TCP 135
只有 1 个会话、1 个 IP,三次握手后无数据:

图36:135 端口同样只有握手。
探测 DCOM 端点映射器,没有进一步利用。
TCP 139
83 个会话、65 个 IP。会话内容里能看到 SMB 查点的直接证据:

图37:139 端口上的 SMB 查点请求。
!\PC0191\C.A: 这一串是 SMB 的目录浏览请求,PC0191 是蜜罐主机名(和 NBNS 里查到的一致),C 是共享名。攻击者在列共享、看目录。
为了确认有没有暴力破解,专门用登录失败状态码 0xC000006D(STATUS_LOGON_FAILURE)过了一遍,结果列表是空的:

图38:用失败状态码过滤,无匹配。
TCP 445
19 个会话、8 个 IP,这一段是真正出事的地方。把每个 IP 用的账户、访问的共享、失败次数汇总:

图39:445 端口 8 个 IP 的账户、共享与失败次数。
| 源 IP | 尝试账户 | 访问共享 | 失败次数 |
|---|---|---|---|
| 209.45.125.69 | Administrator、Guest、IUSR、IWAM、TsInternetUser | — | 28 |
| 66.139.10.15 | Administrator | — | 28 |
| 210.22.204.101 | Administrator | C$ |
21 后成功 |
| 61.111.101.78 | Administrator | ADMIN$ |
— |
| 195.36.247.77 | Administrator | ADMIN$、IPC$ |
— |
| 66.8.163.125 | Administrator(域 OCEAN) | C$、IPC$ |
— |
| 80.181.116.202 | Administrator(域 NOKIA) | IPC$ |
— |
| 129.116.182.239 | Administrator | IPC$ |
— |
两个 IP 各失败了 28 次还没进去,说明用的是字典暴力破解,没成功。210.22.204.101 试了 21 次之后成功,然后访问了 C$(C 盘根目录的默认共享),这是拿到管理员权限的直接标志。
129.116.182.239 的过程更完整,值得单独看。先是 NTLM 认证建立 IPC$ 连接:

图40:129.116.182.239 通过 NTLM 认证连接到 IPC$。
然后建立 \samr 管道。SAMR 是远程账户管理接口,用它可以直接枚举系统里的账户:

图41:建立 samr 管道。
一次响应里同时带出了五个账户:

图42:枚举出的账户,包括 Guest、IUSR_PC0191、IWAM_PC0191、TsInternetUser 等。
最后是管理员账户的登录会话:

图43:第二次登录会话(管理员账户)。
另有两条会话里直接能看到明文账户信息:OCEAN Administrator OCEAN 和 NOKIA Administrator NOKIA,格式是"域名 用户名 域名",说明攻击者用 Administrator 账号配域名进行认证。
61.111.101.78 的操作最能说明问题。它的会话里先是 SMB 版本协商(PC NETWORK PROGRAM 1.0、LM1.2X002、LANMAN2.1、NT LM 0.12),然后连 ADMIN$,最后出现:
\System32\PSEXESVC.EXE
Windows 5.0 / 2000

图44:通过 ADMIN$ 投放并执行 PSEXESVC.EXE。
PSEXESVC.EXE 是 psexec 工具的服务端程序。攻击者把管理员共享当传输通道,把服务程序丢到 %SystemRoot%\System32,注册成服务后启动,从而在目标上拿到一个 SYSTEM 权限的命令行。这是横向移动的标准套路,比单纯登录更进一层。
TCP 4899(Radmin)
9 个会话、2 个 IP。图 45 是其中一条会话的明文,能看到 ..\..\ 目录穿越和 cmd.exe:

图45:4899 端口会话中出现目录穿越与命令执行。
另一条(210.22.204.101)的会话内容大部分是不可读字节,只有大量 PSH, ACK:

图46:210.22.204.101 的 4899 会话,内容为加密数据。
结论
综合以上,按"有没有拿到实际权限或执行了代码"来分:
| 结果 | 依据 |
|---|---|
| 成功 | 210.22.204.101 用 Administrator 登录 445 并访问 C$;129.116.182.239 经 IPC$ 建立 samr 管道并枚举出 5 个账户;61.111.101.78 经 ADMIN$ 投放 PSEXESVC.EXE 并执行;218.25.147.83 触发 Code Red 代码执行,写下 notworm.LMTH 并篡改页面;4899 端口有会话完成了命令执行 |
| 部分成功 | 195.36.247.77、66.8.163.125、80.181.116.202 拿到了 ADMIN$/C$/IPC$ 的访问权限,但没有看到后续的落地或执行证据 |
| 失败 | 209.45.125.69、66.139.10.15 的爆破(28 次失败);Slammer(只有单包,无扩散);25、135 端口(只握手);FrontPage 探测(未见利用结果) |
还有一个值得注意的地方是攻击的时间分布。用 I/O 统计按 6000 秒一档看帧数:

图47:流量时间线,300000–360000 秒区间出现明显尖峰。
前 30 万秒的流量很平稳,每档只有一两百帧,到 30–36 万秒这段突然涨到 31954 帧,之后又回落。这个尖峰对应的是集中攻击期,多个 IP 在同一时间段内对蜜罐发起扫描和登录尝试。
实验四完成b( ̄▽ ̄)d 。
4.问题及解决方案
- 问题1:crackme2 输入正确参数仍然提示
I have an identity problem
参数明明是对的,程序却报身份错误。在 IDA 里看流程图才发现它多比较了一次 argv[0] 和 crackmeplease.exe。
- 问题1解决方案: 先把文件改名为
crackmeplease.exe,并且必须在 cmd 里运行。PowerShell 传的argv[0]是./crackmeplease.exe,带./前缀,字符串比较不相等;cmd 里传的是crackmeplease.exe,才能对上。
ren crackme2.exe crackmeplease.exe
crackmeplease.exe "I know the secret"
5.学习感悟、思考等
-
这次实验做完,最大的感受是眼见不一定为实。一开始看
RaDa.exe,file说它是 PE32、3 个节区用 DIE 一查,UPX[modified],壳还在。这时候如果直接拖进 IDA,看到的全是解压程序的代码。脱壳之后再打开,五组关键字符串几秒钟就定位到了。也让我理解了为什么恶意代码作者都爱加壳。 -
第二个感受是命令行的每个字符都有意义。这次实验中有几次是在输命令时出了问题:引号位置错一位,tcpdump 直接罢工;
awk用双引号,165 变成 29126;grep少个-a,输出被当成二进制吞掉;sed里一个全角冒号,统计结果直接是 0。这些错误在报错信息里往往看不出来,它不报错,只是给你一个错的数字。所以做完统计最好要找第二种方法交叉验证。
参考资料
- RFC 1459: Internet Relay Chat Protocol. J. Oikarinen, D. Reed, 1993. https://www.rfc-editor.org/rfc/rfc1459
- RFC 2810: Internet Relay Chat: Architecture. C. Kalt, 2000. https://www.rfc-editor.org/rfc/rfc2810
- Symantec Security Response. CodeRed Worm Analysis. 2001.
- CERT/CC. CA-2003-04: MS-SQL Worm (Slammer). 2003. https://www.cert.org/advisories/CA-2003-04.html
- MITRE. CWE-120: Buffer Copy without Checking Size of Input. https://cwe.mitre.org/data/definitions/120.html
- Microsoft. PE Format Specification. https://learn.microsoft.com/en-us/windows/win32/debug/pe-format
- UPX 官方文档. https://upx.github.io/

浙公网安备 33010602011771号