2042 字
10 分钟
2015-01-09 流量分析练习:Nuclear EK 感染链还原(含做题思路)

2015-01-09 Traffic Analysis Exercise:Nuclear EK 感染链还原#

题目来源:Malware-Traffic-Analysis.net 的 2015-01-09 练习(Windows 用户访问网站后被 EK 命中)。 本文同时给出 8 道题的答案、逐条取证过程,以及「流量分析题」的通用做题思路与操作方式。

0. 捕获概览#

项目
文件2015-01-09-traffic-analysis-exercise.pcap
包数503 个,时长约 100.7 秒
活动时间(UTC)2015-01-05 16:24:40(注意:文件名是 01-09,但流量实际发生在 1 月 5 日,别被文件名带偏)
TCP 流6 条(tcp.stream 0 ~ 5)
内网主机192.168.204.137(VMware 虚拟机,MAC 00:0c:29:9d:b8:6d)

4 个外网服务器:

主机IP角色
www.opushangszer.hu94.199.178.119被植入恶意代码的匈牙利网站(入口)
imprintchurch.org75.126.113.164被黑的跳板站,托管重定向 SWF
akronkappas.com69.65.9.55EK 跳板(指纹收集 + JS 跳转)
static.domainvertythephones.com167.160.46.121EK 本体:落地页 / 漏洞 SWF / 加密 payload

1. 感染链全貌(一次经典的 Drive-by Download)#

整个链路不到 2 分钟,受害者无感知:

① 受害者从 Google 搜索点进 www.opushangszer.hu(被植入恶意代码)
│ GET / → 响应 HTML 中藏 1x1 隐藏 Flash object
② 页面加载隐藏 SWF:imprintchurch.org/d6bc1dc7….swf(重定向器)
│ FlashVars 里硬编码了 EK 地址(含 q 参数 + base64 指纹)
③ Flash 向 akronkappas.com POST 指纹数据(ip/ua/furl,base64+加密)
│ 响应 HTML:<a id='myLink' href='http://static.domainvertythephones.com/3h251q2c35'>
│ <script>document.getElementById('myLink').click()</script>
④ 访问 EK Landing Page:static.domainvertythephones.com/3h251q2c35
│ 页面用《理智与情感》小说文本做掩护 + 大量混淆 JS
⑤ 下载恶意软件负载:242,285 字节 application/octet-stream(XOR 加密的 PE)
│ 同时下发 Flash 漏洞 SWF(CWS,40 KB)和 Silverlight XAP(含恶意 DLL)
⑥ 中招(本 pcap 截到载荷下载为止)

2. 八道题答案与取证过程#

Q1 活动日期和时间(UTC)?#

答案:2015-01-05 16:24:40

  • 第一个数据包时间戳:tshark -r xxx.pcap -T fields -e frame.time_utcJan 5, 2015 16:24:40.490562 UTC
  • 时区陷阱:本机时区为 CST(UTC+8),Wireshark 默认按本地时区显示为 Jan 6, 2015 00:24:40。用 HTTP 响应头 Date: Mon, 05 Jan 2015 16:24:40 GMT 交叉验证即可确定是 UTC 的 1 月 5 日 16:24:40。
  • 反例排除:题目文件名里的 2015-01-09 只是发布时间,不是流量时间。

Q2 受害 Windows 主机的 IP 和 MAC 地址?#

答案:192.168.204.137,00:0c:29:9d:b8:6d

  • Statistics → Conversations(或 -z conv,ip)里唯一的内网 IP 就是受害机 192.168.204.137。
  • MAC 从以太网帧取:ip.src==192.168.204.137eth.src00:0c:29:9d:b8:6d
  • 00:0c:29 是 VMware OUI,说明是虚拟机(练习环境的典型配置)。

Q3 受感染网站的域名和 IP 地址?#

答案:94.199.178.119,www.opushangszer.hu

  • 链路起点:GET / HTTP/1.1Host: www.opushangszer.hu,且 Referer: http://www.google.si/url?url=http://www.opushangszer.hu/...(经 Google 搜索进入)。
  • 响应的 HTML 里被植入 <object classid="clsid:d27cdb6e-..."> 隐藏 Flash(movie 指向 imprintchurch.org 的 swf,FlashVars 指向 EK)——这就是「受感染网站」。

Q4 漏洞利用工具包(EK)的域名和 IP 地址?#

