20242329 2026-2027-1 《网络与系统攻防技术》实验四实验报告
20242329 2026-2027-1 《网络与系统攻防技术》实验四实验报告
恶意代码分析实践
1. 基础知识
这一节是我做完实验之后回头整理的,不是抄定义。凡是后面用得上的概念,都在这里先交代清楚,免得正文里反复解释。
1.1 PE 文件:所有分析的起点
Windows 上的可执行文件基本都长成 PE 的样子。结构上分四层:
- DOS 头(开头两个字节是
MZ,即0x5A4D) - NT 头:又分
FileHeader和OptionalHeader - 节表:告诉系统每个节在文件里从哪开始、在内存里多大、有什么属性
- 导入表 / 导出表:这个程序调用了哪些外部函数
分析恶意代码时最常看的是 OptionalHeader 里的三个字段:
| 字段 | 含义 | 为什么看它 |
|---|---|---|
Machine |
目标 CPU 架构 | 0x014C = Intel 386,即 32 位 |
Subsystem |
子系统类型 | 2 = Windows GUI,3 = 控制台 |
AddressOfEntryPoint |
入口点 RVA | 加壳程序的入口点通常不落在 .text 节里 |
还有一个常被忽略的:FileHeader.TimeDateStamp,编译时间戳。它可以是伪造的,但如果是真的,往往能和时间线对上。
1.2 加壳与脱壳:一个空房间和一把锁
壳的本质很简单:把原来的代码压缩或加密,再配一段自己写的解压程序(stub)。
程序跑起来的时候,先执行 stub,stub 把原始代码解压回内存里的某个区域,然后跳回去执行——这个跳回去的地址就是 OEP(原始入口点)。所以从文件的角度看,你在磁盘上看到的是一个 20 KB 的壳,它在内存里展开成一个 67 KB 的程序。
查壳有两条路:
- 签名匹配:拿已知壳的 stub 字节特征去比对。PEiD、DIE 都这么干。
- 启发式:看节区名、节区熵值、节区是否重叠、导入表是否稀薄。这条路会误报,因为"可疑"不等于"有壳"。
脱壳也分两条路:静态(工具自动找 OEP 再 dump + 修复 IAT)和动态(跑起来到 OEP 处 dump 内存)。超级巡警属于前者的自动化实现。
一个细节值得记:标准 UPX 生成的节区名一定是 UPX0、UPX1。如果看到的是别的名字,说明有人改过——改名的唯一目的就是躲开那些靠节区名识别的查壳工具。
1.3 静态分析和动态分析,谁也替代不了谁
| 静态分析 | 动态分析 | |
|---|---|---|
| 做法 | 不运行,直接读二进制 | 跑起来,观察行为 |
| 能拿到 | 结构、导入表、字符串、控制流 | 实际的文件/注册表/网络行为 |
| 盲区 | 遇到壳就看不进去;看不懂的加密数据 | 遇反调试/反虚拟机就失效;行为可能不触发 |
这次实验里有个很好的例子:crackme2 的成功提示在磁盘上根本不存在明文,它是运行时用 XOR 0x42 一个字节一个字节解出来的。只看静态,你只能看到一段乱码数据表;只看动态,你只知道它打印了一句话,不知道为什么。两边一起看才完整。
1.4 字符串提取:最便宜也最容易漏的一招
strings 干的事很简单:从二进制里把连续的可打印字符抠出来。
它有两个参数必须记住:
-a:扫整个文件,不只是数据节-el:按 16 位小端 解码,也就是 UTF-16LE,用来抓 Unicode 字符串
为什么强调 -el?因为 VB6 写的程序,字符串默认就是 Unicode 存储的。这次的样本 RaDa.exe 正是 VB6 编译的(Visual Basic 6.00.8041 [Native])。只跑 strings -a,能扫到 177 条;补上 -el,又冒出 109 条。这 109 条里就有它的工作目录和作者信息。
1.5 IRC 和僵尸网络:为什么黑客偏爱一个聊天协议
IRC(Internet Relay Chat) 是 1988 年的东西,客户端/服务器架构,纯明文。它的工作流程就四步:
- 客户端连上服务器(默认 TCP 6667,加密版 6697)
- 发
NICK <昵称>声明自己叫什么 - 发
USER <用户名> <主机名> <服务器名> :<真实名>登记身份 - 发
JOIN #<频道>进频道,之后就能收频道里的广播
服务器会用数字代号回复,比如 001 是欢迎信息、353 是频道成员名单(NAMES 回复)。
为什么僵尸网络用它做 C2(命令与控制):
- 一条指令发到频道里,所有在线的 Bot 同时收到——天生的"一对多"下发通道
- 协议极简,几十行代码就能实现一个 Bot
- 明文传输,Bot 端不需要处理加密
- 常年有公开的 IRC 服务器可以蹭,不用自己搭
僵尸网络(Botnet) 就是大量被植入 Bot 的主机,由一个 C2 集中控制。用途主要是 DDoS、发垃圾邮件、传播更多恶意程序、当跳板、窃取数据。这次实验里蜜罐被攻陷后的表现——大量外连别的机器的 80 端口——就是 Bot 在扫描下一批目标。
1.6 取证要用的工具链
- pcap:抓包文件格式,libpcap 定的,Wireshark / tcpdump / tshark 都能读
- 显示过滤器:
ip.src == x && tcp.dstport == 6667这种,只影响"显示什么",不改原始数据 - Follow TCP Stream:把一个 TCP 连接的双向数据按序拼起来看,看应用层协议必须用它
- tcpflow:按流把 pcap 拆成一个个文件,一条流一个文件,方便直接用 grep 统计
- tshark:Wireshark 的命令行版,
-T fields -e 字段名可以只输出想要的字段,做批量统计比点鼠标快得多
tshark 有个坑要注意:如果指定的协议字段在这份抓包里根本不存在(比如包里没有 TFTP 却写 -e tftp.filename),它不会返回空,而是直接报"字段无效"。这个报错本身就可以当作"没有这个协议"的判断依据。
2. 实验内容
本次实验包含三个动手任务和一个取证分析任务:
(一)恶意代码文件类型标识、脱壳与字符串提取
对提供的 rada 恶意代码样本:
- 使用文件格式和类型识别工具,给出 rada 恶意代码样本的文件格式、运行平台和加壳工具
- 使用超级巡警脱壳机等脱壳软件,对 rada 恶意代码样本进行脱壳
- 使用字符串提取工具,对脱壳后的样本进行分析,从中发现 rada 的编写作者是谁
(二)使用 IDA Pro 静态或动态分析 crackme1.exe 与 crackme2.exe
寻找特定输入,使其能够输出成功信息。
(三)分析自制恶意代码样本 rada,撰写分析报告
回答以下八个问题:
- 提供这个二进制文件的一个摘要,其中包含可帮助识别同一样本的基本信息
- 识别并解释这个二进制文件的目的
- 识别并解释这个文件具有哪些不同的特性
- 识别这个文件使用了哪些防止分析或反逆向工程的技术,并解释
- 对这个代码进行分类(病毒、蠕虫等),并给出理由
- 识别并解释过去已存在的具备类似功能的工具
- 有可能调查出这个二进制文件的开发者吗?如果可以,在什么样的环境和限定条件下?
- 至少给出 5 种检测该恶意软件的方法,并详细介绍(如基于特征码的方法)
(四)取证分析实践
分析的数据源是用 Snort 工具收集的蜜罐主机 5 天的网络数据,该 Windows 2000 系统被攻破并加入了僵尸网络。回答以下七个问题:
- IRC 是什么?当 IRC 客户端申请加入一个 IRC 网络时会发送什么消息?IRC 一般使用哪些 TCP 端口?
- 僵尸网络是什么?通常用于什么?
- 蜜罐主机
172.16.134.191与哪些 IRC 服务器通信? - 在观察期内,有多少不同的主机访问了以
209.196.44.172为服务器的僵尸网络? - 哪些 IP 被用于攻击蜜罐主机?
- 攻击者尝试攻击了哪些安全漏洞?
- 哪些攻击成功了?它们是如何成功的?
3. 实验过程
3.1 环境,以及一个开局就来的意外
环境是 Windows 11 物理机 + Kali 虚拟机,两台机器的主机名都改成了 wangxiaoxuan(图1、图2)。样本放在 C:\rada,工作目录里能看到 rada.rar、crackme1.exe、crackme2.exe(图3)。

