20242411 2026-2027-1 《网络与系统攻防技术》实验四实验报告
20242411 2026-2027-1 《网络与系统攻防技术》实验四实验报告
——恶意代码分析实践
学号:20242411 实验时间:2026年11月2日
1 基础知识
本次实验涉及的知识点包括 PE 文件结构、加壳与脱壳、VB6 程序的 p-code 特征、IRC 协议、僵尸网络以及抓包取证分析。
1.1 PE 文件结构与加壳、脱壳
PE(Portable Executable)是 Windows 可执行文件的标准格式。文件开头是 DOS 头(“MZ”),偏移 0x3C 处的 e_lfanew 指向真正的 PE 头;PE 头后面是 COFF 文件头(机器类型、节数量、时间戳)和可选头(入口点 AddressOfEntryPoint、镜像基址 ImageBase、子系统 Subsystem 等),再往后是节表和各节数据。分析时常用的节有 .text(代码)、.data(数据)、.rdata(只读数据、字符串)、.rsrc(资源,含版本信息)和 .idata(导入表)。
文件偏移(FOA)和内存地址(RVA)不是一回事,需要用节表换算:对于某一节,FOA = 节的文件偏移 + (RVA − 节的虚拟地址)。查看字符串、改字节、定位入口点时都要先做这个换算。
加壳是把自己写的程序压缩或加密后放进新节,并在入口点放一段“壳代码”。程序运行时先执行壳代码,在内存中把原始程序解开,再跳回原入口点(OEP)。所以加壳样本的入口点通常落在壳节里,原始代码段可能原始大小为 0,节熵也会明显偏高(压缩/加密数据的熵一般大于 7.2)。
脱壳一般分两步:先把进程内存 dump 出来,再修复导入表(IAT)。标准 UPX 壳可以直接用 upx -d 还原;但样本作者如果手工改了壳的节名、版本号或标志,标准解压就会失败,需要换通用脱壳机或手工修复。
熵是判断“是否加壳”的一个直观指标:正常代码节的熵多在 6 左右,压缩/加密数据接近 8。但熵高不等于一定是恶意代码,也可能是压缩过的正常程序,需要结合节名、导入表和字符串综合判断。
1.2 VB6 程序与 p-code
Visual Basic 6.0 编译的程序依赖 MSVBVM60.DLL 运行时。它有两种编译方式:原生代码(native)和 p-code。p-code 不是直接的 x86 指令,而是由 VB 运行时解释执行,因此导入表里往往只剩 MSVBVM60 的序号导入,IDA 反汇编出来的控制流也比较零碎。
这类程序有三个对分析很有用的特征:一是字符串多为 Unicode;二是资源里有 VS_VERSION_INFO(公司名、产品名、版本号);三是窗体、控件名会以明文留在程序里。对 rada 这种样本,字符串和版本资源往往比硬啃汇编更高效。
1.3 IRC 协议与僵尸网络
IRC(Internet Relay Chat)是 RFC 1459 定义、RFC 2810—2813 修订的实时文本聊天协议,采用客户端/服务器架构,多个服务器互联成 IRC 网络,用户加入频道(channel)聊天。协议是纯文本命令,直接看抓包就能读懂,这也是僵尸网络早期偏爱 IRC 做命令控制的原因。
客户端加入 IRC 网络时,先完成注册:可选的 PASS(连接密码),然后是 NICK(昵称)和 USER(用户名、主机名、服务器名、真实姓名)。按 RFC 的说法,只有 NICK 和 USER 都被服务器收到,客户端才算注册成功。注册后再用 JOIN #频道 [频道密码] 加入具体频道。
IRC 默认使用 TCP 6667,常见范围是 6660—6670,偶尔用 7000;IRC 不使用 UDP。
僵尸网络(botnet)是由大量被植入 bot 程序的主机组成的网络,这些主机通过命令与控制(C&C)服务器接受统一指挥。C&C 可以是 IRC、HTTP 或 P2P。僵尸网络最常见的用途是 DDoS、发送垃圾邮件、盗取凭证、做代理跳板、点击欺诈和挖矿。
1.4 抓包取证分析
抓包文件(pcap)由 libpcap 库生成,Snort 用 -b 参数也能写出同样格式的二进制日志。分析时一般先用显示过滤器把范围缩小,再对具体 TCP 流做重组,最后看应用层内容。Wireshark 的“追踪 TCP 流”(Follow TCP Stream)能把一条连接的双向数据拼起来,适合看 IRC、HTTP 这类文本协议;tshark 的 -T fields -e 参数适合做批量统计,比如统计某个端口的源 IP、某条流的编号。
抓包里的时间戳是 UTC 秒,Wireshark 默认按本机时区显示。写报告时要么统一用 UTC,要么在图注里注明“本地时间(UTC+8)”,否则时间线容易对不上。
2 实验内容
本次实验围绕“恶意代码分析”展开,分为样本识别与脱壳、CrackMe 分析、rada 样本分析和蜜罐取证分析四个部分。
2.1 实验问题
(1)rada 样本识别与脱壳:用文件格式和类型识别工具给出样本的文件格式、运行平台和加壳工具;用超级巡警等脱壳软件脱壳;对脱壳后的样本提取字符串,找出编写作者。
(2)CrackMe 分析:用 IDA Pro 对 crackme1.exe 和 crackme2.exe 做静态或动态分析,找出能输出成功信息的特定输入。
(3)rada 样本分析报告:回答八个问题,包括样本摘要与识别信息、样本目的、功能特性、防止被分析或逆向工程的技术、恶意代码分类及理由、历史相似工具、能否调查开发者及条件、至少五种检测方法。
(4)取证分析:基于 Snort 采集的 Windows 2000 蜜罐五天网络数据,回答 IRC 是什么、加入 IRC 网络发送什么消息、常用端口,僵尸网络是什么、用途,蜜罐与哪些 IRC 服务器通信,多少主机访问了 209.196.44.172 的僵尸网络,哪些 IP 攻击了蜜罐,攻击者尝试了哪些漏洞,哪些攻击成功及原因。
2.2 实验环境与工具
实验在 Windows 11(版本 22631)上完成,主机名按要求改为 chenzhiwu,工作目录为 D:\lab4_20242411。样本只在隔离目录中做静态分析,没有在宿主机上运行。主要工具见表 1。
表1 实验环境与工具
|
用途 |
工具 |
说明 |
|---|---|---|
|
文件类型与查壳 |
HAPEiD(PEiD 增强版) |
查看 EP、EP 段、子系统、壳特征 |
|
脱壳 |
超级巡警 VMUnpacker |
V1.3,支持多个 UPX 修改版 |
|
字符串 |
GNU strings |
分别提取 ASCII 与 Unicode 字符串 |
|
反汇编 |
IDA Pro 7.4 |
静态分析 CrackMe |
|
动态验证 |
cmd.exe / PowerShell |
在 run 目录运行 CrackMe |
|
流量分析 |
Wireshark / tshark 1.4.3 |
过滤、追踪 TCP 流、字段统计 |
|
辅助脚本 |
Python 3.8 + scapy |
PE 头解析、TCP 流重组与主机去重 |