答案:167.160.46.121,static.domainvertythephones.com

  • EK 本体是 static.domainvertythephones.com(167.160.46.121):落地页、漏洞 SWF、加密 payload 都从它下发(tcp.stream 3/4/5)。
  • static. 前缀是伪装静态资源服务器的常见手段。
  • 注意区分:akronkappas.com 只是 EK 的跳板/落地入口(收集指纹并返回跳转),不算 EK 本体。

Q5 Windows 主机使用什么浏览器?#

答案:Internet Explorer 8

  • 所有 HTTP 请求的 User-Agent:Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; ...)
  • MSIE 8.0 = IE 8;Windows NT 6.1 = Windows 7。2015 年初的 IE8 对 EK 漏洞利用几乎没有防御。

Q6 哪个 HTTP 请求返回了指向 EK 的重定向?(提交 GET 里唯一参数值)#

答案:70a9b40eb73da11445c3a3609c8241d9

  • 跳板 akronkappas.com 收到的请求: POST /d2a42e1f7d9a1021bd7d93af414c95c4.php?q=70a9b40eb73da11445c3a3609c8241d9 HTTP/1.1(Referer 是 imprintchurch.org 的 swf)。
  • 服务器响应 HTML 用 JS 自动点击 <a href='http://static.domainvertythephones.com/3h251q2c35'>——即「返回指向 EK 的重定向」。
  • 该 URL 中唯一的参数是 q,其值 70a9b40eb73da11445c3a3609c8241d9 即为答案(全流量中唯一带参数的请求)。

Q7 哪个 tcp.stream 包含恶意软件负载?#

答案:tcp.stream eq 4

  • 6 条流分工:
tcp.stream连接内容
094.199.178.119:80受感染网站页面(隐藏 Flash)
175.126.113.164:80重定向 SWF(942 B,x-flash-version 在此出现)
269.65.9.55:80Flash 指纹 POST + EK 跳转响应
3167.160.46.121:80EK Landing Page(gzip HTML + 混淆 JS + 漏洞 SWF)
4167.160.46.121:80恶意软件负载(242,285 B,application/octet-stream)
5167.160.46.121:80Silverlight XAP(ZIP:AppManifest.xaml + 恶意 DLL)
  • stream 4 的载荷:Content-Type: application/octet-stream,242,285 字节,熵高达 7.67 bit/byte,且 4 字节模式(4a ac c6 d6 出现 5395 次)重复出现——典型的 XOR 加密 PE(Nuclear EK 惯用手法,用来绕 IDS)。
  • 定位方法:http.content_type == "application/octet-stream" 找到响应帧 379,再看它所属流即可。

Q8 Windows 主机的 Flash Player 版本?#

答案:11.8.800.94

  • Flash 插件(ActiveX)在发起 SWF 请求时会带特殊头:x-flash-version: 11,8,800,94
  • 在 tcp.stream 1 请求重定向 SWF 的帧(frame 25)和 EK Landing Page 请求中都能看到。
  • 该版本是 2013 年的 Flash 11.8.800.94,存在多个已知漏洞,正是 Nuclear EK 的利用目标。

3. 做题思路与一般操作方式(方法论)#

以下是我解这道题(以及任何「流量分析 / pcap 取证」题)的通用流程:

第一步:先看整体,不要急着翻包#

Terminal window
capinfos xxx.pcap # 包数、时长、首末包时间(先看这个就能答 Q1)
tshark -r x.pcap -q -z io,phs # 协议分层:有哪些协议?有没有 HTTP/DNS/SMB/IRC…
tshark -r x.pcap -q -z conv,ip # IP 会话:谁跟谁通信、流量大小(找受害者 IP、主连接)
tshark -r x.pcap -q -z conv,tcp # TCP 会话:顺便拿到 tcp.stream 编号分布
  • 找出内网 IP(通常是唯一的一个)→ 大概率是受害主机(Q2)。
  • 找出流量最大的连接 → 往往是 payload 下载流(Q7 的候选)。
  • 首包时间戳 → Q1(注意时区,见下文)。

第二步:把 HTTP / DNS 会话全部列出来#

Terminal window
tshark -r x.pcap -Y "http.request" -T fields -e frame.number -e http.host -e http.request.uri
tshark -r x.pcap -Y "dns.flags.response==0" -T fields -e dns.qry.name | sort -u

按时间顺序读一遍请求:域名列表、URI、方法(GET/POST)。这一步基本就能答 Q3/Q4/Q5,并建立「访问顺序」的直觉。