图1 Kali 虚拟机主机名

图2 Windows 主机名

图3 工作目录中的样本文件
真正让我意外的是解压那一步。
rada.rar 解压到一半,火绒的文件实时监控弹了一个窗口:Trojan/DDos.c!crit,已处理。文件被清掉了。我先把 C:\rada 加进火绒的信任区(图4),重新解压,文件确实出现了,RaDa.exe 21 KB 好好地躺在那儿。

图4 在火绒信任区添加 C:\rada
然后过了两分钟,再 dir,文件又没了。
去 Windows 安全中心翻保护历史,才看明白:Defender 也在报,而且报得更细(图5、图6)。它的记录里写着:
类别: 特洛伊木马
警报级别: 严重
详情: 这个程序很危险,而且执行来自攻击者的命令。
受影响的项目: C:\rada\rada\RaDa.exe->(UPX)

图5 Defender 检出威胁的弹窗

图6 Defender 保护历史记录
加火绒信任区只对火绒生效,Defender 根本不看火绒的名单,各扫各的。最后是两边分别加排除项才解决(图7)。
不过这次拦截给了我一条意外收获:->(UPX) 这个标记是 Defender 引擎自己给出的——它在我用任何工具之前,先告诉我这文件是 UPX 加壳的。后面 DIE 的结论和它对上了。

图7 在 Defender 中添加排除项
3.2 任务一:从 20 KB 到 67 KB
3.2.1 先确认它是什么
习惯性先算哈希,一是留档,二是后面传输到 Kali 时可以校验完整性。Get-FileHash 一次只能给一种算法,索性跑两遍(图8):
MD5 CAAA6985A43225A0B3ADD54F44A0D4C7
SHA256 13C2379E9D9F679396E21A3391804CC834892F25691381B6D078D07B56D38F90

图8 RaDa.exe 的 MD5 与 SHA-256
传一份到 Kali,用 file 和 objdump 看结构(图9):
cd ~/lab4
md5sum RaDa.exe
file RaDa.exe
objdump -h RaDa.exe | head -25
输出第一行:
RaDa.exe: PE32 executable for MS Windows 4.00 (GUI), Intel i386, 3 sections

图9 file 输出与节区结构
这行读出来三件事:PE32 是 32 位;GUI 说明是窗口程序不是控制台程序;3 sections 说明只有三个节——正常 PE 一般四五个节,节数这么少本身就是加壳的信号。
3.2.2 壳被改了名字
objdump -h 的节区列表让我愣了一下:
Idx Name Size VMA LMA File off Algn
0 JDR0 0000b000 00401000 00401000 00000400 2**2
1 JDR1 00004000 00413000 00413000 00004000 2**2
2 .rsrc 00000000 00417000 00417000 00006000 2**2
我原本以为会看到 UPX0、UPX1,结果是 JDR0、JDR1。
UPX 生成的节区名是固定的,改成别的名字只有一个目的——躲开靠节区名识别的查壳工具。这属于轻度的反分析手段,但确实会让一些老工具认不出来。
数字更能说明问题:JDR0 的虚拟大小是 0xb000 = 45056 字节,可整个文件才 20992 字节。文件里根本没存这么多内容。这就是壳的标准结构——JDR0 是留给解压后代码"落地"的空房间,真正的数据压在 JDR1 里。
用 DIE 再确认一次(图10):
操作系统: Windows(95)[I386, 32位, GUI]
链接器: Microsoft Linker(6.0)
编译器: Visual Basic(6.00.8041)[Native]
语言: VB
打包工具: UPX[modified]
启发式: Compressed or packed data[EntryPoint + Imports like UPX (v0.94-1.93) + Section...]

图10 DIE 对 RaDa.exe 的识别结果
UPX[modified] 那个 [modified] 就是"节区名被改过"的意思。DIE 通过入口点 stub 特征认出是 UPX,同时又发现结构不标准,于是加了这个标注。两条独立证据对上了。
顺带得到一个信息:样本是 VB6 写的。这条后面很关键。
3.2.3 脱壳
用超级巡警万能脱壳工具,把 RaDa.exe 拖进去,点"给我脱"。
工具先识别了一遍,面板上给了一堆参数(图11):
| 字段 | 值 |
|---|---|
| 入口点 | 0000FD20 |
| 文件偏移 | 00004120 |
| EP 段 | JDR1 |
| 首字节 | 60 BE 00 C0 |
| 链接器 | 6.0 |
| 子系统 | Win32 GUI |
| 壳版本 | UPX 0.89.6 - 1.02 / 1.05 - 1.22 -> Markus & Lazlo |
| MD5 | CAAA6985...D4C7 |