图1 主机名与学号工作目录
2.3 实验简介与方案
整体思路是“静态优先、动态验证、样本隔离、分层过滤”。样本分析先看 PE 头和节表判断是否加壳,再判断壳的类型,决定用通用脱壳机还是手工修复;脱壳后以字符串、导入表和版本资源为主推断功能;CrackMe 先在 IDA 里定位 strcmp 和常量字符串,再在命令行验证;取证分析按“端口—会话—应用层”的顺序过滤,先找 IRC 服务器,再重组会话统计主机,最后回到 445、80、4899 等端口还原攻击链。
这样做的好处是每一步都有证据:静态分析给出“可能是什么”,动态验证给出“确实是怎样”,抓包统计给出“规模有多大”。
3 实验过程
3.1 样本文件类型识别与查壳
rada.rar 的解压口令是 rada,解压得到两个文件:RaDa.exe(20,992 字节,MD5 为 caaa6985a43225a0b3add54f44a0d4c7)和 rada_dump_.exe(老师提供的脱壳版本,77,824 字节)。为了安全,样本放在 D:\lab4_20242411\samples 下,只做静态查看,不双击运行。
用 HAPEiD 打开 RaDa.exe,显示文件为 PE32 格式、Win32 GUI 子系统,入口点 0x0000FD20,EP 段为 JDR1,首字节为 60 BE 00 C0(pushad; mov esi, 0x400000),壳识别结果为“UPX 0.89.6 - 1.02 / 1.05 - 2.90”。入口点在 JDR1 节而不是正常的代码节,说明程序被压缩过(图 2)。

图2 PEiD 查壳结果
再用自己写的 pe_info.py 解析 PE 头(图 3)。结果是:3 个节,分别是 JDR0(原始大小 0,运行时展开)、JDR1(原始大小 0x4000,熵 7.83)和 .rsrc;入口点 0xFD20 落在 JDR1;导入表只有 KERNEL32 的 LoadLibraryA、GetProcAddress、ExitProcess 以及 MSVBVM60 的序号 618(ThunRTMain);时间戳为 2004-10-29 23:59:58。JDR1 的熵接近 8,是典型的压缩/加密数据。

