譯者:xd0ol1 (知道創宇404安全實驗室)
原文鏈接:https://labs.bluefrostsecurity.de/files/Look_Mom_I_Dont_Use_Shellcode-WP.pdf
接上篇,這里為后3部分的翻譯,不對之處還望多多指正。
4 沙箱逃逸
默認情況下,Windows 10系統中的Internet Explorer 11并未啟用增強保護模式(EPM),而我們的目標是要在最高級別的安全設置下進行漏洞利用,因此在設置中我們手動啟用增強保護模式和增強保護模式的64位進程這兩項。

在完成上述更改后,我們的payload將在受限的AppContainer沙箱中運行。為了能對系統進行更改,我們需要找到一種突破沙箱的方式,這樣才能以更高的Integrity Level(Medium IL或以上)來執行代碼。
4.1 關于Internet Explorer里的Zone
在Internet Explorer中有個zone的概念,不同的安全設置對應于不同的zone,其中,Internet上的頁面通常在Internet Zone里進行渲染,而本地內網上的頁面則在Local Intranet Zone里進行渲染。
這里需要注意一點,即便你手動啟用了EPM,但Local Intranet Zone中卻不會啟用EPM,也就意味著在Local Intranet Zone里渲染的網頁是由沙箱外的32位Medium IL進程來加載的。
此性質已是人盡皆知了,過去也曾被多次用于繞過Internet Explorer下的保護模式[9][10]。這些攻擊首先會從沙箱進程內啟用一個本地Web服務,然后讓瀏覽器訪問http://localhost/并再次執行這個exploit,此時頁面渲染就會由沙箱外的Medium IL進程來完成。
但是微軟并不決定修復這個問題,而是建議用戶啟用EPM來防止沙箱逃逸[11]。啟用EPM后,渲染過程將在擁有網絡隔離功能的AppContainer沙箱內運行[12],特別的,它能阻止沙箱進程和本地機器建立連接并且阻止它接受新的網絡連接,這就成功解決了前面所描述的攻擊形式。
另一方面,在執行這種攻擊時,我們可以不必局限于localhost域名,如果我們能設法將被認為是Local Intranet Zone中的域名解析到外部的Web服務器地址,那么我們還是能在AppContainer沙箱外以Medium IL進行頁面的渲染。Internet Explorer基于許多規則來判斷站點是否屬于Local Intranet Zone[13],其中有個PlainHostName規則,也就是如果域名中不包含任何句點,那么它將被自動映射到Local Intranet Zone上。
所以問題就變成如何在沙箱進程內注冊一個不含任何句點的且解析到外部IP地址的域名信息,事實證明這能通過本地NetBIOS Spoofing技術來實現。
4.2 NetBIOS Spoofing
NetBIOS Name Service (NBNS) 協議是Windows系統上進行名稱解析的UDP廣播協議。通常程序在進行域名解析時會用到DNS協議,但如果由于某些原因導致DNS查詢失敗,那么系統就會嘗試使用NBNS協議來進行解析。
而NetBIOS Spoofing則是一種常見的網絡攻擊方式,當然,在Hot Potato Exploit[14]中它也被用來進行Windows系統的本地權限提升。
另外注意一點,NBNS數據包中的Transaction ID(TXID)字段將用于保證請求包和響應包的正確匹配,其中,域名“BLUEFROST”對應的NBNS請求包如下:

在典型的NBNS Spoofing期間,攻擊者將響應本地網絡上接收到的任何NBNS請求,由于此過程中初始的NBNS請求包信息是不可見的,因此我們無法獲知使用的16位TXID,但是我們可以通過快速迭代來遍歷可能的65536個TXID值,并最終猜測出正確結果。
正如前面所述,AppContainer的網絡隔離功能將阻止沙箱進程向本地機器發送數據包,但事實證明這個規則是有例外情況的,比如沙箱進程仍然能向本地的137端口發送UDP數據,這就使得在沙箱進程內進行本地NBNS Spoofing成為可能。
因此,我們首先借助本地NBNS Spoofing注冊一個不含任何句點且解析到我們外部Web服務器IP的域名信息。之后,我們通過瀏覽器訪問新注冊的域名,即我們的Web服務器,雖然此Web服務器位于Internet上的某個地方,但渲染的頁面現在卻被認為是位于Local Intranet Zone中的,因此渲染進程將會在沙箱外運行。而后,我們再次觸發exploit,這次就會由沙箱外的32位渲染進程以Medium IL來執行代碼。