图11 脱壳工具的识别信息
注意壳版本写的是 1.22,不是网上更常见的 2.90。这个以工具显示的为准,不改成自己印象里的版本号。另外这里的 MD5 是工具自己又算了一遍,和我在 Windows、Kali 两端算的完全一致——三次独立计算同一个值,文件没有被动过。
点"给我脱",提示 Unpack successfully!,同目录下生成了 RaDa_unpacked.exe(图12),重命名为 RaDa_20242329_unpacked.exe(图13)。

图12 脱壳成功的提示

图13 脱壳产物 67.22 KB
大小从 20.50 KB 变成 67.22 KB,膨胀 3.3 倍,符合 UPX 解压的比例。样本包里还自带一个 rada_dump_.exe,76 KB,比我的产物大 8 KB——那是别人从内存 dump 的,带着运行时镜像的对齐填充;我这是文件型脱壳,还原的是原始节表,所以更小更干净。
脱完再用 DIE 扫一遍(图14):
打包工具 那一栏空了,UPX[modified] 没了。说明脱干净了。

图14 DIE 复检脱壳产物,已无 UPX
只剩一条启发式提示还在:Compressed or packed data[Sections collision ("JDR")]。这是误报——脱壳工具把内容还原了,但没改节区名,JDR0 和 JDR1 还在,而且范围有重叠,DIE 的启发式规则一看"节区名怪 + 有重叠"就当打包特征报了出来。判断有没有壳要看 打包工具 那栏,那栏空了就是没壳。
3.2.4 字符串里的两个作者
VB6 的字符串是 Unicode,所以两个参数都要上(图15):
strings -a RaDa_20242329_unpacked.exe | grep -inE "author|siles|perez"
strings -el RaDa_20242329_unpacked.exe | grep -inE "author|siles|perez"
命中了四条:
53:Copyright (C) 2004 Raul Siles & David Perez
70:--authors
121:Authors: Raul Siles & David Perez, 2004
207:(c) Raul Siles && David Perez

图15 字符串中命中的作者信息
四条不同写法互相印证,不是偶然残留。作者是 Raul Siles 和 David Perez,2004 年。
这里有个坑,差点踩进去:IDA 的 Strings 窗口里还能看到 DataRescue sa/nv、ida@datarescue.com,那是 IDA 自己加载文件时带进去的字符串,不是样本作者。判断方法很简单——这类字符串在未脱壳的原样本里也存在,说明它来自分析工具而不是样本本身。
还有一条更隐蔽的:Copyright (C) 2001 Antonin Foller, PSTRUH Software。这是它借用的第三方上传组件的版权声明,同样不是作者。
顺带比较了一下加壳前后能提取到的信息量(图16):
| 加壳态 | 脱壳后 | |
|---|---|---|
| 可打印字符串 | 306 条 | 635 条 |
| 功能关键词命中 | 1 条 | 13 条 |

图16 加壳态与脱壳后的字符串对比
条数只翻了一倍,但有效信息翻了 13 倍。加壳态那 306 条基本全是 PE 头和资源区的残留,真正有用的东西全压在 JDR1 里。
任务一小结:RaDa.exe 是 32 位 Windows 图形界面程序,用 UPX 加壳且节区名被改成 JDR0/JDR1,脱壳后从字符串里提取到 Authors: Raul Siles & David Perez, 2004。
3.3 任务二:两个 crackme
3.3.1 crackme1:一句话藏在图里
先不动 IDA,喂参数看反应(图17):
| 输入 | 实际 argc | 输出 |
|---|---|---|
crackme1.exe |
1 | I think you are missing something. |
crackme1.exe test |
2 | Pardon? What did you say? |
crackme1.exe test test2 |
3 | I think you are missing something. |
crackme1.exe test test2 test3 |
4 | I think you are missing something. |

图17 crackme1 的参数试探
只有 argc 恰好为 2 时提示才变。也就是说:参数个数这一关已经过了,卡在内容比较上。
打开 IDA,Shift+F12 找到提示语(图18),双击、Ctrl+X 查引用,跳到反汇编。

图18 IDA 的 Strings 窗口
那段控制流是这样的(图19):
cmp [ebp+argc], 2 ← 参数个数必须等于 2
jz short loc_4012D2 ← 相等才跳去比较
...
loc_4012D2:
mov eax, [ebp+argv]
add eax, 4 ← argv[1],第一个参数
push offset Str2 ; "I know the secret"
push dword ptr [eax] ; Str1 = 你输入的
call _strcmp
test eax, eax
jz short loc_401310 ← 相等就走成功分支

图19 crackme1 的控制流图
push offset Str2 旁边 IDA 已经把字符串注出来了:"I know the secret"。
跑一下(图20):
crackme1.exe "I know the secret"
→ You know how to speak to programs, Mr. Reverse-Engineer

图20 crackme1 输出成功信息
引号不能省,不然会被 shell 拆成四个参数,又退回 missing something。
3.3.2 crackme2:它先问"你是谁"
crackme2 的反应不一样(图21):
| 输入 | 输出 |
|---|---|
| 无参数 | I think you are missing something. |
crackme2.exe test |
I have an identity problem. |

图21 crackme2 的参数试探
identity(身份)这个词很扎眼。程序在检查"自己是谁"。
IDA 里跟进去(图22),第一道关卡是:
loc_4012D5:
mov eax, [ebp+argv]
push offset Str2 ; "crackmeplease.exe"
push dword ptr [eax] ; Str1 = argv[0],程序自身的名字
call _strcmp
jz short loc_401313

图22 crackme2 的控制流图
argv[0] 是程序自己的文件名。它要求自己必须叫 crackmeplease.exe——我现在的名字是 crackme2.exe,所以它说"我有身份问题"。
第二道关卡跟 crackme1 一样:argv[1] 必须等于 I know the secret。
过了两关之后还有彩蛋。成功分支不是直接 printf,而是:
loc_401358:
mov eax, [ebp+var_4]
add eax, offset unk_403080 ; 一张编码过的数据表
mov al, [eax]
xor eax, 42h ; 每个字节异或 0x42
push eax
call _putchar
inc dword ptr [ebp+var_4]
jmp short loc_401358 ; 循环
成功提示在磁盘上根本不存在明文,是运行时从数据表里逐字节 XOR 0x42 解出来再打印的。
这里有个必须用 cmd 而不能用 PowerShell 的坑,后面问题章细说。改名之后在 cmd 里跑(图23):
copy crackme2.exe crackmeplease.exe
crackmeplease.exe "I know the secret"
输出:
We have a little secret: Chocolate

图23 crackme2 输出成功信息
3.4 任务三:RaDa 的八个问题
DIE 已经确认它是 VB6 程序,所以字符串要两条路一起扫。先看 ASCII(图24):
strings -a RaDa_20242329_unpacked.exe > rada_str.txt
按四组关键词过滤,结果有点意外:网络通信、注册表自启动两组全部零命中,目录那组唯一命中还是 binary 里带了个 bin(假阳性)。只有功能词组有货:
Command_install / Command_uninstall / Command_usage
Command_exit / Command_conf / Command_go / Sleep