图3 加壳样本的 PE 头与节表
正常 UPX 的节名是 UPX0、UPX1,标志是 UPX!,版本串是 1.25。这个样本的节名被改成了 JDR0、JDR1,版本串被改成 9.99,入口点附近的 UPX! 被改成 JDR!。用 Python 读取 0x3D0 处的字节,能看到 39 2E 39 39 00 4A 44 52 21,也就是 ASCII 的“9.99”和“JDR!”。JDR 正好是三位挑战作者 Jorge、David、Raul 的首字母。
因此第一部分的答案是:文件格式为 PE32,运行平台为 Windows 2000/XP/2003(依赖 VB6 运行时),加壳工具为 UPX 1.25w 的修改版。
3.2 脱壳与导入表修复
先试标准做法 upx -d RaDa.exe,结果报“CantUnpackException:fileismodified/hacked/protected”,一个文件都没解开,说明壳确实被改过。于是改用超级巡警之虚拟机自动脱壳机 V1.3,它的说明里第 1 条就是“新支持脱 UPX 多个最新修改版”,正好对应这种情况。
在 VMUnpacker 里选择 RaDa.exe,点击脱壳,提示“Unpack successfully!”,输出 RaDa_unpacked.exe。把它改名为 rada_dump_.exe 后重新解析:文件大小 71,680 字节,4 个节,分别是 JDR0、JDR1、.rsrc 和 .dsWlab(脱壳工具追加的修复节);入口点变成 0x18A4,导入目录被重建到 0x11000,导入表恢复成 msvbvm60.dll 的一批序号。
需要说明的是,我这个 dump 和老师压缩包里自带的 rada_dump_.exe(77,824 字节,节表是 .newIID、.mackt)并不完全一样,这是工具版本和导入表重建方式不同造成的。判断脱壳是否成功,关键看入口点是否回到 0x18A4、字符串和资源是否能正常读出,而不是看文件大小是否和老师的一致。

图4 超级巡警 VMUnpacker 脱壳结果与脱壳后 PE 信息
3.3 字符串提取与作者定位
对脱壳后的文件分别提取 ASCII 和 Unicode 字符串,再筛选关键字:
strings -n 5 samples\rada_dump_.exe > out\rada_ascii.txt
strings -n 5 -el samples\rada_dump_.exe > out\rada_unicode.txt
Select-String -Path out\rada_ascii.txt,out\rada_unicode.txt -Pattern "Raul|Siles|Perez|SotM|Authors"
结果命中了“(c) Raul Siles && David Perez”“Authors: Raul Siles & David Perez, 2004”“Scan Of The Month 32 (SotM) - September 2004”,还有 RaDa v0.22 和 honeynet.org 的链接(图 5)。因此 rada 的编写作者是 Raul Siles 和 David Perez,这是 2004 年 Honeynet Project “Scan of the Month 32” 的挑战样本。(需要说明的是,他们是这个教学样本的作者,不等同于真实攻击事件中的操盘者)

图5 脱壳样本中的作者字符串
3.4 crackme1 的静态分析与动态验证
crackme1.exe 大小 595,909 字节,MD5 为 4357bf8c20fabb642fafc0b73fb0abfb,是 MinGW/gcc 3.4.5 编译的 PE32 控制台程序,带 .stab 调试信息,导入 msvcrt 的 printf、strcmp。用 IDA Pro 7.4 打开后,左侧“函数名称”面板里能直接看到 _main(0x401280)。
主函数先检查 argc 是否等于 2,不等于就打印“I think you are missing something.”并返回;等于 2 时把 argv[1] 和 0x403024 处的字符串比较,这个字符串就是“I know the secret”。比较相等就跳到成功分支,打印“You know how to speak to programs, Mr. Reverse-Engineer”,返回 0(图 6)。

图6 crackme1 主函数反汇编
命令行验证:参数错误时输出“Pardon? What did you say?”,退出码 2;传入“I know the secret”时输出成功信息,退出码 0;不带参数时退出码 1。说明静态分析和动态结果完全对得上(图 7)。

图7 crackme1 成功输出
3.5 crackme2 的静态分析与动态验证
crackme2.exe 大小 596,596 字节,MD5 为 46aa577172d8f37ae2ae281515c99afb,编译方式与 crackme1 相同。主函数比 crackme1 多了两段逻辑:
第一段是比较 argv[0] 和 0x403024 处的“crackmeplease.exe”。注意这里压入的是 [eax],也就是 argv[0](程序自己的名字),没有加 4;名字不匹配就打印“I have an identity problem.”并返回。第二段才比较 argv[1] 和 0x403053 处的“I know the secret”。两个检查都通过后,程序把 0x403080 处的 0x21 个字节逐个与 0x42 异或,再用 putchar 输出,明文是“We have a little secret: Chocolate”(图 8)。

图8 crackme2 主函数反汇编
动态验证时踩了一个坑:在 PowerShell 里用“.\crackme2.exe "I know the secret"”运行,程序一直报“I have an identity problem.”。原因是 Windows 下 argv[0] 就是命令行里输入的字符串,带了“.\”前缀就不等于“crackmeplease.exe”。把文件复制成 crackmeplease.exe,用 cmd 进入目录后直接输入文件名运行,才通过(图 9)。

