今天想填一个遗留了挺长时间的问题。之前总会被客户问到产品中关于MS17-010的告警到底准不准?攻击结果显示成功是真的成功了吗?因为告警相关的规则也不可能是我们现场研判人员写的,所以被问到的时候总是含糊其辞,无法给出令人信服的答案。我一直很想弄明白MS17-010的告警到底是怎么检测的?又该怎么判断攻击成功?于是有了这篇文章,希望可以帮助到和我一样存在这个问题的人。
我的二进制分析能力几乎为0,所以这里不涉及对于漏洞分析和漏洞利用相关的内容。我们通过MS17-010漏洞利用过程中产生的网络流量,提取相关特征进行检测。
从攻击角度看,我们首先需要知道目标主机是否存在MS17-010漏洞,这需要用到一些漏洞扫描工具,此处我参考了nmap、Metasploit和fscan三款工具的检测代码。
nmap的脚本库中smb-vuln-ms17-010代码片段:
Metasploit中/auxiliary/scanner/smb/smb_ms17_010.rb代码片段:
fscan中Plugins/ms17010.go代码片段:
通过查看源代码,我们可以知道扫描工具其实检测的是目标主机是否打了MS17-010的补丁,现在我们看一下wireshark抓到的数据包中的特征。
观察数据包可知,攻击者通过向目标主机发送PeekNamedPipe请求,返回响应是否包含"STATUS_INSUFF_SERVER_RESOURCES"(0xc0000205)进行判断。通过对比三款工具发出的请求,我们甚至可以直接区分出攻击是哪个工具产生的:
nmap扫描特征,SMB请求用户为WIN7\guest
Metasploit扫描特征,SMB请求用户为".\"
fscan扫描特征,SMB请求用户为"anonymous"
根据PeekNamedPipe请求特征,我们可以编写自定义规则,而在Suricata中,已经可以检测MS17-010的扫描行为,规则如下:
alert smb $HOME_NET any -> any any (
msg:"ET EXPLOIT ETERNALBLUE Probe Vulnerable System Response MS17-010";
flow:from_server,established;
content:"|ff|SMB|25 05 02 00 c0 98 01|"; offset:4; depth:11;
content:"|00 00 00 00 00 00 00 00 00 00|"; distance:3; within:10;
content:"|00 00 00|"; distance:8; within:3; endswith; threshold: type limit, track by_src, count 1, seconds 30;
reference:url,github.com/rapid7/metasploit-framework/blob/master/modules/auxiliary/scanner/smb/smb_ms17_010.rb;
classtype:trojan-activity;
sid:2025650;
rev:3;
metadata:affected_product Windows_XP_Vista_7_8_10_Server_32_64_Bit, attack_target Client_Endpoint, created_at 2018_07_11, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Metasploit, tag ETERNALBLUE, updated_at 2019_09_28;
)
根据上述特征,我们可以通过被攻击IP返回的Trans Response错误来判断攻击是否成功。前提条件是告警探针保留了完整的pcap包。
所有的远程缓冲区溢出攻击都会向目标主机发送大量的垃圾数据,而除此之外还需要根据溢出位置插入代码来触发shellcode。通过观察Metasploit发出的攻击请求,可以发现大量的A(0x41)攻击特征非常明显。
与扫描攻击类似的思路,我们查看Metasploit的攻击组件代码,可发现一些固定发包特征:
我们可以根据代码中的特征编写自定义规则,以下提供Suricata内置规则:
alert tcp any any -> any 445 (
msg:"ET EXPLOIT ETERNALBLUE Exploit M2 MS17-010";
flow:established,to_server;
content:"|8000a80000000000000000000000000000000000ffff000000000000ffff0000000000000000000000000000000000000000000000f1dfff000000000000000020f0dfff00f1dfffffffffff600004100000000080efdfff|";
reference:cve,CVE-2017-0143;
classtype:attempted-admin;
sid:2024297;
rev:2;
metadata:affected_product Windows_XP_Vista_7_8_10_Server_32_64_Bit, attack_target Client_Endpoint, created_at 2017_05_16, deployment Perimeter, former_category CURRENT_EVENTS, performance_impact Low, signature_severity Major, updated_at 2017_07_06;
)
其实从扫描攻击的响应包,我们就可以研判攻击成功了,除此之外我们还可以根据被攻击主机的其他行为判断攻击成功。例如Metasploit攻击成功后会进行ReverseTCPShell通信,触发Suricata 规则"SURICATA Applayer Protocol detection skipped"
{
"timestamp": "2023-02-05T11:03:48.068938+0000",
"flow_id": 1755157932219933,
"in_iface": "enp0s8",
"event_type": "alert",
"src_ip": "192.168.56.101",
"src_port": 49157,
"dest_ip": "192.168.56.102",
"dest_port": 4444,
"proto": "TCP",
"metadata": {
"flowints": {
"applayer.anomaly.count": 1
}
},
"alert": {
"action": "allowed",
"gid": 1,
"signature_id": 2260003,
"rev": 1,
"signature": "SURICATA Applayer Protocol detection skipped",
"category": "Generic Protocol Command Decode",
"severity": 3
},
"app_proto": "failed",
"flow": {
"pkts_toserver": 8,
"pkts_toclient": 77,
"bytes_toserver": 486,
"bytes_toclient": 113674,
"start": "2023-02-05T11:03:47.859677+0000"
},
"payload": "",
"stream": 0
}
本文中所有Pcap包均可在Github仓库中找到:
https://github.com/safest-place/ExploitPcapCollection