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、.idq ISAPI 过滤器存在缓冲区溢出。蠕虫发超长的 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 的编写作者。具体要求:

  1. 使用文件格式和类型识别工具,给出 RaDa 样本的文件格式、运行平台和加壳工具;
  2. 使用超级巡警脱壳机等脱壳软件,对 RaDa 样本进行脱壳处理;
  3. 使用字符串提取工具,对脱壳后的样本进行分析,从中发现 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)具有的特性

  1. 自我复制。把自身写到 C:\RaDa\bin\RaDa.exe,不依赖原始投放位置,用户删掉下载目录里的样本也不影响它运行。
  2. 注册表持久化。写入 Run 键,开机自动加载。
  3. HTTP 协议通信。用 80 端口做 C&C,能穿绝大多数企业防火墙,代理环境下也能工作。
  4. 指令文件驱动。控制端不需要和 bot 保持长连接,只要改服务器上的 RaDa_commands.html,bot 下次轮询就取到新指令。
  5. 双向文件传输。download.cgi 往下投文件,upload.cgi 往上偷文件,具备窃密和二次投放能力。
  6. 体积小、有壳。20 KB 出头,UPX 压缩,便于通过邮件附件、网页下载等方式传播,也增加静态分析成本。
  7. 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 与端口

  1. IRC 全称 Internet Relay Chat,是 1988 年就有的、基于文本的实时聊天协议。客户端连到服务器,再进不同的频道和多人聊天。它协议简单、有现成的服务器软件、还能把一条消息广播给整个频道,所以早期僵尸网络普遍拿它当命令控制通道:控制者在频道里发一句指令,所有 bot 同时收到。
  2. 客户端连上服务器要先注册,发 NICK 给自己起昵称、发 USER 填用户名和主机名,服务器设了连接口令的话前面还得加一条 PASS。服务器确认昵称没被占用,回 001~004 欢迎码,这个客户端才算进了网络。要注意「加入网络」和「加入频道」是两步:注册完再发 JOIN #频道名 才进具体频道,聊天用 PRIVMSG。
  3. 明文 IRC 传统上占 6660~6669 这一段,其中 6667 最常用,基本等于默认端口;走 TLS 加密的用 6697,也有服务器用 7000。

(2)僵尸网络

  1. 僵尸网络(botnet)指攻击者攻陷一批主机、植入受控程序之后,通过命令与控制服务器(C&C)集中操纵形成的网络。被控的主机叫 bot 或肉鸡,操纵者叫 botmaster。它和普通蠕虫的区别在于数量大、能同时动作、指令还能随时换。
  2. 常见用途有 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.学习感悟、思考等

  1. 这次实验做完,最大的感受是眼见不一定为实。一开始看 RaDa.exe,file 说它是 PE32、3 个节区用 DIE 一查,UPX[modified],壳还在。这时候如果直接拖进 IDA,看到的全是解压程序的代码。脱壳之后再打开,五组关键字符串几秒钟就定位到了。也让我理解了为什么恶意代码作者都爱加壳。

  2. 第二个感受是命令行的每个字符都有意义。这次实验中有几次是在输命令时出了问题:引号位置错一位,tcpdump 直接罢工;awk 用双引号,165 变成 29126;grep 少个 -a,输出被当成二进制吞掉;sed 里一个全角冒号,统计结果直接是 0。这些错误在报错信息里往往看不出来,它不报错,只是给你一个错的数字。所以做完统计最好要找第二种方法交叉验证。

参考资料

posted @ 2026-11-07 16:17  chow-  阅读(17)  评论(0)    收藏  举报