图9 crackme2 成功输出
表4 两个 CrackMe 的特定输入
|
程序 |
特定输入 |
成功输出 |
|---|---|---|
|
crackme1.exe |
参数 1 = I know the secret |
You know how to speak to programs, Mr. Reverse-Engineer |
|
crackme2.exe |
文件改名为 crackmeplease.exe,参数 1 = I know the secret |
We have a little secret: Chocolate |
3.6 rada 恶意代码分析(八个问题)
3.6.1 样本摘要与识别信息
rada 的样本信息见表 2。识别同一样本时,最可靠的四样是 MD5、节名、版本资源和特征字符串:文件名可以随便改,但 PE 结构、版本资源和“SotM 32”这类字符串改起来要费劲得多。
表2 rada 样本基本信息
|
项目 |
内容 |
|---|---|
|
文件名 |
RaDa.exe(脱壳后 rada_dump_.exe) |
|
大小 |
20,992 字节(脱壳后 71,680 字节) |
|
MD5 |
caaa6985a43225a0b3add54f44a0d4c7 |
|
文件格式 |
PE32,Win32 GUI,VB6 编写,依赖 MSVBVM60.DLL |
|
编译时间 |
2004-10-29 23:59:58(UTC) |
|
加壳 |
UPX 1.25w 修改版(JDR0/JDR1、9.99、JDR!) |
|
版本资源 |
CompanyName=Malware,ProductName=RaDa,FileVersion=1.00 |
|
内部标识 |
RaDa v0.22,Scan Of The Month 32 (SotM),Copyright (C) 2004 Raul Siles & David Perez |
|
关键字符串 |
C:\RaDa\bin、C:\RaDa\tmp、RaDa_commands.html、download.cgi、upload.cgi、InternetExplorer.Application、ADODB.Stream |

