HTTP.SYS遠程執(zhí)行代碼漏洞分析 (MS15-034 )

來源:http://bbs.ichunqiu.com/thread-9823-1-1.html?from=ch

社區(qū):i春秋

時間:2016年8月10日

作者:MAX丶

大家肯定用過bugscan老板褲子里面經常出現這個漏洞提示。

【xxx存在http.sys遠程漏洞】今天我們來分析分析這漏洞如何存在的,據稱,利用HTTP.sys的安全漏洞,攻擊者只需要發(fā)送惡意的http請求數據包,就可能遠程讀取IIS服務器的內存數據,或使服務器系統(tǒng)藍屏崩潰。

根據公告顯示,該漏洞對服務器系統(tǒng)造成了不小的影響,主要影響了包括Windows 7、Windows Server 2008 R2、Windows 8、Windows Server 2012、Windows 8.1 和 Windows Server 2012 R2在內的主流服務器操作系統(tǒng)。

1. 首先對補丁文件做了二進制比對

以下是Windows 7 修復前后HTTP.SYS的變化。

值得注意的經驗是,每個函數名中都有’range’。 這不禁讓我想起了之前Apache HTTPd ‘Range’ 頭漏洞, (參見RFC2616章14.35節(jié))。

漏洞數據由 ‘range’ 頭帶入已經毋庸置疑。 下面要做的是深入研究其產生的原因。如IDA 自動分析出的的HTTP!UlpParseRange 函數的調用關系圖所示:

這里我使用Vmware搭建了一個未打補丁的Windows 7 SP1 作為測試目標,并且啟用了內核調試器, 對所有關鍵函數設置斷點,收集關鍵數據和內核信息。

在斷點被觸發(fā)之后, 堆棧信息會被打印出來, 接著程序繼續(xù)執(zhí)行.??我們使用了之前的Apache Rangedos 測試樣本針對目標服務器做了攻擊性測試, 調試器捕獲到了下面這些信息:

標準的Apache RangeDos 腳本確實產生了效果,下面讓我們更進一步的來看一下 HTTP!UlpParseRange 函數的實現:

在舊代碼的調試中發(fā)現函數在此處調用了一個很大的整數。

而新版本的代碼調用了HTTP!RtlULongLongAdd 來檢查是否有整數溢出。 注意,這個HTTP.sys內的函數調用5個參數而不是3個參數。重復之前的測試腳本, 就會發(fā)現系統(tǒng)返回的錯誤代碼是0xC000000D(STATUS_INVALID_PARAMETER),而不再是STATUS_INTEGER_OVERFLOW 。

修正之后的一個簡單的POC測試腳本如下(此腳本僅用來解析證明模塊內部對Range頭參數的解析過程)。

接著讓我們在未打補丁的模塊上下斷點。

非常明顯了。EAX 是0x7A69 (Poc中設置的range上限 31337), EDI 是0x539(Poc中設置的range下限 1337)。 在老代碼中,如果我們的下限是0,則上限不會做如此的改變。在上限非常大的時候(整數臨界值), 我們加1, 就會發(fā)生整數溢出。 HexRays 的輸出更加明了:

*(_QWORD *)v18 = __PAIR__(v22, v23) – __PAIR__(v21, v20) + 1.讓我們來試試看。

這時候可以看到上限已經非常的大了(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. 讓我們再看看打過補丁的模塊:

使用同樣的手法, 我們得到了一個不同的錯誤信息. 有趣的是很多情況下都會產生這個錯誤信息(比如節(jié)點深度問題等)。但是我們的主要目標是判斷是否打補丁, 所以這個沒什么大礙. 現在讓我們回到系統(tǒng)是否打補丁的預判上.

一種方法讓未打補丁的模塊返回STATUS_INVALID_PARAMETER錯誤信息的方法就是使下面代碼的關鍵處校驗失敗。

使用調試器動態(tài)改變跳轉條件, 我們可以讓服務器返回下面這個有趣的頁面(手工內存補丁成功):

打完補丁以后當你提交了包含非法range頭字段的http包的時候, 系統(tǒng)會報上面的錯誤。

如果沒打補丁你看到的就是下面這樣:

這就是判斷是否打了補丁的關鍵.

打了補丁:??HTTP!RtlULongLongAdd在遇到非法range頭的時候會返回一個 STATUS_INVALID_PARAMETER 錯誤, 接著HTTP!UlpParseRang 產生一個”Invalid Header” 錯誤信息給客戶端.

打了補丁:??HTTP!UlpParseRange 返回 0, 接著產生一個 “Requested Range Not Satisfiable”.錯誤信息給客戶端.

下面給大家發(fā)一個檢測py腳本。

[Python]純文本查看復制代碼

?

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="這里填入檢測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"

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現,斷路器,智...
    卡卡羅2017閱讀 136,533評論 19 139
  • 背景: 閱讀新聞 12C CDB模式下RMAN備份與恢復 [日期:2016-11-29] 來源:Linux社區(qū) 作...
    陽屯okyepd閱讀 3,828評論 0 7
  • http://python.jobbole.com/85231/ 關于專業(yè)技能寫完項目接著寫寫一名3年工作經驗的J...
    燕京博士閱讀 7,791評論 1 118
  • 1、TCP狀態(tài)linux查看tcp的狀態(tài)命令:1)、netstat -nat 查看TCP各個狀態(tài)的數量2)、lso...
    北辰青閱讀 9,702評論 0 11
  • 我說了 讓我為你寫詩 在我動手寫的剎那 才發(fā)現 這一切早已在心底 靜靜的躺在那 只是在等待 遇見你 而蘇醒 這些文...
    上官南929閱讀 203評論 0 6

友情鏈接更多精彩內容