图24 四组关键词的过滤结果
Command_* 一整组命令名,加上 Sleep,说明它有一张命令分派表,并且以轮询方式等待指令。
但零命中这件事不对劲。 VB6 的字符串是 Unicode 存储的,strings -a 只扫 ASCII,很可能漏了一大半。补扫(图25):
strings -a -n 6 RaDa_20242329_unpacked.exe | sort -u > rada_s.txt # 177 条
strings -el -n 6 RaDa_20242329_unpacked.exe | sort -u > rada_e.txt # 109 条

图25 ASCII 与 Unicode 两次扫描的条数
补完再看清单,东西全出来了(图26、图27)。

图26 字符串清单 A

图27 字符串清单 B
里面有两条特别关键。
第一条,反虚拟机:
00:05:69: 00:0C:29: 00:50:56:
这三个全是 VMware 的 MAC 地址前缀(OUI)。程序在枚举本机网卡、比对 MAC 前缀——一旦发现跑在 VMware 里,就改变行为或直接退出。这是教科书级的反虚拟机手法,而且它是明文躺在字符串里的。
第二条,它是个 HTTP 后门:
multipart/form-data; boundary= Content-Disposition: form-data
cgi-bin download.cgi application/upload
--cgipath --cgiget --cgiput --commands --cycles
[cscript|wscript] fupload.vbs file url [fieldname]
C:\RaDa\bin C:\RaDa\tmp
拼起来就是:连到可配置的 CGI 端点 → 用 multipart 表单上传下载文件 → 按命令表分派执行 → Sleep 轮询等指令。
下面按八个问题逐条作答。
(1)摘要
| 项目 | 内容 |
|---|---|
| 文件名 | RaDa.exe |
| 大小 | 20,992 字节 |
| MD5 | CAAA6985A43225A0B3ADD54F44A0D4C7 |
| SHA-256 | 13C2379E9D9F679396E21A3391804CC834892F25691381B6D078D07B56D38F90 |
| 文件格式 | PE32,GUI,Intel i386,3 个节 |
| 编译环境 | Microsoft Linker 6.0 + Visual Basic 6.00.8041 [Native] |
| 加壳 | UPX(0.89.6-1.02 / 1.05-1.22),节区名改为 JDR0/JDR1 |
| 入口点 / EP 段 | 0000FD20 / JDR1 |
| 脱壳后大小 | 67.22 KiB |
| 作者标识 | Authors: Raul Siles & David Perez, 2004 |
| 自身标记 | This program is the binary of SotM 32 |
| 显著字符串 | Security through obscurity is the key.、C:\RaDa\bin、C:\RaDa\tmp |
| 杀软判定 | 火绒 Trojan/DDos.c!crit;Defender「特洛伊木马」 |

