來(lái)源:http://bbs.ichunqiu.com/thread-9823-1-1.html?from=ch
社區(qū):i春秋
時(shí)間:2016年8月10日
作者:MAX丶
大家肯定用過(guò)bugscan老板褲子里面經(jīng)常出現(xiàn)這個(gè)漏洞提示勺三。
【xxx存在http.sys遠(yuǎn)程漏洞】今天我們來(lái)分析分析這漏洞如何存在的,據(jù)稱(chēng),利用HTTP.sys的安全漏洞,攻擊者只需要發(fā)送惡意的http請(qǐng)求數(shù)據(jù)包兆解,就可能遠(yuǎn)程讀取IIS服務(wù)器的內(nèi)存數(shù)據(jù),或使服務(wù)器系統(tǒng)藍(lán)屏崩潰莱睁。
根據(jù)公告顯示痕支,該漏洞對(duì)服務(wù)器系統(tǒng)造成了不小的影響颁虐,主要影響了包括Windows 7、Windows Server 2008 R2卧须、Windows 8另绩、Windows Server 2012、Windows 8.1 和 Windows Server 2012 R2在內(nèi)的主流服務(wù)器操作系統(tǒng)花嘶。
1. 首先對(duì)補(bǔ)丁文件做了二進(jìn)制比對(duì)
以下是Windows 7 修復(fù)前后HTTP.SYS的變化笋籽。
值得注意的經(jīng)驗(yàn)是,每個(gè)函數(shù)名中都有’range’椭员。 這不禁讓我想起了之前Apache HTTPd ‘Range’ 頭漏洞, (參見(jiàn)RFC2616章14.35節(jié))车海。
漏洞數(shù)據(jù)由 ‘range’ 頭帶入已經(jīng)毋庸置疑。 下面要做的是深入研究其產(chǎn)生的原因拆撼。如IDA 自動(dòng)分析出的的HTTP!UlpParseRange 函數(shù)的調(diào)用關(guān)系圖所示:
這里我使用Vmware搭建了一個(gè)未打補(bǔ)丁的Windows 7 SP1 作為測(cè)試目標(biāo)容劳,并且啟用了內(nèi)核調(diào)試器, 對(duì)所有關(guān)鍵函數(shù)設(shè)置斷點(diǎn)喘沿,收集關(guān)鍵數(shù)據(jù)和內(nèi)核信息闸度。
在斷點(diǎn)被觸發(fā)之后, 堆棧信息會(huì)被打印出來(lái), 接著程序繼續(xù)執(zhí)行.??我們使用了之前的Apache Rangedos 測(cè)試樣本針對(duì)目標(biāo)服務(wù)器做了攻擊性測(cè)試, 調(diào)試器捕獲到了下面這些信息:
標(biāo)準(zhǔn)的Apache RangeDos 腳本確實(shí)產(chǎn)生了效果,下面讓我們更進(jìn)一步的來(lái)看一下 HTTP!UlpParseRange 函數(shù)的實(shí)現(xiàn):
在舊代碼的調(diào)試中發(fā)現(xiàn)函數(shù)在此處調(diào)用了一個(gè)很大的整數(shù)蚜印。
而新版本的代碼調(diào)用了HTTP!RtlULongLongAdd 來(lái)檢查是否有整數(shù)溢出莺禁。 注意,這個(gè)HTTP.sys內(nèi)的函數(shù)調(diào)用5個(gè)參數(shù)而不是3個(gè)參數(shù)窄赋。重復(fù)之前的測(cè)試腳本, 就會(huì)發(fā)現(xiàn)系統(tǒng)返回的錯(cuò)誤代碼是0xC000000D(STATUS_INVALID_PARAMETER)哟冬,而不再是STATUS_INTEGER_OVERFLOW 。
修正之后的一個(gè)簡(jiǎn)單的POC測(cè)試腳本如下(此腳本僅用來(lái)解析證明模塊內(nèi)部對(duì)Range頭參數(shù)的解析過(guò)程)忆绰。
接著讓我們?cè)谖创蜓a(bǔ)丁的模塊上下斷點(diǎn)浩峡。
非常明顯了。EAX 是0x7A69 (Poc中設(shè)置的range上限 31337), EDI 是0x539(Poc中設(shè)置的range下限 1337)错敢。 在老代碼中翰灾,如果我們的下限是0缕粹,則上限不會(huì)做如此的改變。在上限非常大的時(shí)候(整數(shù)臨界值), 我們加1, 就會(huì)發(fā)生整數(shù)溢出纸淮。 HexRays 的輸出更加明了:
*(_QWORD *)v18 = __PAIR__(v22, v23) – __PAIR__(v21, v20) + 1.讓我們來(lái)試試看平斩。
這時(shí)候可以看到上限已經(jīng)非常的大了(0xFFFFFFFF)招驴。代碼接著執(zhí)行毁习。
We can see that EAX is predictably small now.??Now that we have some indication of what the pre-patch block is doing, let’s look at the patch again.
最后EAX在加1之后溢出變成了0. 讓我們?cè)倏纯创蜻^(guò)補(bǔ)丁的模塊:
使用同樣的手法, 我們得到了一個(gè)不同的錯(cuò)誤信息. 有趣的是很多情況下都會(huì)產(chǎn)生這個(gè)錯(cuò)誤信息(比如節(jié)點(diǎn)深度問(wèn)題等)婚陪。但是我們的主要目標(biāo)是判斷是否打補(bǔ)丁, 所以這個(gè)沒(méi)什么大礙. 現(xiàn)在讓我們回到系統(tǒng)是否打補(bǔ)丁的預(yù)判上.
一種方法讓未打補(bǔ)丁的模塊返回STATUS_INVALID_PARAMETER錯(cuò)誤信息的方法就是使下面代碼的關(guān)鍵處校驗(yàn)失敗贰军。
使用調(diào)試器動(dòng)態(tài)改變跳轉(zhuǎn)條件, 我們可以讓服務(wù)器返回下面這個(gè)有趣的頁(yè)面(手工內(nèi)存補(bǔ)丁成功):
打完補(bǔ)丁以后當(dāng)你提交了包含非法range頭字段的http包的時(shí)候, 系統(tǒng)會(huì)報(bào)上面的錯(cuò)誤爽冕。
如果沒(méi)打補(bǔ)丁你看到的就是下面這樣:
這就是判斷是否打了補(bǔ)丁的關(guān)鍵.
打了補(bǔ)丁:??HTTP!RtlULongLongAdd在遇到非法range頭的時(shí)候會(huì)返回一個(gè) STATUS_INVALID_PARAMETER 錯(cuò)誤, 接著HTTP!UlpParseRang 產(chǎn)生一個(gè)”Invalid Header” 錯(cuò)誤信息給客戶(hù)端.
打了補(bǔ)丁:??HTTP!UlpParseRange 返回 0, 接著產(chǎn)生一個(gè) “Requested Range Not Satisfiable”.錯(cuò)誤信息給客戶(hù)端.
下面給大家發(fā)一個(gè)檢測(cè)py腳本堤撵。
[Python]純文本查看復(fù)制代碼
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52importsocket
importrandom[/font][/color][/size]
[size=4][color=Red][font=微軟雅黑]
ipAddr="這里填入檢測(cè)IP地址"
hexAllFfff="18446744073709551615"
req1="GET / HTTP/1.0\r\n\r\n"
req="GET / HTTP/1.1\r\nHost: stuff\r\nRange: bytes=0-"+hexAllFfff+"\r\n\r\n"
print" Audit Started"
client_socket=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((ipAddr,80))
client_socket.send(req1)
boringResp=client_socket.recv(1024)
if"Microsoft"notinboringResp:
print" Not IIS"
exit(0)
client_socket.close()
client_socket=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((ipAddr,80))
client_socket.send(req)
goodResp=client_socket.recv(1024)
if"Requested Range Not Satisfiable"ingoodResp:
print"[!!] Looks VULN"
elif" The request has an invalid header name"ingoodResp:
print" Looks Patched"
else:
print"[/font][/color][color=Red][font=微軟雅黑] Unexpected response, cannot discern patch status"