使用ROP攻擊繞過Windows的DEP

使用ROP攻擊繞過Windows的DEP

基礎知識

DEP

  • DEP(Data Execution Prevention)意爲數據執行保護,是Windows的一項安全機制,主要可以在內存上執行額外檢查以幫助防止在系統上運行惡意代碼,簡單的說也就是之前直接將shellcode插入到堆棧中執行的方法已經不可行了,由於在開啓DEP後,堆棧上的shellcode默認不可執行,所以也就不能使用之前的技術來成功攻擊了。
  • DEP工做狀態可分爲四種:
    • Optin:默認僅將DEP保護應用於Windows系統服務和組件,對其餘程序不予保護;
    • Optout:爲排除列表程序外的全部程序和服務啓用DEP;
    • AlwaysOn:對全部進程啓用DEP的保護,不存在排除列表,此模式下DEP不可被關閉,該模式只能工做在64位的操做系統上;
    • AlwaysOff:對全部進程都禁用DEP,此模式下DEP不能被動態開啓。

繞過DEP實現攻擊

  • 繞過DEP的方法能大體分爲兩種:
    • 新建可執行內存區域,將shellcode複製進去;相關函數: VirtualAlloc() 、 HeapCreate() 、 WriteProcessMemory()
    • 經過系統API關掉DEP保護;相關函數: SetProcessDEPPolicy() 、 NtSetInformationProccess() 、 VirtualProtect()
  • 各函數在Windows各個系統的存在狀況以下,其中(1)表明不存在,(2)表明將因爲默認DEP策略設置而失敗:
    html

  • 繞過DEP須要構造ROP鏈,ROP鏈的做用就是用一連串的gadgets來實現這些函數的調用關閉DEP保護,而後轉到shellcode上執行。python

實驗環境

  • 主機:kali
    git

  • 靶機:Windows XP Professional SP3
    shell

  • 軟件:Immnunity Debugger、OllyDbg、shellcode.exe(漏洞程序)windows

實踐過程

DEP保護關閉

  • shellcode.exe是在網上找的一個漏洞程序,它的功能就是在啓動時會在本地1000端口綁定socket並進行監聽,當有用戶鏈接而且用戶發送大於64bytes的數據時,堆棧會發生溢出,從而產生攻擊。
  • 在Windows XP SP3中,默認以Optin方式開啓DEP,即僅將DEP保護應用於Windows系統服務和組件,對其餘程序不予保護。shellcode.exe是用戶進程,天然也不會受到DEP保護:
    安全

  • 首先,咱們在沒有DEP保護的狀況下看程序可否成功溢出,在主機上進行nc監聽,打開4444端口:
    socket

  • 而後在靶機中運行shellcode.exe程序:
    函數

  • 編寫Python攻擊代碼exploit.py,將返回地址覆蓋爲0x7FFA4512(jmp esp指令),發送shellcode到靶機,而後回連主機的4444端口,編寫完成後運行:
    測試

  • 能夠看到,經過緩衝區溢出攻擊,此時主機上成功得到了xp的shell:
    操作系統