图10 版本资源与关键字符串
3.6.2 样本的目的
rada 是一个基于 HTTP 的远程控制后门。它运行后先把自己安装到 C:\RaDa\bin,写注册表 Run 键实现开机自启动,然后进入一个循环:每 60 秒从 Web 服务器取回一个“命令网页”,解析表单里的命令并执行,再睡 60 秒。
它最特别的地方是不自己开 socket,而是偷偷启动一个隐藏的 Internet Explorer 实例,让 IE 去访问命令网页。这样能自动继承用户配置的代理、PAC 和浏览器设置,穿过企业代理;如果主机防火墙只允许 IE 上网,rada 照样能拿到命令;从流量上看也只是普通的 HTTP 访问。攻击者因此可以获得与登录用户几乎相同的控制权。
3.6.3 样本的功能特性
rada 的功能可以分成四类。第一类是安装与持久化:复制自身到 C:\RaDa\bin\RaDa.exe,写 HKLM\Software\Microsoft\Windows\CurrentVersion\Run\RaDa(REG_SZ),创建并切换到工作目录 C:\RaDa\tmp,支持 --uninstall、--noinstall、--installdir;因为要写 HKLM,安装需要管理员权限。
第二类是命令执行。命令网页是一个 HTML 表单,元素的 name 是命令名、value 是参数,rada 支持五条命令,见表 3。
表3 rada 支持的五类命令
|
命令 |
作用 |
|---|---|
|
exe |
用隐藏的 cmd.exe /c 执行 value 中的命令 |
|
get |
通过 IE 从 cgi-bin/download.cgi 下载文件到 C:\RaDa\tmp |
|
put |
通过 IE 把本地文件 POST 到 cgi-bin/upload.cgi |
|
screenshot |
模拟 Ctrl+Alt+PrintScreen(keybd_event)截屏,保存为 BMP |
|
sleep |
暂停 value 指定的秒数 |
第三类是通信:取命令用 GET /RaDa/RaDa_commands.html;下载用 POST /RaDa/cgi-bin/download.cgi,服务器返回 uuencode 文本;上传用 POST /RaDa/cgi-bin/upload.cgi,multipart 的 boundary 固定为“---------------------------0123456789012”。
第四类是命令行与界面:支持 --server、--commands、--cgipath、--cgiget、--cgiput、--tmpdir、--period、--cycles、--gui、--verbose、--visible、--help、--authors 等参数;带 --gui 时会出现 Install、Uninstall、Go!、Show config、Show usage 按钮。
3.6.4 防止被分析与逆向工程的技术
第一是修改版 UPX。作者先用 UPX 压缩,再手工改掉节名(UPX0/UPX1 改成 JDR0/JDR1)、版本号(1.25 改成 9.99)、UPX! 标志(改成 JDR!)和 DOS 提示语。结果是 strings 拿不到明文,标准 upx -d 直接失败,IDA 打开也只是一段壳代码。这是本样本最主要的反分析手段。
第二是诱饵字符串。脱壳后能看到“Starting DDoS Smurf remote attack...”,看起来像 DDoS 工具,但 rada 实际上没有任何 DDoS 功能。这句话是故意放的烟雾弹,用来误导分析人员把它归类成 DDoS 工具而停止深入分析。
第三是省略帮助信息。--help 只显示版权,不解释参数;--verbose 没有实际作用;GUI 的 Show config 和 Show usage 也只是重复版权页。分析人员只能靠猜和试来还原参数含义。
第四是虚拟机环境检测。程序会检查网卡 MAC 是否属于 VMware 的 00:0C:29、00:50:56、00:05:69 段,以及注册表里是否存在 HKLM\Software\VMware, Inc.\VMware Tools\InstallPath。一旦判定在 VMware 里,--authors 参数会被当成未知参数,不显示作者信息。
另外,样本里直接留着“Security through obscurity is the key.”这句话,作者自己也知道这只是提高门槛;VB6 的 p-code 也让 IDA 的反汇编比较零碎。需要说明的是,它没有加反调试、没有做代码混淆和多态,也没有加密通信,这些手段只能劝退初级分析人员。
3.6.5 分类与理由
rada 应归类为后门(backdoor)/木马(trojan),同时具有间谍软件(spyware)性质。理由有三点:它把自身安装到系统并写 Run 键长期驻留;它接受远程指令执行任意命令、上传下载文件,等于把主机控制权交给攻击者;它可以截屏、窃取文件,具备间谍软件特征。
它不能自我复制、不能感染其他文件、不能主动扫描传播,所以不是病毒,也不是蠕虫。它需要借助钓鱼、漏洞或人工投放进入主机,这一点和蠕虫有本质区别。
3.6.6 历史上功能相似的其他工具
最接近的是 Setiri 及其前身 GatSlag(Roelof Temmingh、Haroon Meer,2002 年 Black Hat 演讲)。它们和 rada 的思路几乎一样:用隐藏的 IE 作为通信通道,绕过个人防火墙和代理,属于“HTTP 隧道型后门”的典型代表。
再往前看,Back Orifice / BO2K 提供文件、进程、注册表、截屏等远程控制能力;Sub7、NetBus 是上世纪的图形化远程控制木马;国内早期的冰河同样具备文件管理、屏幕控制和命令执行能力。Agobot/SDBot 一类 IRC 僵尸程序在“远程控制 + 下载执行”上与 rada 有交集,但它们走 IRC 协议,而 rada 走 HTTP,这是关键区别。
3.6.7 能否调查开发者及条件
可以追到“样本作者”,但追不到“真实攻击者”。具体条件是:在非 VMware 的真实机或改过 MAC 的虚拟机上运行;去掉 HKLM\Software\VMware, Inc.\VMware Tools\InstallPath 这个键;让 MAC 地址不在 00:0C:29、00:50:56、00:05:69 三个段内;执行 RaDa.exe --authors,会弹窗显示“Authors: Raul Siles & David Perez, 2004”。
不运行程序也可以:直接 strings 脱壳样本,能看到同样的版权与作者字符串;--help 的版权页也会显示作者。局限是这些信息来自样本本身,作者是谁、是否用了真名只能作为线索,不能作为法律意义上的归因;rada 是教学样本,作者就是出题人,和真实僵尸网络操盘者不是一回事;如果样本被二次修改,这些线索也可能被抹掉。
3.6.8 至少五种检测方法
方法一,基于特征码和哈希。计算文件 MD5,与威胁情报库比对;用杀毒引擎扫描(历史上 NOD32 报 Win32/DDoS.Rada.A,Sybari 报 Win32/Rada.A.Trojan);写 YARA 规则匹配多个特征字符串:
rule RaDa_SotM32
{
meta:
author = "20242411"
description = "Detect RaDa backdoor (Honeynet SotM32)"
strings:
$a = "RaDa_commands.html" ascii wide
$b = "C:\\RaDa\\tmp" ascii wide
$c = "SotM 32" ascii wide
$d = "Authors: Raul Siles & David Perez" ascii wide
$e = "download.cgi" ascii wide
condition:
uint16(0) == 0x5A4D and 2 of them
}
这种方法的优点是快、误报低;缺点是改一个字节或换壳就可能绕过,只能作为第一道筛子。
方法二,PE 结构检测。检查节名是否为 JDR0/JDR1,检查 UPX 版本串是否为 9.99、入口点附近是否有 JDR!,检查是否同时具备“VB6 序号导入 + 高熵节 + 极小导入表”的组合,检查版本资源里 CompanyName 是否为 Malware。这种方法不需要运行样本,适合在文件网关、邮件网关做批量筛查。
方法三,主机痕迹检测。感染后会有固定痕迹:C:\RaDa\bin\RaDa.exe、C:\RaDa\tmp 目录,Run 键 RaDa,进程列表里出现 RaDa.exe,且它的子进程是隐藏的 cmd.exe /c 或 iexplore.exe。可以用 Process Explorer 看进程树、用 Regshot 对比注册表快照、用文件完整性基线定期比对。
方法四,网络流量检测。rada 的 HTTP 行为很有特征:GET /RaDa/RaDa_commands.html、POST download.cgi/upload.cgi、固定的 multipart boundary、下载响应是 uuencode 文本、每 60 秒一次周期请求。对应的 Snort 规则可以写成:
alert tcp any any -> any $HTTP_PORTS (msg:"RaDa - command page request"; \
flow:to_server,established; content:"GET /RaDa/RaDa_commands.html"; depth:30; \
classtype:trojan-activity; sid:1000001; rev:1;)
alert tcp any any -> any $HTTP_PORTS (msg:"RaDa - multipart upload"; \
flow:to_server,established; \
content:"boundary=---------------------------0123456789012"; depth:1024; \
classtype:trojan-activity; sid:1000002; rev:1;)
这类规则的问题是 HTTP 太常见,改个文件名或路径就可能绕过,而且 NAME=exe 之类的内容可能误报,所以要和“非浏览器进程发起 IE 流量”“固定周期”等行为特征一起判断。
方法五,行为与异常检测。监控“非浏览器进程创建隐藏的 iexplore.exe 子进程”、keybd_event 截屏、ADODB.Stream 写文件、WScript.Shell 写注册表、cmd.exe /c 由非交互进程启动等 API 组合;在沙箱里跑一遍,看是否访问 10.10.10.10 这类私网地址、是否写入 C:\RaDa。行为检测不依赖特征码,对改壳、改字符串的变种更有效,但需要先建立正常行为基线。
方法六,策略与基线。普通用户不给管理员权限(rada 安装需要写 HKLM,非管理员跑不起来);限制服务器和数据库主机访问互联网;只允许签名程序运行;定期做主机基线比对;开展用户安全意识培训。六种方法单独用都有短板,实际中最有效的是“网关特征 + 主机痕迹 + 出站流量”三层一起上。
3.7 蜜罐取证分析(七个问题)
3.7.1 数据说明与分析方法
数据文件为 botnet_pcap_file.dat,18,119,637 字节,MD5 为 861985254440038791B88228C231306F,是 libpcap 格式的抓包,共 54,536 个包,时间范围是 2003 年 3 月 1 日至 3 月 6 日。背景是一台 Windows 2000 蜜罐(172.16.134.191),管理员口令为空,五天内被多次攻破并加入 IRC 僵尸网络;抓包用 Snort 采集,去掉了无关流量,IP 做过混淆。
分析方法分三步:先用 Wireshark 的显示过滤器缩小范围(6667、445、80、4899 等端口),再用“追踪 TCP 流”看应用层内容,最后用 tshark 的字段统计和 Python 的 TCP 流重组做批量计数。需要说明的是,本机安装的是 Wireshark 1.4.3,tshark 不支持新版本的 -Y 参数,读过滤器要用 -R,也不支持 -z follow,所以会话重组主要靠 Wireshark 界面和 Python 脚本完成。
3.7.2 IRC、加入消息与端口
IRC 是 RFC 1459 定义、RFC 2810—2813 修订的实时文本聊天协议,采用客户端/服务器架构,多个服务器互联成 IRC 网络,用户加入频道聊天。协议是纯文本命令,直接看抓包就能读懂。
客户端加入 IRC 网络时,先完成注册:可选的 PASS,然后是 NICK 和 USER。按 RFC 的说法,只有 NICK 和 USER 都被服务器收到,客户端才算注册成功。注册后再用 JOIN #频道 [频道密码] 加入具体频道。IRC 默认使用 TCP 6667,常见范围 6660—6670,偶尔用 7000,不使用 UDP。
3.7.3 僵尸网络及其用途
僵尸网络是由大量被植入 bot 程序的主机组成的网络,这些主机通过 C&C 服务器接受统一指挥。C&C 可以是 IRC、HTTP 或 P2P。常见用途包括 DDoS、发送垃圾邮件、盗取凭证、做代理跳板、点击欺诈和挖矿。本数据集中,蜜罐被拉进的正是 IRC 型僵尸网络。
3.7.4 蜜罐通信的 IRC 服务器
在 Wireshark 中过滤 ip.addr == 172.16.134.191 && tcp.port == 6667,可以看到蜜罐尝试连接了 5 个 IRC 服务器(图 11)。其中只有 209.196.44.172 是持续通信、真正加入成功的 C&C;63.241.174.144 返回了昵称占用和超时,217.199.175.10 短暂通信后关闭,66.33.65.58 和 209.126.161.29 只有 SYN,没有建立连接。
表5 蜜罐尝试连接的 IRC 服务器
|
IRC 服务器 |
端口 |
结果 |
|---|---|---|
|
209.196.44.172 |
6667 |
连接成功,持续通信,真正的 C&C |
|
217.199.175.10 |
6667 |
短暂通信后关闭 |
|
63.241.174.144 |
6667 |
昵称占用/连接超时 |
|
66.33.65.58 |
6667 |
只有 SYN,未建立 |
|
209.126.161.29 |
6667 |
只有 SYN,未建立 |