上面的截圖顯示我們成功在沙箱外以Medium IL創建了一個新的notepad.exe進程。
5 禁用EMET保護
對于特定EMET保護的繞過或直接完全禁用EMET的研究在過去已經有很多了,相關文章的鏈接可在FireEye的最新博文“Using EMET to Disable EMET”[15]中找到。
但是,不同于之前的大部分技術,在我們的exploit中進行EMET繞過時,我們并沒有執行代碼的能力。因此如前面提到的FireEye文章中那些依賴于執行特定ROP代碼以禁用EMET保護的技術,雖優雅,然卻不適用于我們的情況。
不過,我們卻擁有強大的內存讀寫能力,我們可以借此來嘗試繞過特定的EMET保護或者將其完全禁用掉。
在本部分中,我們將看下EMET針對我們的exploit所用到的保護技術以及我們如何成功繞過最新的EMET 5.5版本。
另外,下述的分析都是基于的EMET64.dll 5.5.5870.0版本。
5.1 Attack Surface Reduction (ASR)
我們在EMET 5.5啟用的情況下執行exploit,EMET會檢測到威脅并將其阻止,給出的警告為“ASR check failed”。更多詳細信息可在事件日志中找到:

對于EMET中的ASR保護,它可阻止有潛在風險的特定模塊或插件的加載。
當我們試圖實例化WScript.Shell(wshom.ocx)時,由于此控件在ASR的黑名單中,所以EMET將會停止exploit的運行。我們知道EMET是通過hook LoadLibraryEx函數來檢測控件加載的,為了快速驗證ASR是否為阻止exploit執行的唯一保護措施,我們在調試器中動態對kernelbase!LoadLibraryEx*函數進行patch來臨時去掉相應的hook,此時,再次執行exploit,這次很順利,利用是可以成功的,也就意味著在我們的情況中只需繞過ASR保護即可。
現在我們就需要在exploit運行時找到一種借助內存讀寫來及時禁止ASR檢查的方法。
如果我們從被hook的kernelbase!LoadLibraryExW函數開始跟起,那么最終會來到sub_1800864F0這個函數,它做的第一件事就是讀取存儲在EMET64.dll模塊內偏移136800處的全局變量。

該讀取值是一編碼后的指針,由上圖可知它需要通過DecodePointer函數進行解碼,然后從該解碼指針的0x28偏移處讀取另一指針,最后再取偏移0x0處的flag值與0進行比較,如果flag值為0,那么后面所有關于LoadLibrary的檢查都將被繞過。
其中,全局指針通過EncodePointer函數中使用的每個進程都不同的secret值來進行保護,而位于0x28偏移處的指針存儲在堆中,我們不知道其具體分配的地址,并且存儲最終flag值的內存空間會被映射到只讀頁上,這些都在Offensive Security的博文中[16]有詳細描述。
由于我們并不擁有執行任意代碼的能力,也就無法使用諸如ROP鏈的方式來禁用或者繞過任何保護。我們需要找到一種僅通過讀寫內存就能禁用EMET的方法,因此,我們接下去的精力主要放在使用EncodePointer和DecodePointer函數進行保護的全局指針上。
5.2 指針的解碼
首先讓我們看下EncodePointer和DecodePointer函數是如何實現的,下圖為ntdll.dll模塊中的RtlDecodePointer函數:

