標籤:

HEVD 內核攻擊:漏洞攻擊的完全實現及SMEP繞過(四)

到目前為止,我們還沒有完全實現漏洞的攻擊。讓我們回顧一下第2篇里為DoS PoC創建的漏洞利用步驟,現在我們可以修改其中一些步驟,來實現SYSTEM shell。

第一步,生成cmd.exe進程

雖然這一步非常簡單,但是要在Python中實現,還是需要一些額外的代碼,與C語言代碼相比,我們將使用Kernel32.dll中的CreateProcess API來啟動shell。查看函數原型,該函數需要為調用設置兩個結構體,其中一個將使用我們啟動的cmd.exe進程的PID返回給我們。稍後我們需要使用shellcode來設置我們的結構體。

第一個是STARTUPINFO結構體(STARTUPINFO是用於指定新進程的主窗口特性的一個結構)。使用Python ctypes可以在我們的腳本中重新創建STARTUPINFO結構體,如下所示:

我們可以在腳本中引用這個結構體,如下所示:

我們需要的是一個PROCESS_INFORMATION結構,因為這個結構更易於管理,在ctypes中看起來是這樣:

這裡包含了dwProcessId dword中創建的進程PID。通過創建這兩個結構,我們可以參考CreateProcess函數原型並將我們的API調用放在一起:

第二步和第三步和第2篇里的過程一模一樣,大家可以爬樓。

第四步,使用shellcode分配緩衝區

首先將shellcode翻譯成Python。這也包括將cmd.exe進程的PID動態插入到shellcode中,這樣我們就創建了一個可以接收我們需要的PID並創建shellcode的函數:

利用VirtualAlloc函數複製我們的shellcode區域,當然前提是確保指定的分配緩衝區是可執行的。假設一切順利,我們就可以將shellcode複製到緩衝區(ctypes提供一個memmove()函數),然後返回shellcode所在的地址:

第五步,創建shellcode的緩衝區

這一步又與第2章提到的DoS PoC非常相似。不過,這一次,我們的函數還需要收到shellcode所在的分配地址,以便我們可以將它添加到我們的緩衝區。我們的DoS PoC緩衝區由2048「A」組成,其後是8「B」和8「C」。 「C」是在rip寄存器中結束的,所以我們要用我們的shellcode地址來替換它:

第六步,觸發漏洞

首先生成cmd.exe並獲取它的PID,然後分配shellcode並將該地址插入到我們創建的緩衝區。

如果一切順利的話,會出現以下的情景:

至此,漏洞就可以完全實現了。不過,我們在實際的測試中發現,這些漏洞攻擊只是在Windows 8以前的系統版本中運行的很好,由於Windows 8及更高版本上已經配置了一些新的緩解措施,所以這些漏洞利用就會被禁止。

主管模式執行保護(SMEP)有點像ring 0模式下的DEP,是內核的一種緩解措施,我們可以將它簡單的理解成禁止在內核態下執行用戶空間的代碼。換句話說,當以內核模式運行時,處理器將不會運行映射到用戶模式存儲器的指令。

在Windows 7版本中,我們是將shellcode複製到內存中。一旦我們劫持了內核中的執行流程,我們就會將其指向帶有shellcode的用戶內存緩衝區,但如果我們在啟用了SMEP的系統上也這麼做,那麼一旦處理器試圖執行用戶內存緩衝區的任何指令,則運行就會中斷。

正如開始的時候我說SMEP有點像DEP,繞過DEP比較常見的方法就是ROP鏈,因此繞過SMEP的常見方法也是比較簡單的方法也是ROP鏈,在DEP中構造ROP鏈需要dll的基址,其實在SMEP中構造ROP鏈需要動態鏈接庫內核的地址,而獲取內核地址的一種非常好用的方法就是NtQuerySystemInformation。

那麼我們如何繞過SMEP呢?最簡單的途徑就是簡化CR4寄存器,以便讓Windows認為是處理器不支持SMEP。這與我們的Windows 7 HEVD堆棧溢出漏洞大致相同,但在我們觸發溢出之前,我們必須首先執行ROP鏈以禁用SMEP。為了構建我們的ROP鏈,我們必須找到內核的基址,總共分8步:

1.Spawn cmd.exe進程

2.使用shellcode分配緩衝區

3.獲取內核基地址

4.構建ROP鏈

5.獲取容易受到攻擊的設備句柄

6.獲取正確的IOCTL的堆棧溢出功能

7.創建一個將執行重定向到ROP鏈及shellcode的緩衝區

8.觸發漏洞

以上只有第3步和第4步是新步驟,所以我們就直接來敘述這兩個步驟,其餘的步驟,請參看前文。

第三步,獲取內核基址

就像繞過DEP比較常見的方法就是ROP鏈一樣,我們可以使用ASLR,使用ROP來破壞內核中的SMEP可能會受到KASLR的阻礙。當然有各種方法來擊敗KASLR,但這不在本文的討論範圍之內。

簡單來說,利用psapi.dll的EnumDeviceDrivers功能就可以實現這一目標,EnumDeviceDrivers可以檢索系統中每個設備驅動程序的載入地址,其中包括返回結果中的實際內核:

第四步,建立ROP鏈

使用這一步的前提是,假設大家已經很熟悉ROP技術了。

現在我們已經得到了內核基地址,接下來我們將繼續構建繞過SMEP的ROP鏈。這不是很難,因為這是一個非常小的ROP鏈,只需要把ntoskrnl.exe解析為幾個位元組數組。

我們的目的就是將控制值彈出到CR4寄存器中。在搜索到可用的ROP後,我們發現沒有很多與CR4進行交互的指令,這時 ntoskrnl.exe中的KiFlushCurrentTbWorker函數實際上可以被利用起來:

接下來,我們只需要在內核的地址空間中找到POP RCX就可以了。最後,我們可以構建一個函數,該函數採用內核的基地址和shellcode的用戶地址,將CR4值放在該函數中,最後在shellcode緩衝區得到以下代碼:

至此,在Windows 8及更高版本上我們也實現了最終的漏洞利用:

本文參考來源於sizzop.github.io,如若轉載,請註明來源於嘶吼: HEVD 內核攻擊:漏洞攻擊的完全實現及SMEP繞過(四) 更多內容請關注「嘶吼專業版」——Pro4hou

推薦閱讀:

世界第一黑客凱文·米特尼克再出山:這次教你如何在線隱身
白帽黑客:技術理想抵抗現實慾望
調戲勒索軟體大黑客
馬雲想要的刷臉支付,谷歌真的幫他實現了!

TAG:信息安全 |