DEP保護打開

  • 如圖所示,在控制面板中設置打開DEP:

  • 重啓靶機,再次運行shellcode.exe,發現出錯了:

  • 使用OllyDbg進行調試,能夠看到程序是成功溢出了並執行了jmp esp指令(0x7FFA4512):

  • 從上圖中能夠知道,在DEP開啓的狀況下是溢出成功了,可是shellcode處在堆棧中,因爲DEP的保護,所以並不能觸發執行,於是報錯。
  • 由於SetProcessDEPPolicy函數簡單且ROP鏈構建相對容易,因此我就構建ROP鏈來調用SetProcessDEPPolicy函數關閉DEP保護,而後轉向shellcode執行。基礎知識中提到ROP鏈是由gadgets構造的,要想快速的找到gadgets來構造鏈,能夠用到Immunity Debugger上的一個python模塊:mona.py,具體介紹能夠參考這篇文檔,將它下載後複製到Immunity Debugger的PyCommands目錄下就可使用了。
  • 使用Immunity Debugger載入shellcode.exe,而後能夠查看當前程序加載的可執行模塊:

  • 在下方命令行處輸入命令!mona rop -m kernel32.dllkernel32.dll中進行掃描,查找完成後,會在IM Debugger的安裝目錄下生成報表文件,咱們打開rop_chains.txt進行查看,找到SetProcessDEPPolicy的ROP鏈說明處,能夠看到針對不一樣語言有不一樣的說明,有Ruby語言的、Python的、JavaScript等等,咱們找到Python對應的說明:

  • 整個ROP鏈的最終構造結果是構造出一個特定的寄存器結果,就像上圖所示的同樣,由於咱們知道PUSHAD是依次將EAX、ECX、EDX…ESI、EDI入棧,那麼當咱們經過ROP鏈構造好各個寄存器並經過gadget執行PUSHAD RETN後,此時堆棧的結構大概就是這個樣子的:

  • 這裏能夠看到,入棧前咱們將EDI和ESI的值存儲爲RETN指令的地址,而後會執行EBP處的SetProcessDEPPolicy函數,由於PUSHAD RETN在shellcode的上一個位置,執行完後ESP會指向shellcode,當SetProcessDEPPolicy執行完畢後會直接轉到咱們shellcode處執行(此時已經經過調用SetProcessDEPPolicy取消DEP保護了),因此通過分析能夠看到咱們構造的具體的ROP鏈:
0x????????,  # POP EBP # RETN
0x????????,  # ptr SetProcessDEPPolicy(「SetProcessDEPPolicy」的指針)
0x????????,  # POP EBX # RETN
0x00000000,  # dwFlags
0x????????,  # POP EDI # RETN
0x????????,  # ptr RETN(「retn指令」的地址)
0x????????,  # POP ESI # RETN
0x????????,  # ptr RETN(「retn指令」的地址)
0x????????,  # PUSHAD # RETN
  • 上面的問號表明咱們須要尋找的ROP gadget的地址,這裏還要指出一個問題,不少時候咱們須要的gadget不必定能在當前程序的執行模塊中直接找到,可是咱們能夠經過其餘方法來實現,好比我想使得EBX爲0x00000000,咱們能夠先找到POP EBX; RETN;,將EBX先賦值爲0xffffffff,而後在找到INC EBX; RETN;,這樣兩個gadget合在一塊兒執行達到了咱們的目的。
  • 其實,剛纔經過執行mona.py已經在IM Debugger安裝目錄下記錄了一些小配件的地址,打開rops.txt,經過查找咱們能夠找到在0x7c87f30f處找到咱們想要的ROP小配件:

  • 這裏,咱們能夠從新在IM Debugger中利用mona.py模塊來進行特定指令的查找,retn指令的機器碼爲\xc3,咱們在命令行中輸入!mona find -s '\xc3 -m kernel32.dll',命令執行完成後,結果會在IM Debugger安裝目錄下find.txt文件中,以下圖所示:

  • 能夠選擇其中幾個做爲咱們RETN的gadget,其餘gadget的尋找方法和這個相似,經過mona.py最後找到的各個ROP gadget構成的ROP鏈以下所示:
0x77bf4f42,   # RETN
0x90909090,
0x7c80df32,   # POP EBP # RETN
0x7c862144,   # ptr to SetProccessDEPPolicy()
0x7c81ae28,   # POP EBX # RETN [kernel32.dll]
0x00000000,   # 0x00000000(dwFlags)
0x7c86ce63,   # POP EDI # RETN [kernel32.dll] 
0x77bf54c4,   # ptr RETN
0x7c87b976,   # POP ESI # RETN [msvcrt.dll]
0x77bf5502,   # ptr RETN
0x77d23ad9,   # PUSHAD # RETN [user32.dll]
  • 由於shellcode.exe在溢出點函數返回時是RETN 0x04,所以我加入了前兩個ROP gadget進行過渡,使得整個ROP鏈可以串起來。
  • 最後將構造的ROP鏈與最開始編寫的Python攻擊代碼從新結合一下,構成新的攻擊代碼exlpoit_dep.py

  • 而後,咱們在系統開啓DEP保護的狀況下,使用新的攻擊代碼進行測試:

  • 能夠看到成功獲得了shell,至此使用ROP攻擊繞過Windows的DEP成功:

相關文章
相關標籤/搜索