可以知道這兩個函數最終都調用了ntdll!ZwQueryInformationProcess,并將內核返回的32位數作為secret值用于指針的編碼或解碼。但由于secret值并不保存到內存中的具體位置,也就意味著我們不能單純通過讀內存來獲取它進而來對指針進行手動解碼,因此接下來考慮如何獲取這個secret值。
以下偽代碼表示的是EncodePointer函數所執行的操作:
encoded_ptr = (secret ^ plain_ptr) >> (secret & 0x3f)
相應DecodePointer函數執行的操作如下:
plain_ptr = secret ^ (encoded_ptr >> (0x40 - (secret & 0x3f)))
其中,運算符>>表示循環右移。由于secret值的低字節會影響計算結果右移的比特數,所以我們不能直接通過異或編碼指針(encoded_ptr)和相應明文指針(plain_ptr)的方式來得到secret值。
但是,我們可以很容易對secret值進行暴力破解,因為對于右移操作最多只有0x3f種可能。因此,我們將遍歷從0到0x3f的所有可能情況,先對編碼指針執行右移操作,然后再將結果與相應的明文指針進行異或,這樣我們就會得到一個可能的secret值。此算法的偽代碼如下:
for (var i = 0; i < 0x3f; i++) {
var k = (encoded_ptr >> (0x40 - (i & 0x3f))) ^ plain_ptr;
if (encode_ptr(plain_ptr, k) == encoded_ptr) {
/* Found potential secret key k */
}
}
最終我們將猜出正確的secret值。但是,由于不同secret值對同一指針的編碼仍可能得到相同的編碼指針,因此對單獨的明文指針和編碼指針組合,可能會返回多個正確的secret值。并且相較64位進程,這種影響在32位進程中則更加明顯。
為了提高猜測secret值的準確性,至少需要使用兩對已知的編碼指針和明文指針組合。我們通過其中一對指針來暴力破解可能的secret值,然后使用第二對指針做驗證,只需將其中的明文指針用可能的secret值編碼,再將結果與已知的編碼指針比較即可。這樣,我們就將secret值的碰撞降到了可接受的水平。
5.3 查找指針對
讓我們看下能否在EMET模塊內找到通過讀內存就能獲取的已知編碼指針和明文指針的組合。 如果你查看過emet64.dll內所有的EncodePointer調用,那么你會注意到,其中有次初始調用是發生在sub_180048110函數中的,如下圖:

可以看到,此函數對NULL指針進行了編碼,結果保存在函數第一個入參指向的地址,該函數被調用的其中一個地方是在函數sub_1800204B0內,如下所示:

其中,Ptr是EMET64模塊的.data段中偏移量為0x135b80處的全局變量。
通過快速的調試查看可以知道,當EMET進行ASR檢查時,該位置仍然保存著NULL指針的編碼結果。因此我們找到了所需的第一對指針。
通過查看sub_180081038函數我們可以找到另一對編碼指針和明文指針的組合。

此函數將對第一個入參指針進行編碼,并且僅有一處被調用的地方,相應參數為函數sub_180080B40的地址。如下所示:

該函數指針編碼后的結果保存在EMET64+1362a0起偏移為EMET64+0x135320相應值乘8的地址處。我們可以很容易在內存中讀取這些值,從而得到第二對已知的編碼指針和明文指針組合。
因此,這將使得我們可以解碼iexplore.exe進程中的所有編碼指針。我們不僅提供了一種禁用ASR保護的通用方法,而且該方法還可用于完全消除EMET保護的任何進程中基于EncodePointer和DecodePointer函數實現的那些保護(假設你已具有讀取任意內存和獲取EMET模塊基址的能力)。
5.4 泄漏EMET模塊基址
這里我們將借助EMET中已知的幾個被hook函數,其中包括了ntdll.dll模塊中的NtProtectVirtualMemory函數。我們首先通過讀取jscript9.dll導入表中的RtlCaptureContext函數地址來泄漏ntdll.dll模塊基址,然后我們接著看下NtProtectVirtualMemory函數開頭的這幾條指令。

很顯然,通過檢查前幾字節,我們就可以確定當前進程是否受到EMET保護。為了泄漏EMET模塊的基址,我們跟下EMET啟用時最開始的這兩條jmp指令,最終可以看到如下所示的這條指令,它將EMET64.dll模塊內的偏移量賦值給了一個寄存器:

