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 查壳结果]alt text

在 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

![哈希与文件信息]alt text

先用 strings 直接观察加壳样本,只能看到大量乱码和 JDR0、JDR1 这样被修改过的区段名(正常 UPX 的区段名应为 UPX0/UPX1),以及一句遗留在 DOS Stub 里的提示 !This program is the binary of SotM 32..,有效字符串基本不可读,符合"文件被压缩/加壳"的判断:

![加壳样本 strings 结果]alt text

结论: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:

![超级巡警脱壳]alt text

脱壳后再次用 DiE 复查 RaDa_unpacked.exe:文件大小变为 67.22 KiB,链接器与编译器信息(Microsoft Linker 6.0 / Visual Basic 6.0)保持不变,原先的"UPX[modified]"识别项消失,只剩启发式提示(自定义 DOS Stub、区段名 "JDR" 冲突的残留痕迹),说明脱壳成功,得到了可供后续分析的原始程序。

![脱壳后 DiE 复查]alt text

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

![字符串提取找作者]alt text

此外,对脱壳样本按常见关键字检索时还发现一批 VB 窗体命令按钮名称(Command_install、Command_uninstall、Command_usage、Command_conf、Command_go、Command_exit 等),说明样本带有一个伪装的图形界面,可用于"安装/卸载/运行/查看配置",这是后续任务三分析其特性的重要线索:

![脱壳样本关键字检索]alt text

结论: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 试探]alt text

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 试探]alt text

试探可以得出两条规律:① 两个程序都要求恰好 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]alt text

用 IDA Pro 打开 crackme1.exe,在字符串窗口(Shift+F12)中可以看到四条关键字符串依次排列在 .rdata 节:

![IDA 字符串窗口]alt text

双击字符串通过交叉引用(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 伪代码]alt text

即程序校验逻辑为:参数个数为 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]alt text

用 IDA Pro 查看 crackme2 的字符串窗口,可以看到 crackmeplease.exe、I have an identity problem. 以及两段乱码字符串('b*#4'b#b.+66.'b1'!0'6xb 等,疑似加密后的成功信息):

![crackme2 IDA 字符串]alt text

查看 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 伪代码]alt text

也就是说,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]alt text

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 概览]alt text

(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 服务器连接]alt text

再对目的地址做去重统计,结果如下:

tcpdump -n -nn -r botnet_pcap_file.dat 'tcp port 6667' | awk '{print $5}' | cut -d. -f1-4 | sort | uniq -c | sort -nr

![IRC 通信统计]alt text

统计结果中 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 分流]alt text

分流后重点分析服务器→蜜罐方向的流文件 209.196.044.172.06667-172.016.134.191.01152,其中能看到来自 irc5.aol.com 的大量 353 名单消息:

![IRC 353 名单]alt text

用管道命令提取昵称、去重并计数:

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 统计]alt text

这 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

![蜜罐响应端口统计]alt text

可见蜜罐响应过的主要服务端口包括 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 端口分析]alt text

(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 证据]alt text

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 的坑,每个问题都卡住过一段时间,但正是这些坑逼着我去翻文档、看伪代码、想原理,比顺利跑完学到的东西更扎实。攻防对抗本质上是细节的对抗,谁更理解底层,谁就能占先。

参考资料

posted @ 2026-11-09 21:33  水笔大旧  阅读(2)  评论(0)    收藏  举报