图28 火绒对样本的检出
这些信息为什么能"识别同一样本":哈希是唯一指纹;而"VB6 + UPX 改节区名 + C:\RaDa\ 固定路径 + Security through obscurity is the key. 这句特有字符串"这一组合构成家族级指纹,样本即使被重新编译或换壳,这套特征仍大概率保留。
(2)目的
这是一个基于 HTTP 的远程控制后门,具备"接收指令 → 分派执行 → 上传下载文件"的能力,并带有安装/卸载、配置加载、循环轮询驻留等机制。
证据链:
- 命令分派:
Command_install、_uninstall、_usage、_exit、_conf、_go一整组命令名,说明内部有命令表 - 文件传输:
multipart/form-data、Content-Disposition、application/upload、download.cgi,标准的 HTTP 表单上传下载实现 - 服务端可配置:
cgi-bin、--cgipath、--cgiget、--cgiput——服务器端 CGI 路径由命令行参数指定,不是硬编码
| | |
| --- | --- | - 落地辅助:
[cscript|wscript] fupload.vbs file url [fieldname]这行用法提示说明它会调 Windows 脚本宿主执行fupload.vbs完成上传 - 驻留轮询:
Sleep+--cycles(循环次数) - 可能的命令执行:
COMSPEC是获取cmd.exe路径的常见手段,暗示能拉起系统 shell
(3)不同的特性
- VB6 编写:体积偏大、导入表稀薄、字符串以 Unicode 存储。这直接导致分析时必须用
strings -el补扫,否则漏掉一半 - 自带清晰的作者与用途标记:
Authors: ...、--authors命令行开关、This program is the binary of SotM 32、Security through obscurity is the key.。普通恶意软件极少主动暴露作者,更不会做一个"显示作者"的开关 - 固定工作目录:
C:\RaDa\bin、C:\RaDa\tmp,运行时会在系统盘根目录自建目录 - 命令行参数化程度高:服务器地址、命令内容、循环次数都能外部给定,等于把"攻击配置"和"程序本体"分离
- 依赖第三方组件:
Copyright (C) 2001 Antonin Foller, PSTRUH Software,上传功能借用了第三方组件,也导致版权字符串混杂,容易误判作者 - 带图形界面:
Subsystem = GUI,一个后门却做成窗口程序,与常见的无界面 Bot 不同
(4)防分析 / 反逆向技术
| 技术 | 证据 | 评价 |
|---|---|---|
| 加壳(UPX) | DIE 判定 UPX[modified];超级巡警识别出具体版本 |
低成本保护,只挡静态字符串查看 |
| 修改壳的节区名 | 标准应为 UPX0/UPX1,实际为 JDR0/JDR1 |
专门对抗按节区名识别的查壳工具;但 PEiD/DIE 靠入口点 stub 特征仍能识别 |
| 反虚拟机检测 | 00:05:69:、00:0C:29:、00:50:56: 三个 VMware OUI 前缀 |
枚举网卡 MAC,命中 VMware 前缀就改变行为或退出。这是本样本最实质的对抗手段 |
| 字符串藏于 Unicode | 关键字符串以 UTF-16 存储,strings -a 直接漏掉 |
非主动加密,但客观提高了漏扫概率 |
| 自嘲式"保护" | Security through obscurity is the key. |
作者明示思路:靠"不让人看懂"来保护,而非真正的密码学 |
有个对比值得一提:同批的 crackme2 里,成功提示是真的做了 XOR 0x42 加密,磁盘上查不到明文。相比之下 rada 的保护强度明显更低——它把希望完全寄托在"加壳 + 改节名 + 反虚拟机"上,代码层面没有做任何字符串加密。
(5)分类及理由
功能分类:木马类中的"后门 / 远程控制程序(Backdoor / RAT)"。
理由:
- 不是病毒:没有感染其他可执行文件、改写文件头、插入壳代码段的逻辑
- 不是蠕虫:没有扫描网段、自动复制传播、利用漏洞横向移动的代码
- 符合木马/后门特征:不自复制、以独立程序存在、提供远程指令接收与文件上传下载、具备安装/卸载与驻留(
Sleep轮询)能力、主动规避分析环境
但要补一个观察:样本自带 --authors 开关、公开署名、SotM 32 标记,还有 Security through obscurity is the key. 这种研究者口吻的注释。这更像为安全研究/挑战赛编写的样本,而不是在野传播的恶意软件。功能上是后门,来源上像教学样本——这两层要分开写。
关于杀软的 Trojan/DDos 标签:火绒把它归为 DDoS 木马,但从静态字符串看,没有洪泛发包、UDP 炸弹这类 DDoS 代码特征,更突出的是上传下载与命令分派。这个标签应当理解为家族/行为归类,不能直接当分类依据。
(6)过去已有的类似工具
| 功能 | 历史同类工具 |
|---|---|
| HTTP 隧道远程控制 + 文件上传下载 | Back Orifice 2000(BO2K)、NetBus、Sub7、灰鸽子、PoisonIvy、Gh0st RAT |
| 通过 Web/CGI 收发指令的"网页后门" | China Chopper(一句话木马)、c99/c100 shell、r57 shell |
| 命令行参数驱动的传输工具 | curl、wget、tftp 客户端 |
跟它们的区别:rada 不是通用远控(没有屏幕控制、键盘记录、摄像头模块),而是窄化到"文件上传下载 + 有限命令";同时服务端完全外置(--cgipath 指定),自身只做客户端,更像"定制化的 HTTP 窃密工具"。
(7)能否查处开发者
分三层看。
第一层,样本本身能给出什么:署名有 4 处不同写法(Copyright (C) 2004 ...、(c) ...、Authors: ...、--authors 开关),编译环境是 VB6 + Linker 6.0,使用 ADODB、COMSPEC 和第三方上传组件,还有 SotM 32 这个来源标记。
第二层,什么条件下能进一步确认:
- 编译时间戳未被伪造,且能与样本首次公开时间、VT 上传时间互相印证
- 样本来源可追溯(发布渠道、配套说明文档、挑战赛页面)
- 署名中的姓名可与公开的安全研究社区身份交叉验证
- 有授权的情报/执法渠道做关联
第三层,结论:能确定署名作者,署名与编译特征、语言风格自洽。但"署名"只是作者的自述,不等于法律意义上的身份认定。严格说:能在"公开信息 + 样本内部证据"范围内归因到具体署名,无法进一步确认现实身份。
这个问题的坑在于:字符串里同时存在 Copyright (C) 2001 Antonin Foller, PSTRUH Software(第三方组件版权)和 DataRescue sa/nv(IDA 工具残留)。样本里出现的版权人,不一定就是样本作者。
(8)至少五种检测方法
① 基于特征码(签名)检测
原理:提取唯一且稳定的字节序列或字符串作为签名,扫描命中即告警。
落地:用 Security through obscurity is the key.、Command_uninstall、C:\RaDa\tmp 三组字符串做 YARA 规则,对磁盘和内存同时扫。
rule RaDa_Backdoor_Strings
{
meta:
author = "wangxiaoxuan 20242329"
description = "Detect RaDa HTTP backdoor by unique strings"
strings:
$s1 = "Security through obscurity is the key." ascii wide
$s2 = "Command_uninstall" ascii
$s3 = "C:\\RaDa\\tmp" ascii wide
$s4 = "Authors: Raul Siles & David Perez" ascii
condition:
uint16(0) == 0x5A4D and 2 of them
}
② 基于哈希的黑名单
原理:MD5/SHA-256 唯一标识文件,命中已知恶意哈希即判定。
落地:CAAA6985A43225A0B3ADD54F44A0D4C7 入库。缺点是改一个字节就失效,所以要配合 imphash(导入表哈希)做家族级识别——即使重新加壳,导入表组合往往不变。
③ 基于 PE 结构 / 静态特征
原理:异常结构本身就是可疑信号,不需要认识具体家族。
落地:节区名为非标准 JDR0/JDR1、节数只有 3 个、入口点不在 .text、JDR0 虚拟大小远大于文件实际大小、VB6 程序却带 UPX 壳——任一条命中就提升可疑度。
④ 基于主机行为 / 主机指标(EDR)
原理:监控敏感操作序列。
落地:监控 C:\RaDa\bin、C:\RaDa\tmp 目录被创建;监控进程通过 COMSPEC 拉起 cmd.exe;监控 wscript.exe/cscript.exe 执行 fupload.vbs;监控进程周期性 Sleep 后发起 HTTP 请求的规律。
⑤ 基于网络流量(IDS / NGFW)
原理:识别 C2 通信特征。
落地:检测发往 cgi-bin 下 .cgi 的 HTTP POST 且 Content-Type: multipart/form-data;检测异常的 Content-Disposition: form-data 大文件上传;统计单一内网主机对同一外部 CGI 端点的周期性请求(与 --cycles 吻合)。
⑥ 基于内存扫描(补充)
原理:脱壳后的真实代码只存在于内存,磁盘扫描抓不到。
落地:磁盘上是 UPX 壳,字符串特征可能被压缩掉;改为对进程内存做 YARA 扫描,或对 JDR0 解压后的区域做特征匹配,命中率显著高于文件扫描。
小结
rada 是一个用 VB6 编写、经 UPX(改节区名)加壳的 HTTP 后门程序。它通过可配置的 CGI 端点与被控端交互,支持命令分派、文件上传下载、安装卸载与周期轮询,并具备基于 VMware MAC 前缀的反虚拟机能力。样本自身暴露的作者署名与 SotM 32 标记表明它更可能来源于安全研究场景——这提醒我:功能定性(后门)与来源定性(研究样本)是两个维度,不能混为一谈。
3.5 任务四:5 天流量里的一个人
3.5.1 先看这个包有多大
capinfos botnet_pcap_file.dat
54,536 个包、17 MB、时间跨度 429,588 秒(约 4.97 天),2003-03-01 04:08 到 03-06 03:27。平均包长 316 字节,都是小包,典型的控制流量。
时间落在 2003 年 3 月,和 Honeynet 的 SotM 27 挑战完全吻合。
3.5.2 谁在跟谁说话
第一个问题:蜜罐 172.16.134.191 跟哪些 IRC 服务器通信过。过滤器:
ip.src == 172.16.134.191 && tcp.dstport == 6667
从 5 万多条筛到 496 条(图29)。

