前言
虽然我在若干年前打 CTF 的时候已经做过一些流量分析题,但都是非常简单的题目,例如:
- 给定一个 pcap 文件,找到其中的 flag:一般来说直接打开 WireShark 搜索即可。
- 给定一个 pcap 文件,找到其中的某个文件:WireShark 菜单的
File -> Export Objects可以直接导出 HTTP、FTP 等协议的文件。
但你们也能看出来,由于我的主业不是安全,这博客就好久没有写安全类的文章了,我自然也没有机会接触到更难的流量分析题目了。
面临挑战
前几天跟朋友去爬山,他提到了一个题目,是一个 pcap 的流量分析。乍听起来好像很简单:
一个公司发现有重要文件被盗,但员工没有使用任何 USB 等设备,所以文件一定是通过网络被盗的。幸运的是,他们有当天的网络流量文件(2.pcap)。作为网络取证专家,你能帮助他们找到以下信息吗?
- 攻击者的 IP 地址?你是如何找到的?
- 被盗文件的 MD5 哈希值是多少?文件类型是什么?
- 文件被盗的时间是什么?
在山上,朋友说:这题只要用 WireShark 打开文件,然后用 File -> Export Objects -> FTP Data 导出文件,就能找到被盗的文件了。

在 WireShark 中过滤出所有的 FTP 流量,发现 172.29.1.23 试图登录 FTP 服务器,那么目标 172.29.1.21 一定是那台“服务器”,一定是“攻击者”从“服务器”上下载了文件。
将其保存成 Employee_Information.xls,这是个 Excel 文件(从文件头的 d0 cf 11 e0 也能直接看出来),可以用 Excel 打开。随便 md5sum 一下就能得到结果了。

至于时间,在“攻击者”试图登录 FTP 后,有一个来自 172.29.1.23 的 Syslog:Mon Jul 14 14:14:15 2014 ... A new process has been created. 这可以作为我们的时间线索。这两条记录的时间差大约有 2 秒,所以文件被盗的时间应该是 14:14:13……
……
……吗?
有些不对劲
聪明的你可能已经猜到了,从最开始我们的判断就已经错了——将 FTP 流量都过滤出来后,我们发现“攻击者”执行的命令实际上是 STOR 上传文件,而不是 RETR 下载文件。攻击者没有理由上传一个 Excel 到服务器上啊!看来得好好分析,不能偷懒了。
包里都有哪些协议?
通过 WireShark 的 Statistics -> Protocol Hierarchy,我们可以看到这个 pcap 文件中有哪些协议,以及它们所占的比例:

看起来可疑的协议不多:
- FTP:刚才分析过了,不是下载文件。
- SMB:只是个 Lanman 协议,不太可能是文件传输。
- HTTP:这个协议的流量比例很大,可以再仔细看看。
- TLS:这个协议的流量比例也不小,可能有加密的文件传输。
HTTP 协议分析
先分析最简单的 HTTP 协议。通过 WireShark 的 Statistics -> HTTP -> Request Sequences,我们可以看到 HTTP 请求的序列:

不过并没有什么有意思的东西,看起来先 Google 搜索了 http://www.wireshark.org/、打开了它(加载了好多静态资源),然后又搜索了 http://Lmgsecurity.com/blog/ 并且打开了它,然后跳回了 Google 首页,最后是两个 AOL 邮箱自动收信的请求。看来只能考虑分析 TLS 协议了。
TLS 协议分析
TLS 协议是加密的,我们无法直接看到内容,如果不知道证书的话很难破解。虽然朋友找到了 pcap 中的一些 OCSP 请求,“但这只是一道普通的流量分析题啊,至于那么麻烦?”我心想,没有继续这条路。

那该怎么办呢?机智如我想到了通过 SNI 来分析。在 WireShark 的搜索框里输入 tls.handshake.type == 1 过滤出所有 Client Hello 包(期望这道题没有用 ECH),发现似乎也没什么特别的,都是 Google、新闻站 blackhat.com、垃圾站 2o7.net:

普通的 TCP 协议
还有什么协议可以分析呢?从前文的协议比例中可以发现,还有很多普通的 TCP 协议我们没有分析。通过 WireShark 的 Statistics -> Conversations,我们可以看到所有的 TCP 会话。按照 Bytes 降序排列,可以发现第一名是到 blackhat.com 的 HTTPS 流量,第二名是到 172.29.1.21 的……krb524 流量?