第三步:用 Referer 链还原访问顺序(关键技巧)#

Terminal window
tshark -r x.pcap -Y "http.request" -T fields -e frame.number -e http.referer

Referer 记录了「这个请求是谁带我来的」:google.si → opushangszer.hu → imprintchurch.org(swf)→ akronkappas.com → static.domainvertythephones.com。一条 Referer 链就是完整的攻击路径(Q6 的答案往往藏在跳转那一跳里)。

第四步:Follow 关键流,看响应内容#

Terminal window
tshark -r x.pcap -q -z follow,tcp,ascii,2 # 按流号看内容
  • 看跳板/落地页的响应 HTML:找 <a>…click()</a><iframe><object>location.href 等跳转元素(Q6)。
  • 看响应头:Content-Type(octet-stream/zip/swf)、Content-Encoding(gzip)、Locationx-flash-version 等(Q8)。
  • 遇到 gzip + chunked 双编码的响应,按「解 chunked → gunzip」两步还原(我用 Python 脚本处理,见附录)。

第五步:定位并识别 payload(Q7 的核心)#

Terminal window
# 找非 HTML 的下载响应
tshark -r x.pcap -Y "http.response" -T fields -e frame.number -e http.content_type -e tcp.stream
# 看文件魔数
tshark -r x.pcap -2 -Y "frame.number==N" -T fields -e http.file_data | xxd -r -p | head -c 16 | xxd

识别文件类型:MZ=PE 可执行、CWS/FWS=Flash SWF、PK=ZIP(含 Office/ClickOnce/Silverlight XAP)、\x1f\x8b=gzip。再结合熵值(7.5+ bit/byte 通常是加密/压缩)判断是否被混淆加密。最后用 tcp.stream eq N 过滤器在 Wireshark 里隔离确认(Q7 答题格式就是 tcp.stream eq 4)。

第六步:识别 EK 家族(加分项)#

  • 落地页用小说文本/乱码掩饰(Jane Austen 文本 = Nuclear 的经典特征)。
  • POST 携带 base64 加密的 ip/ua/furl 指纹。
  • 返回 myLink + JS 自动点击跳转。
  • payload 用 XOR 加密、恶意文件为 Silverlight XAP 或 PE。
  • 这些特征组合可锁定 Nuclear Exploit Kit(2014-2015 高峰期)。

常用 Wireshark 过滤器速查#

http.request # 所有请求
http.response # 所有响应
http.host == "example.com" # 按域名
tcp.stream eq 4 # 隔离某条流(答题格式)
http.content_type contains "octet-stream" # 找二进制下载
http.referer # 追踪来源链
frame.time_utc # UTC 时间列
x-flash-version # Flash 版本(若存在)

做题时的三个常见坑#

  1. 时区:pcap 时间戳可能是 UTC 也可能是抓包机本地时区。用响应头 Date: ... GMT 与包时间比对,或用 datetime.utcfromtimestamp(ts) 统一换算(Q1 本题就是 UTC+8 显示 vs UTC 实际)。
  2. 文件名 ≠ 流量时间:发布日 ≠ 活动日(本题文件名 01-09,流量是 01-05)。
  3. gzip/chunked/编码:肉眼读不到的响应用脚本解,别直接放弃;跳转可能藏在 JS 或 Flash 变量里(如 FlashVars),不一定有 3xx 状态码。

附录:解 gzip+chunked 响应的最小脚本#

import re, gzip, subprocess
def follow_raw(stream):
out = subprocess.run(
["tshark","-r","x.pcap","-q","-z",f"follow,tcp,raw,{stream}"],
capture_output=True, text=True).stdout
hexs = [l.strip() for l in out.splitlines() if re.fullmatch(r"[0-9a-f]{40,}", l.strip())]
return bytes.fromhex("".join(hexs))
def dechunk(b):
out = b""
while b:
le = b.find(b"\r\n")
n = int(b[:le], 16)
if n == 0: return out
out += b[le+2:le+2+n]; b = b[le+2+n+2:]
return out
data = follow_raw(3)
resp = data[data.find(b"HTTP/1.1 200"):]
body = resp[resp.find(b"\r\n\r\n")+4:]
if b"chunked" in resp.lower(): body = dechunk(body)
if b"gzip" in resp.lower(): body = gzip.decompress(body)
print(body.decode("utf-8", "replace"))

参考#