学号 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. 实验内容

  1. 对rada恶意代码样本进行文件类型识别、脱壳与字符串提取,找到编写作者
  2. 使用IDA Pro静态分析crackme1.exe与crackme2.exe,寻找特定输入使其输出成功信息
  3. 分析rada恶意代码样本,回答8个深度分析问题
  4. 分析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 二进制文件的特性

  1. Visual Basic编写:依赖MSVBVM60.DLL,所以字符串都是Unicode编码
  2. HTTP命令控制:通过Internet Explorer控件下载HTML格式的命令文件
  3. 注册表自启动:写HKLM\Software\Microsoft\Windows\CurrentVersion\Run\键
  4. 命令行参数丰富:支持--authors、--uninstall、--noinstall、--period等参数
  5. 私有网段限制:命令服务器必须在私有子网(10.x.x.x、172.16.x.x、192.168.x.x),防止被公网反向利用

3.3.4 防止被分析的技术

  1. UPX加壳:压缩代码和数据,静态分析看不到原始字符串
  2. 节名篡改:把UPX0/UPX1节名改成JDR0/JDR1(作者名字Raul Siles & David Perez的首字母),阻止UPX自动脱壳
  3. UPX!标志覆盖:把UPX头部的魔术字节覆盖成"!This program is the binary of SotM 32..",导致自动脱壳工具认不出来
  4. 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 相似功能的其他工具

  1. Back Orifice:90年代经典的Windows后门工具, Cult of the Dead Cow出的
  2. NetBus:远程控制木马,当年很有名
  3. Sub7:功能比NetBus还强的后门工具
  4. Gh0st(幽灵):国产远控木马,国内用得很多
  5. PoisonIvy(火焰):广泛使用的远控木马,很多APT组织用过

3.3.7 能否调查出作者

可以。 条件就是脱壳之后直接在二进制里搜字符串,就能找到版权信息"Copyright (C) 2004 Raul Siles & David Perez"。这俩人是Honeynet Project的安全研究人员,这个样本就是他们公开出来做安全竞赛用的。分析的时候在隔离的虚拟机里跑就行,没什么难度。

3.3.8 检测该恶意软件的5种方法

  1. 基于特征码检测:把脱壳后文件里的特定字节序列提取出来当特征码,杀毒软件匹配到就报毒
  2. 基于哈希检测:算文件的MD5或SHA1哈希,跟已知恶意样本哈希库比对(比如这个样本MD5是caaa6985a43225a0b3add54f44a0d4c7)
  3. 基于行为检测:监控程序是不是写注册表Run键自启动、是不是创建C:\RaDa\目录、是不是调用Internet Explorer下载文件
  4. 基于网络流量检测:检测异常的HTTP流量,特别是访问私有网段IP地址的HTTP请求,还有上传下载文件的流量模式
  5. 基于沙箱动态检测:在隔离环境里跑一下样本,看它是不是检测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通信流量】

  1. 63.241.174.144(端口6667)
  2. 217.199.175.10(端口6667)
  3. 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,也就是攻击源。一下就清晰了。

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 反编译使用指南》