通过 tcp.stream eq 30 过滤出相关流量,并 Follow TCP Stream,我看到了一个很熟悉的文件头 4d 5a,以及一个刻在 DNA 里的字符串 This program cannot be run in DOS mode:

需要把流量保存下来。在命令行执行 tshark -r 2.pcap -Y "tcp.stream eq 30 && tcp.len > 0" -T fields -e data > output.raw 可以将其保存为 ASCII 文件(里面是十六进制的字符串)。删掉第一行看起来是协议头的东西,然后用 xxd -r -p output.raw > output.exe 就能得到一个可执行文件了。
可执行文件分析
使用 IDA 打开它,发现它里面有 501 个函数,没有符号表,并且 .rdata、.text 等段都无法被自动解析,很显然不是个正常程序。出题人为了一个流量分析的题目如此大费周折,实在是让人难以理解。

由于二进制不是我的强项,于是我们求助了一位专搞二进制的大佬,然后发现这个程序是个 Meterpreter 生成的远程控制程序……
- 朋友:难道我真猜对了是远控?
- 大佬:你猜对了。
- 朋友:为啥我的联想电脑管家没报毒?
- 大佬:他是 Meterpreter 生成的。
- 朋友:这怎么看出来的?
- 大佬:Windows defender 说的。
- 我:……

根据我对 metepreter 的了解,它生成的远程控制程序通常会使用 4444 端口,只不过被 WireShark 识别成了 Kerberos 524 而已。我又完整看了这个 TCP 流:
- 首先是普通的 TCP 三次握手。
- 之后的第一个包(刚才怀疑是协议头的东西)只有 4 字节
00 be 0b 00,可能就是开始传递文件的命令。 - 后面一系列包都是单向传递文件。
- 最后是双方频繁互相通信,往来的消息体都以
17 03 00 00开头,应该就是命令和响应。但由于这段流量是加密的,且题目没有提供内核转储文件,所以我们无法拿到 Meterpreter 的 AES key,无法解密。
在双方互相通信的过程中,夹杂了 FTP 协议,看起来是攻击者控制受害者上传文件。
意料之外的结论
我们一开始都以为 172.29.1.21 是服务器、172.29.1.23 是攻击者,这跟我们日常的经验比较相符(IP 最后一位是 1 的设备通常是网关),但实际上刚好相反。攻击者(172.29.1.21)先通过早已建立的通道传了一个 Meterpreter 生成的远程控制程序给受害者(172.29.1.23),然后控制受害者通过 FTP 协议将文件上传给了攻击者。
虽然最开始我们没能很好地还原现场,不过误打误撞,至少被偷走的文件我们判断正确了。看起来这道题在 CTF 里面不止要 200 分,可能至少得 300 分。
还没完——对时间的分析
第二天朋友又找到我,说我们没有注意到时间可能有问题。Syslog 内容里记录的时间,跟 ETH 报文被捕获的时间,有很大的误差(不是时区问题)。

该相信哪一个呢?理论上来说,Syslog 的时间是受害者机器的时间,ETH 报文的时间是抓包机器的时间,都可能会被误差影响。机智如我又突然想到,不是有人访问过 Google 吗?Google 的时间是不是可以作为一个参考呢?于是我又找到 Google 的请求:

- Google 响应体的
Date头是正确时间的20:12:52,相对时间是62.557605。(注意到 ETH 报文的时间是20:25:24,抓包机器的时间也快了 12 分 32 秒。) - 4096(请求包)~4097(响应包)的时间差是这次请求的 TTFB,只有 63 毫秒,可以认为 Google 服务器延迟导致的误差可忽略。
- 得出结论:偷窃开始(第一个 FTP Data)时间是相对时间
209.463818,也就是 Google 响应的 2 分 26 秒后,也就是正确时间20:15:18;整个偷窃过程在 3 毫秒内完成。 - 使用 wireshark.com 的请求也可以得出相同的结论。考虑到 Google 和 WireShark 的服务器时间不可能同时被篡改,这个结果的可信度非常高。
尾声
真真假假,假假真真。这道题以它的反直觉性和复杂性,让我学会了在流量分析中不要过于依赖直觉,要多方面考虑。以及任何蛛丝马迹都可能是线索,不要放过任何一个细节。
体内的 CTF 基因动了,CTF 简直太好玩了……