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.hu | 94.199.178.119 | 被植入恶意代码的匈牙利网站(入口) |
| imprintchurch.org | 75.126.113.164 | 被黑的跳板站,托管重定向 SWF |
| akronkappas.com | 69.65.9.55 | EK 跳板(指纹收集 + JS 跳转) |
| static.domainvertythephones.com | 167.160.46.121 | EK 本体:落地页 / 漏洞 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_utc→Jan 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.137的eth.src→00:0c:29:9d:b8:6d。 00:0c:29是 VMware OUI,说明是虚拟机(练习环境的典型配置)。
Q3 受感染网站的域名和 IP 地址?
答案:94.199.178.119,www.opushangszer.hu
- 链路起点:
GET / HTTP/1.1,Host: 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 | 连接 | 内容 |
|---|---|---|
| 0 | 94.199.178.119:80 | 受感染网站页面(隐藏 Flash) |
| 1 | 75.126.113.164:80 | 重定向 SWF(942 B,x-flash-version 在此出现) |
| 2 | 69.65.9.55:80 | Flash 指纹 POST + EK 跳转响应 |
| 3 | 167.160.46.121:80 | EK Landing Page(gzip HTML + 混淆 JS + 漏洞 SWF) |
| 4 | 167.160.46.121:80 | 恶意软件负载(242,285 B,application/octet-stream) |
| 5 | 167.160.46.121:80 | Silverlight 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 取证」题)的通用流程:
第一步:先看整体,不要急着翻包
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 会话全部列出来
tshark -r x.pcap -Y "http.request" -T fields -e frame.number -e http.host -e http.request.uritshark -r x.pcap -Y "dns.flags.response==0" -T fields -e dns.qry.name | sort -u按时间顺序读一遍请求:域名列表、URI、方法(GET/POST)。这一步基本就能答 Q3/Q4/Q5,并建立「访问顺序」的直觉。
第三步:用 Referer 链还原访问顺序(关键技巧)
tshark -r x.pcap -Y "http.request" -T fields -e frame.number -e http.refererReferer 记录了「这个请求是谁带我来的」:google.si → opushangszer.hu → imprintchurch.org(swf)→ akronkappas.com → static.domainvertythephones.com。一条 Referer 链就是完整的攻击路径(Q6 的答案往往藏在跳转那一跳里)。
第四步:Follow 关键流,看响应内容
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)、Location、x-flash-version等(Q8)。 - 遇到 gzip + chunked 双编码的响应,按「解 chunked → gunzip」两步还原(我用 Python 脚本处理,见附录)。
第五步:定位并识别 payload(Q7 的核心)
# 找非 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 版本(若存在)做题时的三个常见坑
- 时区:pcap 时间戳可能是 UTC 也可能是抓包机本地时区。用响应头
Date: ... GMT与包时间比对,或用datetime.utcfromtimestamp(ts)统一换算(Q1 本题就是 UTC+8 显示 vs UTC 实际)。 - 文件名 ≠ 流量时间:发布日 ≠ 活动日(本题文件名 01-09,流量是 01-05)。
- 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"))