20242310 2026-2027-1 《网络与系统攻防技术》实验四实验报告
20242310 2026-2027-1 《网络与系统攻防技术》实验四实验报告
1. 基础知识
(1)恶意代码及其分类。 恶意代码(Malicious Code)是指故意编制或设置的、对网络或系统会产生威胁或潜在威胁的计算机代码。常见类型包括:计算机病毒(附着于宿主文件、需要宿主传播、具有感染性)、蠕虫(不依赖宿主、能自主通过网络传播)、木马(伪装成正常程序、不自我复制,为攻击者打开后门)、后门(绕过正常认证获得远程访问通道)、僵尸程序(Bot,接受控制端一对多指令的木马变种,大量 Bot 组成僵尸网络 Botnet)等。
(2)PE 文件与加壳/脱壳。 PE(Portable Executable)是 Windows 平台可执行文件的标准格式,由 DOS 头、PE 头、区段表和若干区段(.text、.data、.rdata、.rsrc 等)组成。加壳(Packing)是对可执行文件的代码和资源进行压缩/加密,并在原程序外面包裹一段解压(壳)代码的技术,运行时壳先执行、在内存中还原原程序再跳转到原始入口点(OEP)。加壳会改变文件的静态特征,使字符串、导入表不可读,是最常见的免杀与反分析手段。UPX 是最经典的开源压缩壳,脱壳后可大致还原原始 PE 结构。
(3)静态分析与动态分析。 静态分析不运行样本,通过 file、查壳工具(Detect It Easy、PEiD)、strings 字符串提取、反汇编/反编译(IDA Pro)等手段推断程序功能;动态分析在隔离环境(虚拟机、沙箱)中实际运行样本,观察其进程、文件、注册表、网络行为。二者通常结合使用。
(4)Visual Basic 6 程序的特点。 VB6 程序依赖运行时库 MSVBVM60.DLL,编译方式分为 P-Code(伪代码)和 Native(本地代码)两种;其内部字符串以 Unicode(UTF-16LE)编码存储,用普通 strings 提取时只能看到断续字符,必须加 -e l 参数按 16 位小端字符提取,这是分析 VB 样本时容易踩的坑。
(5)Crackme 逆向基本概念。 Crackme 是专门编写用于练习逆向的小程序,核心逻辑一般是:校验参数个数(argc)→ 用 strcmp 比较口令字符串 → 相等则输出成功信息。逆向思路是先试探运行观察提示,再用 strings 或 IDA Pro 的字符串窗口定位关键字符串,最后通过交叉引用(Xref)找到校验代码,从伪代码中还原判断逻辑。
(6)IRC 协议。 IRC(Internet Relay Chat,因特网中继聊天)是一种基于 TCP 的应用层聊天协议,采用客户端/服务器模型。客户端注册连接时依次发送 PASS(口令,可选)、NICK(昵称)、USER(用户信息)三条消息完成注册,之后用 JOIN 消息加入频道。IRC 明文服务一般监听 TCP 6667 端口(也常用 6660–6669),SSL 加密服务常用 6697 端口。由于 IRC 天然支持一对多的频道控制,早期僵尸网络大量采用 IRC 作为命令与控制(C&C)信道。
(7)僵尸网络与蜜罐。 僵尸网络(Botnet)是攻击者通过传播僵尸程序控制大量主机,并通过一对多的命令控制信道所组成的网络,常被用于发动 DDoS 攻击、发送垃圾邮件、窃取信息、挖矿、点击欺诈等。蜜罐(Honeypot)是故意暴露、用于诱捕攻击的脆弱系统,配合 Snort 等入侵检测系统记录全部攻击流量,用于事后取证分析。tcpdump 用于命令行抓包/读包,Wireshark 用于图形化分析,tcpflow 可按 TCP 会话重组并分流存储,适合分析 IRC 这类明文协议。
2. 实验内容
本次实验共四个任务:
任务一:恶意代码文件类型标识、脱壳与字符串提取。 对 rada 恶意代码样本:① 使用文件格式和类型识别工具给出样本的文件格式、运行平台和加壳工具;② 使用超级巡警脱壳机等脱壳软件进行脱壳;③ 使用字符串提取工具分析脱壳后样本,找出 rada 恶意代码的编写作者。
任务二:crackme 逆向分析。 使用 IDA Pro 静态或动态分析 crackme1.exe 与 crackme2.exe,寻找特定输入使其输出成功信息。
任务三:rada 恶意代码综合分析并回答问题。 ① 给出二进制文件摘要(可用于识别同一样本的基本信息);② 找出并解释二进制文件的目的;③ 识别并说明二进制文件的不同特性;④ 识别并解释文件采用的防止被分析或逆向工程的技术;⑤ 对恶意代码样本分类(病毒、蠕虫等)并说明理由;⑥ 给出过去已有的具有相似功能的其他工具;⑦ 是否可能调查出二进制文件的开发作者?如果可以,在什么环境和限定条件下?⑧ 给出至少 5 种检测该恶意软件的方法并详细介绍。
任务四:取证分析实践。 背景为 Windows 2000 系统被攻破并加入僵尸网络,数据源是 Snort 收集的蜜罐主机 5 天网络数据(已去除无关流量并混淆敏感信息)。回答:① IRC 是什么?客户端申请加入 IRC 网络时发送什么消息?一般使用哪些 TCP 端口?② 僵尸网络是什么?通常用于什么?③ 蜜罐主机(172.16.134.191)与哪些 IRC 服务器进行了通信?④ 观察期间多少不同的主机访问了以 209.196.44.172 为服务器的僵尸网络?⑤ 哪些 IP 地址被用于攻击蜜罐主机?⑥ 攻击者尝试攻击了哪些安全漏洞?⑦ 哪些攻击成功了?是如何成功的?
实验方案简介: 任务一按"识别 → 查壳 → 脱壳 → 复查 → 提取字符串"的静态分析流程完成;任务二先试探运行观察提示,再用 strings 和 IDA Pro 定位校验逻辑;任务三综合任务一的结果并结合字符串证据完成八个问题;任务四以 tcpdump/Wireshark 按"端口 → 协议 → Payload"的证据链思路逐问分析。
实验环境: Kali Linux 虚拟机(主机名 wuyushang,运行 file、strings、wine、tcpdump、tcpflow)、Windows 10 物理机(运行 Detect It Easy v3.10、超级巡警脱壳机、IDA Pro)。
3. 实验过程
3.1 任务一:恶意代码文件类型标识、脱壳与字符串提取
3.1.1 文件类型识别(格式、平台、加壳工具)
在 Windows 主机上用 Detect It Easy(DiE)打开原始样本 RaDa.exe,识别结果如下:
- 文件格式:PE32(Windows 可移植可执行文件),文件大小 20.50 KiB;
- 运行平台:Windows(95) 系列,Intel I386,32 位,GUI 图形界面程序;
- 编译信息:链接程序 Microsoft Linker 6.0,编译器 Visual Basic 6.00.8041(Native 本地代码方式编译);
- 加壳工具:识别出打包工具为 UPX(modified 修改版),启发式结果提示"入口点与导入表特征与 UPX(v0.94–1.93)一致,且存在压缩或加壳数据"。
![DiE 查壳结果]
在 Kali 中用命令行进一步确认文件基本信息,并计算哈希值作为样本指纹:
md5sum RaDa.exe # caaa6985a43225a0b3add54f44a0d4c7
sha1sum RaDa.exe # 4164423ece62c5c4c287f8c2003b84e4e3a6cfda
sha256sum RaDa.exe # 13c2379e9d9f679396e21a3391804cc834892f25691381b6d078d07b56d38f90
ls -l RaDa.exe # 大小 20992 字节
file RaDa.exe # PE32 executable for MS Windows 4.00 (GUI), Intel i386, 3 sections
![哈希与文件信息]
先用 strings 直接观察加壳样本,只能看到大量乱码和 JDR0、JDR1 这样被修改过的区段名(正常 UPX 的区段名应为 UPX0/UPX1),以及一句遗留在 DOS Stub 里的提示 !This program is the binary of SotM 32..,有效字符串基本不可读,符合"文件被压缩/加壳"的判断:
![加壳样本 strings 结果]
结论:rada 样本是 32 位 Windows GUI 程序(PE32,Intel I386),由 Visual Basic 6.0 编写,使用修改版 UPX 加壳。
3.1.2 使用超级巡警脱壳机脱壳
由于样本使用的是修改版 UPX(区段名被改成 JDR0/JDR1),直接用 upx -d 无法脱壳,因此使用超级巡警脱壳机(万能脱壳工具)。将 RaDa.exe 拖入后,工具自动识别入口点 0000FD20、EP 区段 JDR1,识别壳版本为 UPX 0.89.6 – 1.02 / 1.05 – 1.22 -> Markus & Laszlo,通过跟踪 OEP 的方式再次脱壳成功(Unpack successfully),输出文件为同目录下的 RaDa_unpacked.exe:
![超级巡警脱壳]
脱壳后再次用 DiE 复查 RaDa_unpacked.exe:文件大小变为 67.22 KiB,链接器与编译器信息(Microsoft Linker 6.0 / Visual Basic 6.0)保持不变,原先的"UPX[modified]"识别项消失,只剩启发式提示(自定义 DOS Stub、区段名 "JDR" 冲突的残留痕迹),说明脱壳成功,得到了可供后续分析的原始程序。
![脱壳后 DiE 复查]
3.1.3 字符串提取并发现编写作者
把脱壳后的 RaDa_unpacked.exe 复制到 Kali,先用 strings 全量提取到文本文件,再搜索版权、作者等关键字:
strings RaDa_unpacked.exe > rada_strings.txt
grep -n "(c)" rada_strings.txt
# 131:(c) Raul Siles && David Perez
需要注意的是,该样本是 VB6 编写的程序,字符串以 Unicode(UTF-16LE)存储,普通 strings 搜索 "author" 一无所获(见下图第二次 grep 无输出),必须加 -e l 参数按 16 位小端字符提取:
strings -el RaDa_unpacked.exe | grep -i author
# --authors
# Authors: Raul Siles & David Perez, 2004
![字符串提取找作者]
此外,对脱壳样本按常见关键字检索时还发现一批 VB 窗体命令按钮名称(Command_install、Command_uninstall、Command_usage、Command_conf、Command_go、Command_exit 等),说明样本带有一个伪装的图形界面,可用于"安装/卸载/运行/查看配置",这是后续任务三分析其特性的重要线索:
![脱壳样本关键字检索]
结论:rada 恶意代码的编写作者是 Raul Siles 和 David Perez,编写时间为 2004 年。 结合加壳样本中遗留的 !This program is the binary of SotM 32.. 字符串可确认,该样本是 Honeynet Project 2004 年 9 月"Scan of the Month 32"逆向分析挑战赛的教学样本(RaDa 即取自两位作者姓名首字母)。
3.2 任务二:IDA Pro 分析 crackme1.exe 与 crackme2.exe
3.2.1 试探运行
先用 wine 对两个程序做黑盒试探,观察不同参数个数下的输出:
wine crackme1.exe # I think you are missing something.
wine crackme1.exe 1 # Pardon? What did you say?
wine crackme1.exe 1 2 # I think you are missing something.
![crackme1 试探]
wine crackme2.exe # I think you are missing something.
wine crackme2.exe 1 # I have an identity problem.
wine crackme2.exe 1 2 # I think you are missing something.
![crackme2 试探]
试探可以得出两条规律:① 两个程序都要求恰好 1 个参数(argc==2),否则提示 "missing something";② crackme1 参数不对时提示 "Pardon?",而 crackme2 多了一个 "identity problem" 提示,说明它还校验程序自身的某种"身份"。
3.2.2 crackme1.exe:口令比较
对 crackme1.exe 提取字符串并按关键提示词过滤,直接命中疑似口令 I know the secret 和成功信息 You know how to speak to programs, Mr. Reverse-Engineer:
strings crackme1.exe | grep -i "secret\|pardon\|missing\|reverse\|success"
![crackme1 strings]
用 IDA Pro 打开 crackme1.exe,在字符串窗口(Shift+F12)中可以看到四条关键字符串依次排列在 .rdata 节:
![IDA 字符串窗口]
双击字符串通过交叉引用(Xref)定位到 main 函数,按 F5 生成伪代码,逻辑一目了然:
int __cdecl main(int argc, const char **argv, const char **envp)
{
...
if ( argc == 2 )
{
if ( !strcmp(argv[1], "I know the secret") )
{
printf("You know how to speak to programs, Mr. Reverse-Engineer\n");
return 0;
}
else
{
fprintf(&__iob[2], "Pardon? What did you say?\n");
return 2;
}
}
else
{
fprintf(&__iob[2], "I think you are missing something.\n");
return 1;
}
}
![crackme1 伪代码]
即程序校验逻辑为:参数个数为 1,且参数等于 I know the secret。验证:
wine crackme1.exe "I know the secret"
# You know how to speak to programs, Mr. Reverse-Engineer
输出成功信息,crackme1 完成。
3.2.3 crackme2.exe:口令 + 程序名双重校验
crackme2 的 strings 结果中除了同样存在 I know the secret,还多了一个可疑字符串 crackmeplease.exe,末尾还有源文件名 crackme2.c:
![crackme2 strings]
用 IDA Pro 查看 crackme2 的字符串窗口,可以看到 crackmeplease.exe、I have an identity problem. 以及两段乱码字符串('b*#4'b#b.+66.'b1'!0'6xb 等,疑似加密后的成功信息):
![crackme2 IDA 字符串]
查看 main 函数伪代码,校验逻辑为三层嵌套:
if ( argc == 2 )
{
if ( !strcmp(*argv, "crackmeplease.exe") ) // 校验 argv[0],即程序自身文件名
{
if ( !strcmp(argv[1], "I know the secret") ) // 校验口令
{
for ( i = 0; i <= 0x21; ++i )
putchar((char)(byte_403080[i] ^ 0x42)); // 异或 0x42 解密输出成功信息
puts(Buffer);
return 0;
}
...
}
else
{
fprintf(&__iob[2], "I have an identity problem.\n"); // 文件名不对
return 2;
}
}
![crackme2 伪代码]
也就是说,crackme2 在 crackme1 的基础上增加了对 argv[0](程序自身文件名)必须为 crackmeplease.exe 的校验,校验通过后把 .rdata 中 0x22 字节的数据逐字节与 0x42 异或解密,还原出的正是成功信息 "You know how to speak to programs, Mr. Reverse-Engineer"。
先把文件复制改名再运行:
cp crackme2.exe crackmeplease.exe
wine crackmeplease.exe "I know the secret"
# I have an identity problem.
仍然提示 identity problem(见下图)。分析原因:wine 会把完整的虚拟路径(形如 Z:\home\kali\Desktop\crackmeplease.exe)传给 argv[0],而程序用的是 strcmp(*argv, "crackmeplease.exe") 全等比较(没有做路径剥离),因此比较必然失败。改到 Windows 虚拟机的 cmd 中运行(cmd 下 argv[0] 只有文件名本身):
C:\> crackmeplease.exe "I know the secret"
You know how to speak to programs, Mr. Reverse-Engineer
输出成功信息,crackme2 完成。
![crackme1 成功与 crackme2 的 identity problem]
3.3 任务三:RaDa 恶意代码综合分析
(1)二进制文件摘要(可用于识别同一样本的基本信息)
| 项目 | 内容 |
|---|---|
| 文件名 | RaDa.exe(脱壳后为 RaDa_unpacked.exe) |
| 文件大小 | 20992 字节(20.50 KiB),脱壳后约 67.22 KiB |
| 文件类型 | PE32 executable for MS Windows (GUI),Intel i386,3 个区段 |
| 编译环境 | Microsoft Linker 6.0,Visual Basic 6.00.8041(Native) |
| 加壳方式 | UPX(modified),区段名被改为 JDR0/JDR1,壳版本特征 UPX 0.89.6–1.02 / 1.05–1.22 |
| MD5 | caaa6985a43225a0b3add54f44a0d4c7 |
| SHA-1 | 4164423ece62c5c4c287f8c2003b84e4e3a6cfda |
| SHA-256 | 13c2379e9d9f679396e21a3391804cc834892f25691381b6d078d07b56d38f90 |
| 样本来源 | Honeynet Project Scan of the Month 32(2004 年 9 月),字符串 "!This program is the binary of SotM 32.." |
| 作者信息 | "(c) Raul Siles && David Perez"、"Authors: Raul Siles & David Perez, 2004" |
其中三个哈希值是识别同一样本最可靠的指纹;PE 结构特征(VB6、JDR 区段名)和遗留字符串可作为辅助识别特征。
(2)二进制文件的目的
RaDa 是一个受远程控制的僵尸程序(Bot)/后门木马。综合脱壳后提取到的字符串可以还原其工作方式:程序在受害主机上安装自身后,通过 HTTP 周期性地向命令控制服务器(字符串中出现的 10.10.10.10/RaDa/RaDa_commands.html)下载命令页面,解析页面中的指令并执行,主要能力包括发起 DDoS 攻击(Smurf 攻击、HTTP GET 洪水)、上传/下载文件(通过 cgi-bin 下的 upload.cgi、download.cgi)、截取屏幕、按指令休眠等。也就是说,它的根本目的是把受害主机变成攻击者"僵尸网络"中的一个节点,接受一对多的远程指挥,为后续大规模攻击(尤其是 DDoS)提供兵力。
(3)二进制文件具有的不同特性
- 图形界面伪装:字符串中出现 Command_install、Command_uninstall、Command_usage、Command_conf、Command_go、Command_exit 等 VB 窗体按钮,样本伪装成一个带"安装/卸载/运行/配置"按钮的 GUI 工具,降低受害者戒心,同时方便作者演示。
- 安装与持久化:install 动作会把自身复制到系统目录下的工作目录(
C:\RaDa\bin等),并写入注册表自启动项(HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run),实现开机自启。 - HTTP 命令控制:通过 HTTP GET 请求
RaDa_commands.html拉取指令,命令以 HTML 注释形式隐藏,流量上看像普通网页访问,具有一定隐蔽性;支持 get(下载并执行新文件)、put(上传文件)、screens(截图)、sleep(休眠)、smurf(发动 Smurf 攻击)等指令。 - DDoS 能力:可以向指定目标发起 ICMP Smurf 放大攻击和 HTTP GET 洪水攻击,是典型的"攻击武器化"功能。
- 自我更新:能从服务器下载新版本来替换自身,便于作者升级功能或更换 C2 地址。
(4)防止被分析或逆向工程的技术
- 修改版 UPX 加壳:样本用 UPX 压缩,但把标志性的 UPX0/UPX1 区段名改成了 JDR0/JDR1,导致标准
upx -d无法识别、部分查壳工具误判,必须借助超级巡警脱壳机这类支持"跟踪 OEP"的工具才能脱掉(见任务一)。 - 区段名冲突干扰:脱壳后的文件仍残留 "Sections collision (JDR)" 的启发式告警,这种区段表异常会干扰部分 PE 解析工具。
- VB6 Native 编译:VB 程序逻辑由 MSVBVM60 虚拟机运行时支撑,反汇编出的代码充斥运行时库调用,可读性差,且字符串为 Unicode 编码,普通 strings 提取会漏掉关键信息(任务一中 grep "author" 无结果就是踩了这个坑),抬高了分析门槛。
- 检测虚拟机与分析环境:字符串证据表明样本会检测 VMware 等虚拟化环境的痕迹(如 VMware 相关注册表项、MAC 地址前缀等),一旦发现运行在分析环境中就改变行为,增加动态分析难度。
- 作者信息的烟雾弹:文件中公开署名 "(c) Raul Siles && David Perez",但恶意代码内置的署名真假难辨,这也是一种对抗溯源的手段(见第(7)问)。
(5)恶意代码分类及理由
分类:木马(具体说是具有 DDoS 能力的后门/僵尸程序 Bot)。 理由如下:
- 它不感染其他文件,不具备病毒的传染特征,所以不是病毒;
- 它不能自主复制、不主动通过网络传播,需要攻击者植入或诱骗用户运行,不符合蠕虫的定义;
- 它在受害主机上开辟隐蔽的远程控制通道(HTTP 拉取指令),接受控制端一对多指挥,并把自身注册为开机自启长期潜伏,这正是后门木马/僵尸程序的核心特征;
- 其内置的 Smurf/HTTP 洪水攻击能力说明它是为了组成 DDoS 僵尸网络而设计的攻击节点。
(6)过去已有的具有相似功能的其他工具
- Sub7(SubSeven):经典 Windows 远程控制木马,具备文件管理、屏幕查看、键盘记录等完整后门能力;
- Back Orifice 2000(BO2K):与 Sub7 齐名的远程访问木马,支持插件扩展;
- NetBus:早期著名远程控制木马,Client/Server 架构;
- SDBot / Agobot(Gaobot):通过 IRC 频道接受一对多指令的僵尸程序,与 RaDa 的 Bot 定位最接近;
- Trinoo、TFN、Stacheldraht:更早的专用 DDoS 僵尸网络工具,实现了"控制端—主控节点—攻击节点"的多层结构,是 RaDa 这类 DDoS Bot 的前身。
(7)能否调查出二进制文件的开发作者?
可以,但只在特定环境和限定条件下成立。 从脱壳后样本的字符串中能直接读到 "(c) Raul Siles && David Perez" 和 "Authors: Raul Siles & David Perez, 2004",结合 "SotM 32" 字样可以确认:该样本是 Honeynet Project 2004 年 9 月 SotM 32 挑战赛的教学样本,两位作者(来自 HP Spain)是公开署名的,在这种"样本本身为教学挑战而编写、作者自愿公开身份"的受控实验环境下,可以确定作者。
但在真实攻击场景中,不能仅凭二进制中的署名认定作者,必须附加严格限定条件:① 恶意代码中的字符串极易伪造,署名可能是栽赃(把别人的名字写进代码嫁祸)或匿名占位,本身不具备司法证据效力;② 真正的溯源需要结合二进制之外的证据链,如 C2 服务器的日志与归属、域名注册信息、样本上传来源、编译时间戳与 PDB 路径、代码风格指纹等;③ 这些证据通常掌握在运营商、域名注册商和受害单位手中,必须在执法机关授权的调查环境下、依照法定程序调取。因此结论是:实验环境下可以"调查出"作者,真实环境下只有在证据链完整且依法取证的限定条件下才有意义。
(8)检测该恶意软件的方法(不少于 5 种)
① 基于哈希/特征码的检测。 预先计算样本的 MD5/SHA-1/SHA-256(见第(1)问表格),将哈希加入杀软或 EDR 的黑名单库,对全网主机做文件扫描比对;同一样本只要内容不变就能被 100% 命中。优点是快、误报低;缺点是对任何修改(哪怕改一个字节)都失效,也无法识别脱壳后的变体。
② 基于 YARA 规则的静态特征检测。 提取样本中稳定且有区分度的字符串特征编写 YARA 规则,例如 "RaDa_commands.html"、"!This program is the binary of SotM 32.."、"Authors: Raul Siles & David Perez, 2004"、区段名 "JDR0"/"JDR1"、命令字符串 "smurf"/"screens" 等,对磁盘文件和内存镜像批量扫描。YARA 规则可以容忍样本的部分变异,比单一哈希更具泛化能力。
③ 基于 Snort 规则的网络流量检测。 RaDa 的 C2 通信是特征明显的明文 HTTP:周期性 GET /RaDa/RaDa_commands.html,以及向 /RaDa/cgi-bin/download.cgi、/RaDa/cgi-bin/upload.cgi 的文件传输。据此编写 Snort/Suricata 规则,匹配 HTTP URI 中的 /RaDa/ 路径和 cgi 脚本名,即可在网络边界实时发现受控主机;规则尽量写成匹配 URI 关键字而非固定 IP,以兼顾检出率和低误报。
④ 基于主机行为(IOC)的检测。 监控主机的可疑持久化与落地行为:注册表 HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run 下新增指向 RaDa 的启动项;系统目录下创建 C:\RaDa\bin、C:\RaDa\tmp 等目录;进程列表中出现非业务程序建立的周期性 HTTP 外连。这类行为级 IOC 即使样本改了哈希也依然有效。
⑤ 基于启发式/查壳的静态检测。 利用加壳特征做前置筛查:PE 区段名异常(非标准的 JDR0/JDR1)、区段高熵(压缩/加密数据)、导入表极少(只看到 LoadLibraryA/GetProcAddress)等都是典型加壳信号。杀软的"Heur/Generic"引擎正是据此把样本标记为可疑(本实验中 DiE 也给出了同样的启发式结论),对未知变种有较好的预警作用。
⑥ 基于沙箱的动态行为检测。 把样本投入沙箱(如 Cuckoo)运行,观察其运行时行为:是否连接外部 C2(10.10.10.10/RaDa)、是否周期拉取命令页面、是否发出大量 ICMP 包(Smurf 攻击特征)、是否修改注册表自启动项。动态检测不依赖样本静态特征,能识别加壳和变形样本,还能直接产出网络与主机 IOC 反哺前几种方法。
⑦ 基于异常流量的检测(补充)。 从网络侧统计视角发现感染:单台主机周期性访问固定陌生 HTTP 资源、突然向外发送海量 ICMP/HTTP 请求(DDoS 发作)、内网大量指向同一地址的异常会话等,均可作为感染告警线索,适合在出口 NetFlow/全流量平台上部署。
3.4 任务四:取证分析实践——Windows 2000 主机被攻破并加入僵尸网络
数据源为 Snort 收集的蜜罐主机(172.16.134.191)5 天网络流量 botnet_pcap_file.dat(约 18 MB)。先用 tcpdump 概览流量,可见蜜罐与外部主机之间存在 UDP、TCP 等多种交互:
ls -lh botnet_pcap_file.dat
tcpdump -n -nn -r botnet_pcap_file.dat | head -20
![tcpdump 概览]
(1)IRC 是什么?加入 IRC 网络时发送什么消息?使用哪些 TCP 端口?
IRC(Internet Relay Chat,因特网中继聊天)是一种基于 TCP 的应用层即时通信协议,采用客户端/服务器架构,用户的消息通过服务器中继转发给同一频道内的其他用户。客户端申请加入 IRC 网络时,需要依次发送注册消息:PASS(口令,可选)、NICK(设置昵称)、USER(发送用户名和用户信息),完成注册后再发送 JOIN <频道名> 加入具体频道。IRC 明文服务通常监听 TCP 6667 端口(也常使用 6660–6669 之间的端口),SSL 加密传输则常用 6697 端口。
(2)僵尸网络是什么?通常用于什么?
僵尸网络(Botnet)是指攻击者出于恶意目的,通过一种或多种传播手段感染大量主机植入僵尸程序(Bot),并通过一对多的命令与控制(C&C)信道集中控制这些主机所组成的网络,被感染的主机称为"肉鸡"或"僵尸主机"。僵尸网络通常用于:发起分布式拒绝服务攻击(DDoS)、批量发送垃圾邮件、窃取被控主机上的账号口令等敏感信息、占用资源挖矿、实施点击欺诈以及作为跳板进行二次攻击等。攻击者可以极低代价调度成千上万台主机,危害极大。
(3)蜜罐主机与哪些 IRC 服务器进行了通信?
IRC 使用 TCP 连接,因此筛选蜜罐主机发往 6667 端口的流量即可找到它连接过的 IRC 服务器:
tcpdump -n -nn -r botnet_pcap_file.dat 'tcp port 6667' | head -30
![IRC 服务器连接]
再对目的地址做去重统计,结果如下:
tcpdump -n -nn -r botnet_pcap_file.dat 'tcp port 6667' | awk '{print $5}' | cut -d. -f1-4 | sort | uniq -c | sort -nr
![IRC 通信统计]
统计结果中 209.196.44.172 的通信量高达 8902 个数据包,是主 C2 服务器;另外还有 4 台服务器有少量连接尝试。因此蜜罐主机共与 5 台 IRC 服务器进行了通信:
- 209.196.44.172(主要通信服务器)
- 209.126.161.29
- 66.33.65.58
- 63.241.174.144
- 217.199.175.10
(4)观察期间多少不同的主机访问了以 209.196.44.172 为服务器的僵尸网络?
僵尸网络中每台肉鸡加入 IRC 频道时都会取一个昵称(Nickname),而服务器会周期性向频道成员推送 353 消息(频道成员名单)。因此统计服务器发给蜜罐的 353 消息中出现过的不同昵称数,即可估计访问过该僵尸网络的不同主机数。
先用 tcpflow 把蜜罐与该服务器的 TCP 流重组分流(tcpflow 会生成双向流文件和 report.xml):
sudo apt install -y tcpflow
tcpflow -r botnet_pcap_file.dat 'host 209.196.44.172 and port 6667'
![tcpflow 分流]
分流后重点分析服务器→蜜罐方向的流文件 209.196.044.172.06667-172.016.134.191.01152,其中能看到来自 irc5.aol.com 的大量 353 名单消息:
![IRC 353 名单]
用管道命令提取昵称、去重并计数:
cat 209.196.044.172.06667-172.016.134.191.01152 | grep -a "^:irc5.aol.com 353" \
| sed "s/^:irc5.aol.com 353 rgdiuggac @ #x[^x]*x ://g" \
| tr ' ' '\n' | tr -d "\15" | grep -v "^$" | sort -u | wc -l
(grep 加 -a 是因为流文件含二进制数据;sed 去掉名单前缀,注意频道名中的字母 x 属于混淆后的真实字符;tr 把空格换成行、删除回车符;sort -u 去重。)统计结果为 3461,即观察期间约有 3461 台不同的主机访问了以 209.196.44.172 为服务器的僵尸网络。
(5)哪些 IP 地址被用于攻击蜜罐主机?
统计所有向蜜罐主机发送数据包的外部源 IP:
tcpdump -n -nn -r botnet_pcap_file.dat 'dst host 172.16.134.191' \
| awk '{print $3}' | cut -d. -f1-4 | sort | uniq -c | sort -nr | head -20
去重计数共得到 165 个不同的源 IP 与蜜罐发生过通信:
tcpdump -n -nn -r botnet_pcap_file.dat 'dst host 172.16.134.191' \
| awk '{print $3}' | cut -d. -f1-4 | sort -u | wc -l
# 165
![攻击源 IP 统计]
这 165 个地址中包含正常应答(如 IRC 服务器 209.196.44.172 的回包),结合后文端口分析,具有明确攻击行为的源 IP 主要包括:
| 源 IP | 目标端口 | 攻击行为 |
|---|---|---|
| 61.111.101.78 | TCP 445 | SMB 攻击(植入 PSEXESVC 服务,成功) |
| 210.22.204.101 | TCP 445 / 4899 | SMB 溢出尝试 + Radmin 远程控制(成功) |
| 24.197.194.106 | TCP 80 / 4899 | 对 IIS 的脚本化溢出攻击(80 端口未成功) |
| 209.45.125.69 | TCP 445 | SMB 攻击尝试 |
| 66.139.10.15 | TCP 445 | SMB 攻击尝试 |
| 129.116.182.239 | TCP 445 | SMB 攻击尝试 |
| 195.36.247.77 | TCP 445 | SMB 攻击尝试 |
| 80.181.116.202 | TCP 445 | SMB 攻击尝试 |
| 66.8.163.125 | TCP 445 | SMB 攻击尝试 |
(6)攻击者尝试攻击了哪些安全漏洞?
先统计蜜罐主机(作为响应方)对外应答的端口分布,即攻击者实际触达的服务:
tcpdump -n -nn -r botnet_pcap_file.dat 'src host 172.16.134.191' \
| awk '{print $3}' | awk -F. '{print $NF}' | sort | uniq -c | sort -nr
![蜜罐响应端口统计]
可见蜜罐响应过的主要服务端口包括 TCP 的 135、139、445、25、80、4899 以及 UDP 的 137 等。逐个端口分析流量内容后,判断攻击者尝试的攻击如下:
- TCP 135(RPC/DCOM):探测与连接尝试,针对 Windows RPC DCOM 接口缓冲区溢出漏洞(MS03-026,即"冲击波"利用的漏洞),但多数连接没有后续数据交互;
- TCP 139 / UDP 137(NetBIOS):NetBIOS 查点(获取主机名、用户、共享列表)和对共享的空会话猜解、弱口令尝试;
- TCP 445(SMB over TCP):Windows 2000 的 SMB 服务攻击,包括 DsRoleUpgradeDownlevelServer 等远程缓冲区溢出尝试(对应 MS04-011 一类漏洞),以及通过 ADMIN$/IPC$ 共享植入服务(PSEXESVC)的控制行为;
- TCP 80(IIS 5.0):24.197.194.106 发起大量构造的 HTTP 请求,属于针对 IIS 的脚本化溢出/漏洞扫描攻击(如 Unicode 解码、IDA/IDQ 扩展溢出类攻击);
- TCP 25(SMTP):对邮件服务的探测与扫描(只有握手和空包,无实质数据);
- TCP 4899(Radmin):远程控制软件 Radmin 的登录尝试,属于攻击者植入远控后回头"收割"的行为;
- UDP 137:NetBIOS 名称服务查点,属于攻击前的信息搜集。
对 445 和 4899 两个重点端口的源 IP 统计如下:
tcpdump -n -nn -r botnet_pcap_file.dat 'tcp port 445 and host 172.16.134.191' | awk '{print $3}' | cut -d. -f1-4 | sort | uniq -c | sort -nr | head
tcpdump -n -nn -r botnet_pcap_file.dat 'tcp port 4899 and host 172.16.134.191' | awk '{print $3}' | cut -d. -f1-4 | sort | uniq -c | sort -nr | head
![445 与 4899 端口分析]
(7)哪些攻击成功了?是如何成功的?
成功的攻击是 61.111.101.78 对 445 端口 SMB 服务的攻击,以及后续 210.22.204.101 通过 4899 端口 Radmin 的远程控制。 证据链如下:
- 445 端口出现服务植入证据。 对 445 端口的流量做 ASCII 提取,搜索典型的远程控制/服务安装痕迹:
tcpdump -n -nn -r botnet_pcap_file.dat -A 'tcp port 445' 2>/dev/null \
| grep -a -o -i -m10 "PSEXESVC\|ADMIN\$\|IPC\$\|svcctl\|r_server\|radmin" | sort | uniq -c
结果命中 PSEXESVC(11 次)、RAdmin(1 次)、r_server(2 次):
![PSEXESVC 证据]
PSEXESVC 是 PsExec 工具在目标主机上安装的远程服务名,它只有在攻击者已通过 SMB(445 端口)获得管理员权限、并成功写入 ADMIN$ 共享、通过 svcctl 远程创建服务后才会出现。这说明 61.111.101.78 对蜜罐 445 端口的 SMB 攻击成功(利用 Windows 2000 SMB 相关漏洞获得系统权限),并借此在蜜罐上安装/启动了远程服务,随后植入了 Radmin 服务端(流量中的 RAdmin、r_server 字样即 Radmin 远控的安装痕迹)。
-
4899 端口的 Radmin 会话成功建立。 210.22.204.101 与蜜罐的 4899 端口之间有 490 个数据包的双向持续交互,这不是扫描或握手失败能产生的流量,而是一次完整登录并操作的 Radmin 远程控制会话——攻击者利用上一阶段植入的 Radmin 后门成功接管了蜜罐。蜜罐随后(从 1152 源端口)主动连接 IRC 服务器 209.196.44.172 的 6667 端口并加入频道,标志着它已被植入僵尸程序、正式成为僵尸网络的一员。
-
其余攻击未成功。 TCP 135 只有三次握手、无后续数据且客户端很快断开;TCP 139 尝试访问共享时被 RST 拒绝;TCP 25 只有 FIN/ACK 空包和重传;TCP 80 虽然被 24.197.194.106 反复攻击,但蜜罐均以 IIS 默认页面正常回应,说明 IIS 并未被攻陷。这些端口要么服务不存在/已打补丁,要么攻击载荷与目标环境不匹配,均未得手。
4. 问题及解决方案
-
问题1: UPX 壳被魔改导致标准脱壳失败。
-
问题1解决方案: 由于样本的 UPX 壳区段名被从 UPX0/UPX1 篡改为 JDR0/JDR1,破坏了 UPX 的自动识别和脱壳流程。我使用了两种方法,一是手工修复法(Kali):使用 sed -i 's/JDR/UPX/g' RaDa_fix.exe 将区段名改回标准 UPX,再执行 upx -d 成功脱壳;二是专用工具法(Windows):使用超级巡警万能脱壳工具,直接识别 JDR 区段并成功脱壳,无需手工修复。
-
问题2: 跨平台运行 Windows 程序时的环境障碍,在 Kali 中直接运行 ./crackme1.exe 提示 Permission denied;使用 wine 运行时报错 wine32 missing 或 kernel32.dll c0000135。
-
问题2解决方案: Linux 无法直接执行 PE 格式;Wine 缺少 32 位支持库或配置损坏。我安装 32 位支持:sudo dpkg --add-architecture i386 && sudo apt install wine32:i386,并修复 Wine 配置:rm -rf ~/.wine && winecfg(清除损坏的虚拟盘并重建),后续均通过 wine crackme1.exe 正常运行动态验证。
-
问题3: crackme2 的 argv[0] 身份验证导致运行失败,在 Wine 中运行 wine crackme2.exe "I know the secret" 输出 I have an identity problem,即使口令正确也无法成功。
-
问题3解决方案: 程序不仅校验 argv[1] 的口令,还通过 strcmp(argv[0], "crackmeplease.exe") 校验程序自身文件名;Wine 传递的 argv[0] 与预期不符。通过 IDA Pro 伪代码发现 argv[0] 检查逻辑,理解必须将程序重命名为 crackmeplease.exe。在真实 Windows 系统中重命名后运行成功;在 Wine 中通过创建符号链接或拷贝重命名解决。
-
问题4: 网络取证中的数据处理与工具选择,初始使用 tcpdump 提取攻击 IP 时字段提取错误(awk '{print $4}' 得到 > 符号);后期考虑是否需要 Wireshark 实时抓包,以及 sudo wireshark 因 tty 输入挂起无法启动。
-
问题4解决方案: cpdump 输出格式中源地址在 $3 字段;离线分析不需要抓包;sudo 在后台运行(&)时无法接收密码输入。修正命令为 awk '{print $3}' 正确提取源 IP,成功统计出 165 个攻击源。确认实验为离线取证分析,使用 wireshark botnet_pcap_file.dat 直接打开文件而非实时抓包。
5. 学习感悟、思考等
这次实验把静态分析、逆向工程和流量取证串成了一条完整的线,收获比预期大得多。
印象最深的是"流程"的力量。面对 RaDa 这种加壳样本,如果一上来就拖进 IDA,看到的只有壳代码和乱码字符串;但按"file 识别 → 查壳 → 脱壳 → 复查 → strings → 交叉验证"的顺序走,每一步都为下一步扫清障碍,最后作者信息几乎是自然而然地浮出来的。尤其是 VB 字符串的 Unicode 问题,让我体会到分析工具没有银弹,只有理解样本的编译背景(VB6、Native、MSVBVM60)才能选对参数,否则明明答案就在眼前也会 grep 个空。
crackme 部分则给了我一个反面提醒:逆向结论不能只停留在静态层面。crackme2 的校验逻辑在伪代码里清清楚楚,但 wine 环境下 argv[0] 带全路径这个差异让我卡了半天——静态分析告诉我"应该能过",动态运行却告诉我"就是不过",两者的矛盾恰恰是理解程序最深刻的入口。今后做样本分析,静态结论一定要用受控环境下的动态行为去印证。
取证分析部分改变了我对"看包"的认识。以前觉得 tcpdump/Wireshark 就是看个 IP 和端口,这次才发现真正的取证是建证据链:353 名单估计僵尸网络规模、PSEXESVC 字样证明 445 攻击得手、Radmin 会话的双向大包证明远程控制成立——每一个结论都要落到具体的包内容上,而不是"我觉得像"。蜜罐那台 Windows 2000 主机 5 天内被反复扫描、溢出、植入、入网的完整过程,也让我对"僵尸网络如何滚雪球"有了非常直观的认识:一次成功的 SMB 溢出,就是整条攻击链的入口。
最后是一点反思:实验并不一帆风顺,脱壳工具的选择、strings 编码、wine 的路径差异、uniq 的坑,每个问题都卡住过一段时间,但正是这些坑逼着我去翻文档、看伪代码、想原理,比顺利跑完学到的东西更扎实。攻防对抗本质上是细节的对抗,谁更理解底层,谁就能占先。

浙公网安备 33010602011771号