图29 蜜罐主动连接 6667 的流量
用 Statistics → Endpoints 汇总(图30):
| IRC 服务器 | 包数 | 判断 |
|---|---|---|
| 63.241.174.144 | 17 | 仅尝试 |
| 66.33.65.58 | 9 | 仅尝试 |
| 209.126.161.29 | 9 | 仅尝试 |
| 217.199.175.10 | 14 | 仅尝试 |
| 209.196.44.172 | 18,700 | 建立持续会话 |

图30 端点统计:5 台 IRC 服务器
这张表的关键不是"5 台",而是分布:四台只发了不到 20 个包,一台发了 1.87 万个。那 4 台是蜜罐挨个试连、连不上就走;只有 209.196.44.172 承载了完整会话,是真正的 C2。
跟一条流看内容(图31):
NOTICE AUTH :*** Looking up your hostname...
NICK rgdiuggac
USER rgdiuggac localhost localhost :rgdiuggac
:irc5.aol.com 001 rgdiuggac :Welcome to the Internet Relay Network...
265: Current local users: 346 Max: 348
266: Current global users: 4752 Max: 4765
JOIN #x... :sex0r
:irc5.aol.com 353 rgdiuggac @ #x... :nick1 nick2 nick3 ...

图31 IRC 流的应用层内容
第 1 问问的"客户端入网发什么消息",答案就在 NICK 和 USER 这两行;端口 6667 也在过滤器里验证过了。IRC 是明文协议,所以这些内容在流量里一览无余——这也是它容易被取证的原因。
3.5.3 数一遍僵尸网络有多大
用 tcpflow 把这条流拆成文件(图32):
tcpflow -r botnet_pcap_file.dat 'host 209.196.44.172 and port 6667'

图32 tcpflow 按流还原出的文件
两个文件大小差得离谱:
| 方向 | 大小 |
|---|---|
| 蜜罐 → 服务器 | 1,052 字节 |
| 服务器 → 蜜罐 | 1,082,018 字节 |
蜜罐只说了 1 KB 的话(NICK、USER、JOIN、PING),服务器回了 1 MB 成员名单。僵尸网络的规模全堆在下行流量里。
从下行流里提取 353 行、取昵称、去重(图33、图34):
cat 209.196.044.172.06667-172.016.134.191.01152 \
| grep -a " 353 " \
| sed 's/^.* #x[^ ]* ://' \
| tr ' ' '\n' \
| sed 's/^[@+~&]//' \
| tr -d '\r' \
| grep -v '^$' | sort -u | wc -l
结果 3460。

图33 353 名单去重后的计数

图34 353 条目总数与回复条数
但这里有三个数,口径完全不同:
| 数字 | 出处 | 含义 |
|---|---|---|
| 346 | 流中 265: 行 |
该服务器本地客户端数(瞬时) |
| 4752 | 流中 266: 行 |
全局用户数,跨 4 台服务器(瞬时) |
| 3460 | 我的统计 | 该频道出现过的不同昵称数(去重) |
另有 3729 是名单条目总数(含重复与 @/+ 状态前缀),68 是收到的 353 回复条数。
第 4 问该答 3460,因为题目问的是"多少个不同主机"。但要加一句限定:昵称数并不严格等于主机数——同一台主机可能注册多个昵称,不同主机也可能重名,而且数据集的 hostmask 已脱敏,无法按主机名精确归并。所以 3460 是"参与该频道的不同客户端标识数",作为规模的近似值。
3.5.4 谁在打,打了什么
筛出"主动向蜜罐发起连接"的源(SYN=1 && ACK=0),前 20 名(图35):
| 源 IP | SYN 次数 |
|---|---|
| 24.197.194.106 | 1,229 |
| 210.22.204.101 | 105 |
| 129.116.182.239 | 10 |
| 66.139.10.15 / 209.45.125.69 | 6 |
| 其余 15 个 | 1–5 |

图35 攻击源 IP 统计
长尾分布非常明显。真正有攻击意图的只有两个:24.197.194.106 和 210.22.204.101。
再看他们请求了什么(图36):
/msadc/../../../../../../winnt/system32/cmd.exe?/c+dir
/_vti_bin/../../../../../../winnt/system32/cmd.exe?/c+dir
/scripts/../../../../../../winnt/system32/cmd.exe?/c+dir
/_vti_cnf/ /_mem_bin/ /_exchange/ /PBServer/ /Rpc/ /samples/ /cgi-bin/ /bin/ ...

图36 攻击请求的 URI 列表
拆开是三段:msadc、_vti_bin、scripts 这些是 IIS 里已知可执行或有缺陷的虚拟目录;../../../../../../winnt/system32/ 是目录遍历,跳出 Web 根目录;cmd.exe?/c+dir 是执行命令(+ 是 URL 编码的空格)。十来个路径 × 各 8 次,典型的工具化扫描。
这是 IIS 目录遍历 / Unicode 双重解码类漏洞(MS00-078、MS01-057 一系)的探测尝试,目的不是直接入侵,而是先确认"能不能执行命令"。
3.5.5 真正成功的那一次
这一问差点写反。
按常理,24.197.194.106 发了 1229 个 SYN、把所有 cmd.exe?/c+dir 都试了一遍,应该是"攻击成功"的那个。但查状态码(图37):
| 源 IP | 200 响应 |
|---|---|
| 168.169.174.108 | 3 次(03-01、03-02,抓包中未捕获请求原文) |
| 213.23.49.158 | 1 次(03-01 07:47,请求是 GET /,普通页面访问) |
| 210.22.204.101 | 1 次(03-04 21:39:24) |
| 24.197.194.106 | 0 次 |

图37 HTTP 状态码统计与各 IP 的 200 响应时间
狂发 1229 个 SYN 的那个,一个 200 都没拿到。 它的活动时间也只有 05:42:47 到 06:07:24,25 分钟,一次失败的自动化扫描。
真凶是那个只发了 105 次连接的 210.22.204.101,它用的也不是目录遍历,而是溢出(图38):
/NULL.IDA?CCCCCCCCCCCC...(数千字节填充)...
%u0ae0%u8b90%x96d%u77e5%u0000%u0000%u38b%u0094%u000%u408b%u0564%u0150...
...(Unicode 编码的 shellcode)...
...cmd.exe$