通過這條寄存器賦值指令,我們就可以計算出EMET模塊的基址。
5.5 禁用ASR保護
既然我們能得到EMET模塊的基址且擁有解碼被保護指針的能力,那么很自然的想法就是將校驗的flag值置為0以繞過ASR保護。但是,正如前面所述,該flag值存儲的頁面是只讀的,因此我們轉而替換指向此頁面的指針。
所以,在泄露EMET模塊的基址后,我們先按照前面的方法計算出EncodePointer/DecodePointer保護中所使用的secret值。而后借助該secret值,我們對EMET64.dll模塊內偏移0x136800處的全局指針進行解碼,最后使用指向NULL的指針來覆蓋其中偏移量0x28處的指針。此處用到的覆蓋值為EMET64+0x110ef8,它指向EMET64.dll模塊.rdata段中的NULL值。
經過這么處理后,我們可以成功繞過ASR保護,進而執行我們的exploit。如果需要,也可以使用同樣的方法來禁用其它的EMET保護技術。
6 結語
本文詳細描述了利用我們發現的一個關于Internet Explorer 11中JavaScript實現方面的漏洞來進行exploit開發的完整過程。其中,我們闡述了許多現有的諸如DEP或CFG這樣的漏洞利用保護措施就算不借助傳統的ROP代碼和shellcode也是可以實現輕松繞過的,只要我們能將漏洞轉換成對任意內存空間的讀寫就可以了,之后再通過瀏覽器中已有的功能來執行系統命令,同時,我們還分析了如何僅通過寫一個null字節就可在最新的Internet Explorer 11版本中實現這種方式的攻擊。
接下去我們給出了一種借助本地NetBIOS Spoofing進行Internet Explorer中EPM繞過的新方法,我們詳述了即便在開啟EPM的情況下,利用之前的Local Intranet Zone方式還是可以實現Internet Explorer沙箱逃逸。
最后,我們討論了最新的EMET 5.5版本是如何被繞過的以及我們如何通過計算secret值的方式來消除EMET中使用的EcodePointer保護。當然,所討論的這些方法不僅可以用于禁用ASR保護,而且還可用于消除EMET保護的進程中基于EncodePointer和DecodePointer函數實現的那些緩解措施。
這里所有提到的漏洞和技術都作為Mitigation Bypass Bounty項目提交的一部分報告給了微軟。其中,第2部分描述的Typed Array Neutering漏洞(CVE-2016-3210)已在MS16-063中修復,有趣的是,Edge的ChakraCore引擎自發布時就修復了同樣的漏洞。
3.6節中描述的借助null字節開啟上帝模式的技術(CVE-2016-0188)則在MS16-051中得到了修復,微軟通過引入QueryProtectedPolicy函數來緩解此問題。
而第4部分描述的通過本地NetBIOS Spoofing實現EPM下的沙箱逃逸技術(CVE-2016-3213)在MS16-077中也得到了修復。
但最后第5部分介紹的EMET繞過技術尚未被修復,而且微軟目前也沒有計劃去解決此問題。
總體來說,伴隨著當前Windows系統中漏洞利用保護措施不斷增長的數目以及穩定性的提升,exploit的開發成本被大幅增加了。但是,如果借助合適的漏洞,那么許多保護仍然是可以被繞過的,所缺乏的僅僅是想象力和創造性。 例如文中所述的data-only attacks,它就允許攻擊者繞過許多的保護措施,雖然微軟已經開始著手進行一些修復,但我們預計這種利用方式在未來會變得更加常見。
7 參考
[9] ?Verizon, "Escaping from Microsoft’s Protected Mode Internet Explorer":
https://www.exploit-db.com/docs/15672.pdf
[10] ?Zero Day Initiative, "There’s No Place Like Localhost: A Welcoming Front Door To Medium Integrity, HP Security Research":
http://community.hpe.com/t5/Security-Research/There-s-No-Place-Like-Localhost-A-Welcoming-Front-Door-To-Medium/ba-p/6560786
[11] ?Zero Day Initiative, "(0Day) (Pwn2Own\Pwn4Fun) Microsoft Internet Explorer localhost Protected Mode Bypass Vulnerability":
http://www.zerodayinitiative.com/advisories/ZDI-14-270/
[12] ?M. V. Yason, "Diving Into IE 10’s Enhanced Protected Mode Sandbox":
https://www.blackhat.com/docs/asia-14/materials/Yason/WP-Asia-14-Yason-Diving-Into-IE10s-Enhanced-Protected-Mode-Sandbox.pdf
[13] ?Microsoft, "IEInternals: The Intranet Zone":
http://blogs.msdn.com/b/ieinternals/archive/2012/06/05/the-local-intranet-security-zone.aspx
[14] ?FoxGlove Security, "Hot Potato Windows Privilege Escalation Exploit":
http://foxglovesecurity.com/2016/01/16/hot-potato
[15] ?FireEye, "Using EMET to Disable EMET":
https://www.fireeye.com/blog/threat-research/2016/02/using_emet_to_disabl.html
[16] ?Offensive Security, "Disarming and Bypassing EMET 5.1":
https://www.offensive-security.com/vulndev/disarming-and-bypassing-emet-5-1/
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.jmbmsq.com/196/
暫無評論