图11 蜜罐通信的 IRC 服务器
3.7.5 僵尸网络的主机数量
对与 209.196.44.172:6667 的会话做 TCP 流重组,统计 JOIN 和 QUIT 消息里的 nick!user@host,去重后得到 5,580 台不同主机(图 12)。这个数字有三种口径:按 JOIN/QUIT 的 host 去重是 5,580;蜜罐加入时服务器自报在线用户 4,752(4 台服务器合计,含隐身用户,可能含非 bot 用户);蜜罐加入时 NAMES 返回的昵称是 3,457(只是那一刻频道里的昵称数)。题目问的是“观察期间多少不同主机访问”,所以采用 5,580。
我一开始用 PowerShell 的 Select-String 去统计,但还没有把 Follow Stream 的内容保存成文件,命令报“路径不存在”。后来改用 Python 的 scapy 对同一条 TCP 流按序列号重组,再提取 nick!user@host 去重,结果稳定在 5,580,和官方 writeup 对得上。

图12 僵尸网络主机数量统计
3.7.6 攻击蜜罐的源 IP
按“目的地址等于 172.16.134.191”统计,tshark 得到 165 个向蜜罐发包的源 IP;官方 Argus 清单列出 171 个对端,但其中混进了 0.0.0.0、80.20.0.0、112.2.64.0 三个被 sed 截断产生的伪条目,去掉后实际对端约 168 个,其中约 154 个向蜜罐发送过应用层数据。报告里采用“165 个实际源 IP,官方口径 171 个”的写法,避免口径混淆。主要攻击端口和代表 IP 见表 6。
表6 主要攻击端口与代表源 IP
|
端口 |
代表源 IP |
说明 |
|---|---|---|
|
445 |
210.22.204.101、61.111.101.78、66.8.163.125、66.139.10.15、80.181.116.202、129.116.182.239、195.36.247.77、209.45.125.69 |
SMB 空口令,最关键的入口 |
|
80 |
24.197.194.106、210.22.204.101、218.25.147.83、68.169.174.108 |
IIS .ida 溢出、Code Red II、WebDAV 探测 |
|
139 |
4.64.221.42、61.177.154.228、210.22.204.101 等 65 个 |
NetBIOS 共享探测 |
|
137 |
64 个源 IP |
NBNS 名称查询,信息泄露 |
|
1434 |
47 个源 IP |
SQL Slammer 探测 |
|
4899 |
210.22.204.101 |
Radmin 后门连接 |
|
28431 |
62.150.170.134、62.150.170.232 |
Hack-A-Tack 探测 |
3.7.7 攻击者尝试的漏洞
第一类是 udp/137 的 NetBIOS 名称查询,属于信息收集,能拿到主机名、域、工作组等信息,例如 PC0191、ADMINISTRATOR、IWAM_PC0191、SBM。第二类是 tcp/139 的 NetBIOS 会话与 SMB 共享探测,尝试访问 \\PC0191\\C 和 \\PC0191\\IPC$,多数被拒绝或复位。
第三类是 tcp/80 的 IIS 攻击:210.22.204.101 发送超长的 /NULL.IDA?CCCC...%u0aeb...,是典型的 .ida 缓冲区溢出(类似 eEye 公布的 IIS 溢出),shellcode 里带 cmd.exe;218.25.147.83 发送 /default.ida?NNNN...,是 Code Red II 蠕虫的扫描请求;24.197.194.106 做了大量 Web 路径探测。
第四类是 tcp/445 的 SMB 攻击:Windows 2000 的 SMB 服务,攻击者利用空管理员口令建立会话,通过 SAMR 接口读取账户信息。第五类是 udp/1434 的 SQL Slammer 探测(47 个源 IP,固定 376 字节),蜜罐没装 SQL Server,没有成功;而且蜜罐外发的 UDP 包中没有一个是 1434 源端口,说明蠕虫没有在蜜罐上执行。第六类是 udp/28431 的 Hack-A-Tack 探测(源端口 28432),只有一个字节,无响应。
另外还有 tcp/135 的端口探测(195.36.247.77),三次握手后立刻 FIN,没有 DCOM 利用载荷;MS03-026 是 2003 年 7 月才公开的,而抓包是 2003 年 3 月,时间上也不可能是 DCOM 漏洞攻击。tcp/4899 的 Radmin 连接是攻击的结果,不是入口。
3.7.8 成功的攻击及原因
成功的部分主要有四条。第一,tcp/445 的空口令 SMB 会话:蜜罐 Administrator 口令为空,攻击者无需认证即可建立会话并读取 SAMR 信息。第二,文件上传与后门安装:210.22.204.101 在 3 月 5 日 02:39 向 C:\\WINNT\\System32 写入 r_server.exe、raddrv.dll、admdll.dll(RAdmin 套件),02:44:24 成功连上 tcp/4899,建立加密的 Radmin 后门。
第三,Deloder 上传:61.111.101.78 在 3 月 6 日 03:35 通过 ADMIN$ 上传 PSEXESVC.EXE、inst.exe(Deloder 蠕虫组件),随后用 net share /delete 清理共享。第四,加入僵尸网络:3 月 6 日 04:23:20,蜜罐以 rgdiuggac 为昵称连上 209.196.44.172:6667,JOIN 了频道(频道名被混淆,带频道口令 sex0r),成为 5,580 台 bot 中的一台。
Deloder 上传比入网只早约 48 分钟,而 Radmin 早在 26 小时前就装好了,所以把蜜罐拉进 botnet 的更可能是 Deloder 这条线,Radmin 是另一条独立的远控后门。udp/137 的信息泄露也算“成功”,但它只是信息收集,不是攻破。
失败的部分:tcp/80 的 .ida 溢出和 Code Red II 没有返回 shell,蜜罐也没有开始对外扫描;tcp/139 的共享访问多数被拒绝;udp/1434 的 Slammer 没有执行;udp/28431 的 Hack-A-Tack 无响应;tcp/135 只有端口探测。
成功的原因核心就两条:空管理员口令,以及未打补丁的 Windows 2000 开放了 445/139 等 SMB 服务。攻击者几乎不需要高级漏洞利用,用现成的 SMB 工具和蠕虫就能拿到权限;拿到权限后上传 Radmin、装后门、连 IRC,一套流程全是自动化工具完成的。

