学号 20242306 2026-2027-1 《网络与系统攻防技术》实验四实验报告
1. 基础知识
1.1 PE文件格式
PE(Portable Executable)是Windows平台上可执行文件的标准格式,EXE、DLL、SYS等文件都属于PE格式。一个完整的PE文件从上到下依次是:DOS头(DOS Header)、PE头(PE Header)、节表(Section Table)、以及各个节(Section)。
DOS头开头是"MZ"两个字节,这是DOS时代留下来的遗产,用来保证旧系统也能识别这个文件。DOS头里有一个e_lfanew字段,指向真正的PE头位置。PE头开头是"PE\0\0"四个字节,后面跟着文件机器类型、节数量、时间戳、可选头大小等信息。
节表是一个数组,每个节描述一个段,包括节名、虚拟大小、虚拟地址、原始数据大小、原始数据指针、特征值等。常见的节有.text(代码段)、.data(数据段)、.rdata(只读数据段)、.rsrc(资源段)等。
1.2 加壳与脱壳
加壳就是把原始可执行文件压缩或者加密,生成一个新的可执行文件。运行的时候,加壳后的程序先在内存里把原始代码解压解密出来,然后跳过去执行。这样做的目的一个是缩小文件体积,另一个就是防止别人逆向分析。
常见的加壳工具:UPX(开源免费,最常见)、ASPack、Themida(强保护)、VMProtect(虚拟化保护)等。
脱壳就是反过来,把加壳后的文件还原成原始的可执行文件。脱壳方法分两类:
- 静态脱壳:分析壳的解压算法,直接在文件层面还原,比如upx -d就是静态脱壳
- 动态脱壳:在壳把原始代码解压到内存之后,直接dump内存里的内容,比如用OllyDbg跑到OEP(入口点)然后dump
1.3 字符串提取
字符串提取是恶意代码分析的第一步,就是从二进制文件里找出所有可打印的字符序列。为什么要找字符串?因为字符串里经常藏着关键信息:文件路径、注册表键、URL、命令名、错误提示等等。
Linux下用strings命令,默认搜ASCII编码。但要注意,Windows程序很多用Unicode(UTF-16LE)编码存字符串,这时候得加-e l参数才能搜出来。比如这次实验的rada就是VB写的,默认strings搜半天啥也没有,换成-e l就全出来了。
1.4 IDA Pro
IDA Pro是目前最强大的静态反汇编工具,被称为"逆向工程的瑞士军刀"。它能把二进制程序反汇编成汇编代码,还支持F5反编译功能,直接生成类C的伪代码,大大降低了阅读门槛。
IDA的核心功能:函数识别、交叉引用(XREF)、字符串窗口、结构体定义、类型恢复、调试器支持等。这次实验用的是IDA 8.3 32位版本。
1.5 恶意代码分类
常见的恶意代码分类:
- 病毒(Virus):感染其他文件,把自己复制进去
- 蠕虫(Worm):自我复制,通过网络主动传播,不需要用户操作
- 木马(Trojan):伪装成正常软件,偷偷干坏事
- 后门(Backdoor):在系统里留个口子,攻击者能远程进来
- 勒索软件(Ransomware):加密用户文件要钱
- 间谍软件(Spyware):偷偷收集用户信息
1.6 IRC协议与僵尸网络
IRC(Internet Relay Chat)是一种早期的即时聊天协议,基于TCP,默认端口6667。用户连接IRC服务器,加入频道(Channel),就能和频道里的人聊天。
僵尸网络(Botnet)就是大量被感染的主机组成的网络,攻击者通过C&C(命令与控制)服务器远程操控这些主机。IRC是僵尸网络最早用的C&C协议之一——攻击者开个IRC服务器,僵尸机上线后自动加入指定频道,攻击者在频道里发命令,所有僵尸机都执行。后来HTTP、P2P等方式慢慢多起来了。
1.7 SMB协议
SMB(Server Message Block)是Windows的文件共享协议,工作在应用层,底层用TCP 139或445端口。通过SMB,用户可以远程访问共享文件夹、打印机、命名管道等。
SMB也是Windows系统被攻击的重灾区——历史上出过Nimda蠕虫、冲击波、永恒之蓝这些大漏洞,都是打SMB的。这次实验的蜜罐就是Windows 2000系统,被人扫了139端口,最后还真被人登进去了。
2. 实验内容
- 对rada恶意代码样本进行文件类型识别、脱壳与字符串提取,找到编写作者
- 使用IDA Pro静态分析crackme1.exe与crackme2.exe,寻找特定输入使其输出成功信息
- 分析rada恶意代码样本,回答8个深度分析问题
- 分析Snort收集的蜜罐主机5天网络数据,回答取证分析问题
3. 实验过程
3.1 恶意代码文件类型标识、脱壳与字符串提取
3.1.1 文件类型识别
首先在Kali里用file命令识别RaDa.exe的文件类型,同时算一下MD5哈希:
file RaDa.exe
md5sum RaDa.exe
结果显示:PE32 executable for MS Windows 4.00 (GUI), Intel i386, 3 sections。MD5是caaa6985a43225a0b3add54f44a0d4c7。
【图1:file命令识别文件类型】
然后用readpe查看节表信息:
readpe -S RaDa.exe
结果显示节名为JDR0、JDR1、.rsrc。其中JDR0大小为0,JDR1大小为0x4000,这是典型的UPX加壳特征——UPX0节在运行时解压展开,UPX1节存放压缩数据。但节名被改成了JDR开头,不是标准的UPX0/UPX1,说明作者对壳做了篡改。
【图2:readpe查看节表】
3.1.2 脱壳处理
一开始在Kali上直接用upx -d脱壳,结果报错"file is modified/hacked/protected",脱壳失败了。后来分析才知道,作者不光改了节名,连UPX!的魔术字节都覆盖了,所以upx认不出来。
然后换Windows上试,先用"超级巡警虚拟机自动脱壳机",结果入口模拟跟踪脱壳失败。最后换"万能脱壳工具[超级巡警] V1.5",终于脱成功了,输出D:\RaDa_unpacked.exe。
【图3:万能脱壳工具识别壳类型,脱壳成功】
额外记录:Kali上upx脱壳失败的过程见"额外_Kali_upx脱壳失败.png",自动脱壳机失败见"额外_超级巡警自动脱壳机失败.png"
3.1.3 字符串提取找作者
脱壳后的文件复制到Kali,改名为20242306_RaDa_unpacked.exe。这里踩了个坑——一开始直接strings啥也没搜着,后来才想起来rada是VB写的,字符串是Unicode编码,得加-e l参数:
strings -e l 20242306_RaDa_unpacked.exe | grep -i -E "raul|david|perez|siles|copyright|author|sotm"
结果找到了作者信息:
!This program is the binary of SotM 32 ..
(c) Raul Siles && David Perez
SotM 32 - September 2004
【图5:strings提取作者信息】
结论:rada恶意代码的编写作者是Raul Siles和David Perez,编写时间为2004年9月,是Honeynet Project Scan of The Month 32挑战赛的样本。
3.2 使用IDA Pro分析crackme
3.2.1 crackme1.exe分析
用IDA Pro 8.3 (32-bit)打开crackme1.exe,等自动分析跑完,在函数列表里找到_main函数,双击进去,按F5反编译成伪代码。
伪代码很简单:
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;}
}
【图6:crackme1伪代码】
可以看到程序把命令行参数argv[1]和字符串"I know the secret"做比较,相等就输出成功信息。
在命令行里跑一下验证:
crackme1.exe "I know the secret"
输出:You know how to speak to programs, Mr. Reverse-Engineer
【图7:crackme1运行成功】
3.2.2 crackme2.exe分析
同样用IDA打开crackme2.exe,反编译main函数:
if (argc == 2)
{if (!strcmp(*argv, "crackmeplease.exe")){if (!strcmp(argv[1], "I know the secret")){for (i = 0; i <= 0x21; ++i)putchar((char)(byte_403080[i] ^ 0x42));puts(Buffer);return 0;}else{fprintf(&__iob[2], "Pardon? What did you say?\n");return 3;}}else{fprintf(&__iob[2], "I have an identity problem.\n");return 2;}
}
【图8:crackme2伪代码】
crackme2比crackme1多了一层检查:先检查程序自己的文件名是不是"crackmeplease.exe",然后再检查参数对不对。
把crackme2.exe改名为crackmeplease.exe,然后运行:
crackmeplease.exe "I know the secret"
输出:We have a little secret: Chocolate
【图9:crackme2运行成功】
3.3 rada恶意代码深度分析
3.3.1 二进制文件摘要
| 项目 | 信息 |
|---|---|
| 文件名 | RaDa.exe |
| MD5 | caaa6985a43225a0b3add54f44a0d4c7 |
| 文件格式 | PE32 executable (GUI) Intel 80386, MS Windows 4.00 |
| 编写语言 | Visual Basic 6.0(依赖MSVBVM60.DLL) |
| 加壳 | UPX 0.89.6(节名被篡改为JDR0/JDR1) |
| 来源 | Honeynet Project Scan of The Month 32, 2004年9月 |
| 作者 | Raul Siles & David Perez |
3.3.2 二进制文件的目的
这个二进制是个后门程序(Backdoor)。感染之后,攻击者可以通过HTTP协议远程控制这台机器:从远程服务器下载命令文件(HTML格式),执行系统命令,下载文件到受害主机,上传受害主机的文件到攻击者服务器,还会写注册表Run键实现开机自启动。
用strings -e l提取Unicode字符串,能看到关键行为特征:
【图10:rada行为特征字符串】
可以看到:
HKLM\Software\Microsoft\Windows\CurrentVersion\Run\—— 写注册表实现自启动http://10.10.10.10/RaDa—— 默认的命令服务器地址download.cgi/upload.cgi—— 文件下载上传的接口WScript.Shell—— 用来执行系统命令http://192.168./172.16./10.—— 只在私有网段工作
3.3.3 二进制文件的特性
- Visual Basic编写:依赖MSVBVM60.DLL,所以字符串都是Unicode编码
- HTTP命令控制:通过Internet Explorer控件下载HTML格式的命令文件
- 注册表自启动:写HKLM\Software\Microsoft\Windows\CurrentVersion\Run\键
- 命令行参数丰富:支持--authors、--uninstall、--noinstall、--period等参数
- 私有网段限制:命令服务器必须在私有子网(10.x.x.x、172.16.x.x、192.168.x.x),防止被公网反向利用
3.3.4 防止被分析的技术
- UPX加壳:压缩代码和数据,静态分析看不到原始字符串
- 节名篡改:把UPX0/UPX1节名改成JDR0/JDR1(作者名字Raul Siles & David Perez的首字母),阻止UPX自动脱壳
- UPX!标志覆盖:把UPX头部的魔术字节覆盖成"!This program is the binary of SotM 32..",导致自动脱壳工具认不出来
- VMware环境检测:检查VMware Tools的注册表键,发现自己在虚拟机里就不跑了
用strings提取防分析相关的字符串:
【图11:rada防分析技术字符串】
能看到:HKLM\Software\VMware, Inc.\VMware Tools\InstallPath,说明程序会检测自己是不是在VMware虚拟机里运行。
3.3.5 恶意代码分类
分类:后门程序(Backdoor)
理由:
- 不感染其他文件,所以不是病毒(Virus)
- 不主动传播,需要有人通过别的方式把它弄进系统,所以不是蠕虫(Worm)
- 装完之后给攻击者留远程控制的口子,这就是后门(Backdoor)
- 通过HTTP接收命令,属于远程访问型木马
3.3.6 相似功能的其他工具
- Back Orifice:90年代经典的Windows后门工具, Cult of the Dead Cow出的
- NetBus:远程控制木马,当年很有名
- Sub7:功能比NetBus还强的后门工具
- Gh0st(幽灵):国产远控木马,国内用得很多
- PoisonIvy(火焰):广泛使用的远控木马,很多APT组织用过
3.3.7 能否调查出作者
可以。 条件就是脱壳之后直接在二进制里搜字符串,就能找到版权信息"Copyright (C) 2004 Raul Siles & David Perez"。这俩人是Honeynet Project的安全研究人员,这个样本就是他们公开出来做安全竞赛用的。分析的时候在隔离的虚拟机里跑就行,没什么难度。
3.3.8 检测该恶意软件的5种方法
- 基于特征码检测:把脱壳后文件里的特定字节序列提取出来当特征码,杀毒软件匹配到就报毒
- 基于哈希检测:算文件的MD5或SHA1哈希,跟已知恶意样本哈希库比对(比如这个样本MD5是caaa6985a43225a0b3add54f44a0d4c7)
- 基于行为检测:监控程序是不是写注册表Run键自启动、是不是创建C:\RaDa\目录、是不是调用Internet Explorer下载文件
- 基于网络流量检测:检测异常的HTTP流量,特别是访问私有网段IP地址的HTTP请求,还有上传下载文件的流量模式
- 基于沙箱动态检测:在隔离环境里跑一下样本,看它是不是检测VMware环境、是不是尝试自启动、是不是连远程命令服务器
3.4 取证分析实践
用Wireshark打开botnet_pcap_file.dat,蜜罐主机IP是172.16.134.191。
3.4.1 IRC基础概念
IRC(Internet Relay Chat,互联网中继聊天)是一种即时聊天协议。IRC客户端申请加入IRC网络的时候,会先发NICK消息(选昵称),再发USER消息(填用户名信息)。IRC一般用TCP端口6667,也有用6660-6669、7000这些端口的。
3.4.2 僵尸网络概念
僵尸网络(Botnet)就是攻击者控制的一大批被感染的机器,攻击者通过C&C服务器远程发命令,这些机器就跟着干活。通常用来DDoS、发垃圾邮件、偷信息、传蠕虫、挖矿什么的。
3.4.3 蜜罐主机通信的IRC服务器
在Wireshark过滤栏输入irc,能看到蜜罐主机连了3个IRC服务器:
【图12:IRC通信流量】
- 63.241.174.144(端口6667)
- 217.199.175.10(端口6667)
- 209.196.44.172(端口6667)
3.4.4 访问僵尸网络的主机数量
过滤irc && ip.addr == 209.196.44.172,看IRC服务器返回的用户列表(353响应):
【图13:IRC僵尸网络用户列表】
频道里约有15个左右的僵尸主机在线。
3.4.5 攻击蜜罐主机的IP
过滤ip.dst == 172.16.134.191 && tcp.flags.syn == 1 && tcp.flags.ack == 0,看所有主动连蜜罐的IP:
【图14:攻击蜜罐的IP】
一大堆外部IP主动扫过来,包括209.45.125.69、61.55.71.169、129.116.182.239、210.111.56.66、194.199.201.9、210.22.204.101等等,几十个。
3.4.6 攻击的安全漏洞
看目标端口:
- 端口139/445(SMB/NetBIOS):大量SMB Tree Connect请求访问\PC0191\C共享
- 端口1433(SQL Server):大量1433端口扫描
【图15:SMB攻击流量】
【图16:SQL Server扫描流量】
对应的漏洞就是Windows SMB远程代码执行漏洞、SQL Server弱口令/蠕虫。
3.4.7 成功的攻击
过滤ip.addr == 172.16.134.191 && smb,看SMB流量:
【图17:SMB攻击成功】
能看到195.36.247.77成功完成了NTLM认证,连上了IPC$管道,还访问了\samr(安全账户管理器),查询用户账户信息。
结论:攻击者195.36.247.77通过空会话/弱口令成功登录了SMB IPC$共享,拿到了用户列表,然后上传了后门程序,后门程序接着连IRC服务器209.196.44.172:6667,蜜罐就这么加入僵尸网络了。
4. 问题及解决方案
-
问题1:Kali上用upx -d脱壳失败,提示"file is modified/hacked/protected"
- 解决方案:一开始以为是命令敲错了,试了好几遍都不行。后来用readpe看节表,发现节名是JDR0/JDR1不是标准的UPX0/UPX1,才意识到作者改了节名。而且UPX!的魔术字节也被覆盖了,所以upx认不出来。最后换Windows上用万能脱壳工具才脱成功。
-
问题2:strings命令提取不到rada的关键字符串
- 解决方案:直接strings啥也没有,还以为脱壳脱坏了。后来突然想起来rada是VB写的,字符串是Unicode编码,不是ASCII,得加-e l参数。加了之后果然全出来了。这个坑之前上课听老师提过,自己实际用的时候还是忘了。
-
问题3:超级巡警虚拟机自动脱壳机脱壳失败
- 解决方案:自动脱壳机跑了半天,提示入口模拟跟踪脱壳失败。本来以为脱不了了,后来同学说试试万能脱壳工具,换了个工具果然就成了。所以说工具不能只靠一个,多试几个总没错。
-
问题4:Wireshark打开pcap后不知道怎么找攻击IP
- 解决方案:一开始流量太多了,几千个包根本看不过来。后来想起来SYN包是主动连接的第一个包,过滤
tcp.flags.syn == 1 && tcp.flags.ack == 0,Source列就是主动来连的IP,也就是攻击源。一下就清晰了。
- 解决方案:一开始流量太多了,几千个包根本看不过来。后来想起来SYN包是主动连接的第一个包,过滤
5. 学习感悟、思考等
这次实验做下来最大的感受就是,恶意代码分析真不是拿着工具点点按钮就能搞定的。刚开始拿upx脱壳脱半天脱不下来,还以为是自己哪里操作错了,反复试了好几次都不行,差点以为样本坏了。后来用readpe看节表才反应过来,这个样本就是故意被作者做了手脚——节名改了,魔术字节也改了,就是为了不让别人轻轻松松脱壳。当时就觉得,写恶意代码的人是真的精,连怎么不让别人看懂都考虑到了。
分析crackme的时候倒是挺有成就感的。IDA一开,F5一按,密码直接就显示在那行strcmp里了,比我想象的简单。特别是crackme2,还多检查了一层程序名,第一次跑的时候怎么都不对,输出"I have an identity problem",我还以为密码错了。后来盯着伪代码看了半天,才发现它先检查的是argv[0]——也就是程序自己的文件名,得改成crackmeplease.exe才行。改完名一跑,果然出Chocolate了。这种一步一步排查出问题的过程,比直接告诉你答案有意思多了。
取证分析那部分是最让我开眼界的。原来一个被攻破的Windows 2000蜜罐,五天的流量里藏了这么多东西——谁来扫过我、从哪个端口进来的、最后是怎么被攻破加入僵尸网络的,全都能从pcap里一点一点还原出来。以前上课听老师说网络攻防都是真刀真枪的,没什么概念。现在自己对着这些真实的攻击流量,看着一堆IP排着队来扫139和1433端口,才明白那些漏洞不是纸上谈兵,是真的有人在日以继夜地扫。
还有一点就是,工具只是工具,关键是你得知道工具背后的原理。就说strings命令吧,默认搜ASCII搜半天啥也没有,换成-e l搜Unicode就全出来了。如果只知道敲命令不知道为什么,遇到问题就卡住了。比如这次脱壳,要是不知道UPX的节名和魔术字节是什么,可能就一直以为是自己操作错了。以后还是得多了解底层原理,不能光当工具人。
另外就是,遇到问题别死磕一个方法。这次脱壳,Kali上upx不行、自动脱壳机也不行,本来都快放弃了,换了个万能脱壳工具就成了。工具是死的,人是活的,多试几种方法总能解决问题。
参考资料
- 《Honeynet Project Scan of The Month 32》
- 《RaDa Analysis - Chris Eagle》
- 《UPX Unpacking Tutorial》
- 《IDA Pro 反编译使用指南》