图38 .ida 溢出载荷,末尾拼接 cmd.exe
超长 C 填充 + %u 编码的 Unicode shellcode + 末尾拼 cmd.exe。这是 Index Server ISAPI 扩展 .ida/.idq 缓冲区溢出(MS01-033 / CVE-2001-0500),也就是 Code Red / Code Red II 蠕虫用的同一个漏洞家族。请求发出后,服务器返回了 HTTP 200。
判定成功靠三条证据串起来:
① 攻击请求被正常响应:210.22.204.101 在 2003-03-04 21:39:24 收到 200(图37)。
② 攻击后 2.7 小时出现 Bot 行为:03-05 00:21 起,蜜罐主动连接数十个外部 IP 的 80 端口(207.68.176.250、207.46.196.108、128.242.214.10、217.151.192.231、194.68.68.39…)。这是 Bot 在扫描下一批目标——只有溢出后的代码已经在跑,才会有这种行为(图39 D 组)。
③ 最终回连 C2:2003-03-05 22:36:42,蜜罐首次主动连 209.196.44.172:6667,完成 NICK/USER/JOIN,成为该僵尸网络的一员(图39 B 组)。

图39 时间线:攻击者活动时间与蜜罐首次回连时间
完整时间线:
| 时间(-0500) | 事件 |
|---|---|
| 03-01 07:47 | 213.23.49.158 请求 /,返回 200,普通访问 |
| 03-01 / 03-02 | 168.169.174.108 获得 3 次 200,请求原文未捕获,无法判定 |
| 03-04 21:39:24 | 210.22.204.101 发送 .ida 溢出载荷,返回 HTTP 200 |
| 03-04 21:39–21:40 | 同一 IP 重复发送多次溢出请求 |
| 03-05 00:21–00:25 | 蜜罐开始向数十个外部 IP 的 80 端口发起连接(Bot 扫描) |
| 03-05 05:42–06:07 | 24.197.194.106 发起 1229 次 SYN + 目录遍历,零个 200 |
| 03-05 22:36:42 | 蜜罐首次连 209.196.44.172:6667,加入僵尸网络 |
因果链闭合:溢出攻击成功 → 2.7 小时后 Bot 已运行并扫描 → 最终回连 C2。
至于为什么能成功:蜜罐是未打补丁的 Windows 2000 + IIS,.ida/.idq ISAPI 扩展的缓冲区长度没做校验,超长请求就能覆盖栈上返回地址;载荷用 Unicode 编码绕过字符过滤,一次 GET 就拿到命令执行权限。整个攻击混在正常的 80 端口流量里,不需要认证。
4. 问题及解决方案
问题一:解压两次,文件消失两次
现象:rada.rar 解压时火绒弹窗报 Trojan/DDos.c!crit 并处理,文件被清掉。把 C:\rada 加进火绒信任区、重新解压后,文件出现了;过了两分钟再 dir,又没了。
排查:先去 Windows 安全中心的保护历史记录翻,发现 Defender 也报了,而且记录里写着 C:\rada\rada\RaDa.exe->(UPX)。也就是说这期间两套杀软都在扫,我加的火绒信任区对 Defender 完全无效。
原因:火绒和 Defender 是两套独立的引擎,各自的信任名单/排除项互不通用。加了一边的白名单,另一边照样拦。
改法:两边分别加。火绒放信任区,Defender 放排除项(管理设置 → 排除项 → 添加文件夹),然后从隔离区还原文件。加完再解压,文件稳住了。
经验:杀软的白名单是"每家自己的一份",装了两套就得配两遍。 另外,拦截这件事本身是情报——->(UPX) 这个标记是 Defender 引擎给出的,比我用任何工具都早。
问题二:Get-FileHash 一次算两种哈希,直接报类型错误
现象:
Get-FileHash .\RaDa.exe -Algorithm MD5,SHA256
→ 无法将值转换为类型 System.String
排查:看报错信息,它说的是"无法转换为 String",不是"参数错误"。说明 PowerShell 把 MD5,SHA256 当成一个数组,而 -Algorithm 参数在这个版本里只接受单个字符串。
原因:Windows PowerShell 5.1 的 Get-FileHash -Algorithm 是单值参数。PowerShell 7 之后才支持数组。我这台机器是 5.1。
改法:拆成两条跑,或者用 certutil -hashfile(老命令,没这个限制)。
经验:报错关键字要说的是"类型"而不是"值",问题多半在参数形状上,不在内容上。 版本差异导致的这种小坑,查文档比猜快。
问题三:strings 扫出 177 条就以为扫完了
现象:对脱壳后的样本按四组关键词过滤,网络通信、注册表自启动两组完全零命中。当时第一反应是"这样本没有网络功能",但 DIE 明明显示它是 VB6 程序,而 rada 的功能不可能不上网。
排查:停下来想了一下——VB6 的字符串是 BSTR,也就是 UTF-16LE 存储。strings 默认只按单字节 ASCII 扫,UTF-16 里每个字符后面跟一个 \x00,在它眼里就是"长度为 1 的碎片",全被过滤掉了。
原因:漏了 -el 参数。
改法:
strings -el -n 6 RaDa_20242329_unpacked.exe | sort -u > rada_e.txt
补扫之后,Unicode 那批多出 109 条,C:\RaDa\bin、C:\RaDa\tmp、00:05:69: 这些关键证据全在里面。前面那个"零命中"是假象。
经验:strings 不是一条命令,是两条。 只要目标是 VB6/Delphi 这类用宽字符写字符串的编译器产物,-a 和 -el 必须一起上,少一条就可能得出完全相反的结论。
问题四:crackme2 明明改名了,还是"identity problem"
现象:在 IDA 里看到它比较的是 argv[0] 和 "crackmeplease.exe",于是把文件复制成 crackmeplease.exe。但在 PowerShell 里跑 .\crackmeplease.exe "I know the secret",还是报 I have an identity problem.
排查:PowerShell 里执行当前目录的程序必须加 .\ 前缀。而这个前缀会原样进入命令行,程序拿到的 argv[0] 就是 .\crackmeplease.exe,跟 crackmeplease.exe 字符串比较当然不相等——多出来的 .\ 让它"身份"对不上。
原因:不是文件名错了,是调用方式让 argv[0] 变了。
改法:换 cmd(命令提示符),cd /d C:\rada 之后直接敲 crackmeplease.exe "I know the secret",不带任何前缀。这次 argv[0] 就是纯文件名,第一关过了,输出 We have a little secret: Chocolate。
经验:argv[0] 是"你敲的那个字符串",不是"文件的真实名字"。 同一个 exe,从不同 shell、用不同路径调起来,argv[0] 可能完全不同。凡是程序检查自身名字的题,调用方式本身就是解题条件。
问题五:僵尸网络的规模,三个数对不上
现象:先直接 wc -l 数名单,得到 3729;但流里服务器自己说 346(本地)、4752(全局)。三个数差得离谱,不知道报告该写哪个。
排查:拆开看。3729 是条目总数,里面有重复——68 条 353 回复,成员进出频道会让同一个昵称反复出现;而且条目带 @(管理员)、+(语音)这类状态前缀,同一个昵称可能以两种形态出现。346 和 4752 是服务器在连接那一刻自报的在线数,一个是本机、一个是全网,跟"频道里出现过多少不同昵称"本来就是三件事。
改法:剥掉状态前缀、sort -u 去重,得到 3460。报告里答 3460(题目问"不同主机"),同时把三种口径列表说明。
经验:统计之前先问一句"这个数字在数什么"。 同一个对象,数"条目""去重元素""瞬时在线"会得到三个都正确但互相矛盾的答案。不把口径写清楚,数字就是错的。
问题六:找不到 Directory of,一度以为攻击没成功
现象:用 tshark -Y 'frame contains "Directory of"' 搜命令执行回显,零结果。按"命令执行成功就会有 dir 输出"的思路,这意味着目录遍历攻击全失败了。
排查:结果这个判断只对了一半。查状态码发现,发目录遍历的那个 IP(24.197.194.106)确实一个 200 都没有,攻击确实失败;但真正攻陷蜜罐的是另一个 IP 的溢出攻击,而溢出成功后 cmd.exe 的输出未必走 HTTP 回显(可能走反向连接)。所以"找不到回显"不等于"没人成功"。
改法:改用三重证据交叉判定——状态码 + 攻击后的 Bot 行为(扫描 80 端口)+ 最终回连 C2 的时间顺序。三条都对上,才能下"成功"的结论。
经验:一条证据缺失,不能直接推出否定结论。 尤其是取证,找不到某样东西,先想"它本来会不会出现在这里",再想"是不是被人拿走了"。
5. 学习感悟、思考等
一、最响的那个,往往不是真凶。
任务四里我差点写错。24.197.194.106 发了 1229 个 SYN,把十几个 cmd.exe?/c+dir 路径轮着刷了一遍,攻击意图明明白白。另一个 210.22.204.101 只发了 105 次连接,安安静静。
按直觉,前者才该是攻陷蜜罐的人。但状态码摊开一看:1229 次的,零个 200;105 次的,有。
这件事对我的冲击比技术本身大。以前看告警、看日志,本能地按"数量"排序,谁的告警多谁就是重点。但攻击者不需要刷屏——一次成功的溢出,比一千次失败的探测有用得多。动静大的那个在试探你,安静的那个才在做事。
二、壳只值 20 KB。
看到 JDR0/JDR1 那两个节区名的时候我有点意外,第一反应是"这壳改过名,得费点劲"。结果超级巡警点一下,20.50 KB 变 67.22 KB,两秒钟。
但真正让我记住的不是这个速度,是后面的对比:加壳态能提取 306 条字符串,脱壳后 635 条。数字只翻了一倍,可有用的功能关键词从 1 条变成 13 条——有效信息翻了 13 倍。
也就是说,壳挡住的是"一眼看穿",但它挡不住任何一个愿意花两秒钟点鼠标的人。20 KB 的压缩,换来的是"随手双击的人不会发现"——这个收益对作者来说可能是划算的,但对稍有训练的分析者来说接近于零。
反倒是那个"改节区名"的小动作让我想了更久。它对付的是工具,不是人。工具认不出 UPX,人还能看入口点、看节区大小、看导入表。所有的"防分析",防的都是自动化的那部分,人一旦愿意动手,成本低得可怜。
三、名字写在脸上,还是抓不到他。
rada 里有两个作者的名字,四种写法,还有 --authors 这么一个"显示作者"的开关。做实验的时候我一度觉得这作者挺业余——哪有恶意代码主动报名字的?
但把第 7 问想完,我发现业余的可能是我的思路。
署名不等于身份。Copyright (C) 2001 Antonin Foller, PSTRUH Software 这条就在旁边,那是第三方组件的版权;IDA 还会往 Strings 里塞 DataRescue sa/nv。如果一个字符串出现在样本里,它凭什么一定是作者? 三个"作者"里有两个是别人的,我要靠"在未脱壳的原样本里也存在"这种旁证才能排除。
技术归因是有边界的。样本能给我署名、编译环境、语言风格、来源标记;给不了身份证号。要往下走,就得靠样本之外的东西——发布时间线、发布渠道、公开身份、授权渠道。这些东西,一个二进制文件里一个字节都没有。
所以我最后写的是"能确认署名作者,但不能确认现实身份"。这不是回避,是我认为准确的说法。取证这件事,说清楚边界,比给出一个漂亮的结论难,也重要。
参考资料
[1] Michael Sikorski, Andrew Honig. 恶意代码分析实战[M]. 北京: 电子工业出版社, 2014.
[2] Wildlinux. 网络与系统攻防技术 实验指导书(实验四 恶意代码分析实践)[EB/OL]. https://gitee.com/wildlinux/NetSec
[3] 罗克杜. 网络攻防实践课程资料[EB/OL]. https://www.cnblogs.com/rocedu/p/5102332.html
[4] The Honeynet Project. Scan of the Month 27: Botnet Analysis[EB/OL]. https://www.honeynet.org/scans/scan27/
[5] Horsicq. Detect It Easy (DIE) 官方仓库与文档[EB/OL]. https://github.com/horsicq/DIE-engine
[6] UPX Team. UPX: the Ultimate Packer for eXecutables — 官方文档[EB/OL]. https://upx.github.io/
[7] Microsoft Learn. PE Format — 可移植可执行文件格式规范[EB/OL]. https://learn.microsoft.com/windows/win32/debug/pe-format
[8] Microsoft. Microsoft Security Bulletin MS01-033: Unchecked Buffer in Index Server ISAPI Extension Could Enable Web Server Compromise[EB/OL]. https://learn.microsoft.com/security-updates/securitybulletins/2001/ms01-033
[9] MITRE. CVE-2001-0500: Buffer overflow in ISAPI extension[EB/OL]. https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2001-0500
[10] Wireshark Foundation. Wireshark User's Guide[EB/OL]. https://www.wireshark.org/docs/
[11] Wireshark Foundation. tshark manual page[EB/OL]. https://www.wireshark.org/docs/man-pages/tshark.html
[12] O. K. Network Working Group. RFC 1459: Internet Relay Chat Protocol[S]. 1993. https://www.rfc-editor.org/rfc/rfc1459
[13] The Honeynet Project. Know Your Enemy: Tracking Botnets[EB/OL]. 2005. https://www.honeynet.org/papers/bots/
[14] VirusTotal. RaDa.exe 样本在线检测报告[EB/OL]. https://www.virustotal.com/
浙公网安备 33010602011771号