图13 SMB 上传文件与后门证据
表7 关键攻击时间线(UTC)
|
时间(2003年) |
事件 |
|---|---|
|
03-01 09:08 |
抓包开始,蜜罐 172.16.134.191(PC0191)在线,445/139/80 暴露,管理员口令为空 |
|
03-05 02:38:14 |
210.22.204.101 通过 tcp/445 用空口令建立 SMB 会话,枚举 SAMR |
|
03-05 02:39:06—02:39:15 |
向 C:\WINNT\System32 写入 r_server.exe、raddrv.dll、admdll.dll |
|
03-05 02:44:24 |
210.22.204.101 连上 tcp/4899,Radmin 后门建立 |
|
03-06 03:35:35—03:36:22 |
61.111.101.78 通过 ADMIN$ 上传 PSEXESVC.EXE、inst.exe(Deloder),随后删除共享清场 |
|
03-06 04:23:20 |
蜜罐以 rgdiuggac 加入 209.196.44.172:6667 的 IRC 频道(口令 sex0r) |
|
03-06 08:27 |
抓包结束,观察期内该频道共出现 5,580 台不同主机 |
3.8 实验结果汇总
四部分的结果可以概括为:rada 是 UPX 修改版加壳的 VB6 HTTP 后门,作者是 Raul Siles 和 David Perez;crackme1 的特定输入是“I know the secret”,crackme2 还需要把程序改名为 crackmeplease.exe;蜜罐在五天里被以空口令 SMB 攻破,攻击者安装了 Radmin 和 Deloder,并把主机拉进了一个 5,580 台规模的 IRC 僵尸网络。
4 问题及解决方案
问题 1:crackme2 在 PowerShell 里用 .\crackme2.exe 运行,一直报“I have an identity problem.”。原因是 Windows 下 argv[0] 就是命令行原文,带了“.”前缀就不等于 crackmeplease.exe。
解决办法是把文件复制成 crackmeplease.exe,在 cmd 里直接输入文件名运行。
5 学习感悟、思考等
这次实验最大的感受是:“分析”比“运行”更重要,而工具给出的结论不能全信。第一部分查壳时,我一开始以为 PEiD 显示什么就照抄什么,结果发现 upx -d 根本解不开,PEiD 显示的节名也不是 UPX0/UPX1。把 PE 头手工翻了一遍,看到 JDR0/JDR1、9.99、JDR! 才反应过来:壳被作者改过。后来查资料确认,JDR 是三位出题人 Jorge、David、Raul 的首字母。这个小细节让我印象很深——加壳工具的特征是死的,分析人员得看结构、看熵、看字符串。
CrackMe 部分让我踩了一个很典型的坑。crackme2 静态分析时我已经看到它比较的是 argv[0],但动态验证时还是习惯性地用 .\crackme2.exe 去跑,结果一直报“身份问题”。折腾了一会儿才想明白:Windows 下 argv[0] 就是命令行里输入的那串字符,带 .\ 前缀就不等于 crackmeplease.exe。改成在目录里直接输入文件名才通过。
第四部分的 pcap 有 18 MB、5 万多包,一开始直接 tshark 刷屏,根本看不过来。后来按“先端口、再会话、最后应用层”的顺序过滤,才慢慢理出头绪:先看 6667 找到 IRC 服务器,再 Follow TCP Stream 统计 JOIN,最后回到 445/80 看攻击链。统计出 5,580 台主机的时候还是挺有成就感的,说明自己的过滤条件没写错。
不足之处也很明显:对 VB6 p-code 的反编译不熟,rada 的具体代码逻辑主要靠字符串和资料推断,没能把每个函数都还原出来
总的来说,这次实验让我把查壳、脱壳、字符串、IDA、抓包这些零散的工具串成了一条线,也真正理解了“空口令 + 未打补丁”有多致命——一台 Windows 2000 蜜罐上线五天,就被几千台机器“围观”,最后变成僵尸网络的一部分。安全防护里,最基础的口令和补丁,往往比任何高级设备都重要。
浙公网安备 33010602011771号