20155330 《網絡攻防》Exp1 PC平臺逆向破解(5)M

20155330 《網絡攻防》Exp1 PC平臺逆向破解(5)M

實踐目標

運行pwn1可執行文件中的getshell函數,學習如何注入運行任何Shellcode
本次實踐的對象是一個名爲pwn1的linux可執行文件。linux

實踐內容

  • 手工修改可執行文件,改變程序執行流程,直接跳轉到getShell函數。
  • 利用foo函數的Bof漏洞,構造一個攻擊輸入字符串,覆蓋返回地址,觸發getShell函數。
  • 注入一個本身製做的shellcode並運行這段shellcode。

基本思路

  • 運行本來不可訪問的代碼片斷
  • 強行修改程序執行流
  • 以及注入運行任意代碼。

相關知識

  • 熟悉Linux基本操做
    • 能看懂經常使用指令,如管道(|),輸入、輸出重定向(>)等。
  • 理解Bof的原理。
    • 能看得懂彙編、機器指令、EIP、指令地址。
  • 會使用gdb,vi。
  • 指令
    • NOP:經過nop指令的填充(nop指令一個字節),使指令按字對齊,從而減小取指令時的內存訪問次數。(機器碼:90)
    • JNE:條件轉移指令,若是不相等則跳轉。(機器碼:75)
    • JE:條件轉移指令,若是相等則跳轉。(機器碼:74)
    • JMP:無條件轉移指令。
      • 段內直接短轉Jmp short(機器碼:EB)
      • 段內直接近轉移Jmp near(機器碼:E9)
      • 段內間接轉移Jmp word(機器碼:FF)
      • 段間直接(遠)轉移Jmp far(機器碼:EA)
    • CMP:比較指令,至關於減法指令,只是不保存結果。執行後,對標誌寄存器產生影響。其餘相關指令經過識別這些被影響的標誌寄存器位來得知比較結果。
      • 機器碼shell

        機器碼 指令功能
        38 CMP reg8/mem8,reg8
        39 CMP reg16/mem16,reg16
        3A CMP reg8,reg8/mem8
        3B CMP reg16,reg16/mem16
        3C CMP al,immed8
        3D CMP ax,immed16

1、直接修改程序機器指令,改變程序執行流程

  • 首先對pwn1文件進行反彙編windows

  • 查看main函數調用foo的地址值,foo函數的第一條指令的地址值,和須要修改的getShell函數第一條指令的地址值。由下圖可知,main函數調用foo對應機器指令爲e8 d7ffffff,因爲要將調用的函數更改成getShell,則需修改d7 ff ff ffgetShell-80484ba對應的補碼,經過計算47d-4ba獲得補碼,main函數調用getShell對應機器指令爲c3 ff ff ff
    網絡

  • 使用VIM編輯器對pwn1文件進行編輯。文件顯示爲亂碼,用%!xxd命令將顯示模式切換爲16進制模式
    dom

  • 輸入/e8 d7查找要修改的內容,修改d7c3,用命令%!xxd -r將16進制轉換爲原格式,wq存盤退出。
    編輯器

  • 再次將文件反彙編,能夠看到地址80484b5的機器指令d7變動爲c3,main函數調用getShell
  • 運行文件。(在實踐過程當中從新備份了pwn1文件爲pwn2,以上步驟爲備份前截圖,備份後將pwn1文件修改成原文件。)函數

2、經過構造輸入參數,形成BOF攻擊,改變程序執行流

  • 目標:觸發getShell函數學習

  • pwn1可執行文件正常運行是調用以下函數foo,這個函數有Buffer overflow漏洞spa

  • 讀入字符串,但系統只預留了__字節的緩衝區,超出部分會形成溢出,咱們的目標是覆蓋返回地址3d

  • main函數中call調用foo,同時在堆棧上壓上返回地址值:80484ba

  • 確認輸入字符串哪幾個字符會覆蓋到返回地址
    • gdb pwn3_155330調試可執行文件,r運行,info r查看寄存器eip(即將執行的指令地址)的值

    • 再次運行,將後八位值更改後發現eip值改變。1234 四個數最終會覆蓋到堆棧上的返回地址,進而CPU會嘗試運行這個位置的代碼。將這四個字符替換爲 getShell 的內存地址,輸給pwn,pwn1就會運行getShell。

  • 確認用什麼值來覆蓋返回地址
    • 經過反彙編時能夠看到getShell的內存地址爲0804847d。接下來要確認下字節序,簡單說是輸入\x08\x04\x84\x7d,仍是輸入\x7d\x84\x04\x08。對比以前的eip,該終端採用小端方式,正確應用輸入\x7d\x84\x04\x08
    • 由爲咱們無法經過鍵盤輸入\x7d\x84\x04\x08這樣的16進制值,因此先生成包括這樣字符串的一個文件。\x0a表示回車,若是沒有的話,在程序運行時就須要手工按一下回車鍵。
    • 用perl命令生成字符串並重定向>input文件中。
    • 使用16進制查看指令xxd查看input文件的內容
    • 將input的輸入,經過管道符「|」,做爲pwn1的輸入。

3、注入Shellcode並執行

  • 準備一段Shellcode
    • shellcode就是一段機器指令(code)
    • 一般這段機器指令的目的是爲獲取一個交互式的shell(像linux的shell或相似windows下的cmd.exe),因此這段機器指令被稱爲shellcode。
    • 在實際的應用中,凡是用來注入的機器指令段都通稱爲shellcode,像添加一個用戶、運行一條指令。
  • execstack -s pwn1設置堆棧可執行。

  • apt-get install execstack獲取安裝。

  • execstack -q pwn1查詢文件的堆棧是否可執行。並依次執行如下命令。

more /proc/sys/kernel/randomize_va_space 
echo "0" > /proc/sys/kernel/randomize_va_space
more /proc/sys/kernel/randomize_va_space

  • 構造要注入的payload。

  • Linux下有兩種基本構造攻擊buf的方法:
    • retaddr+nop+shellcode
    • nop+shellcode+retaddr。
  • 由於retaddr在緩衝區的位置是固定的,shellcode要不在它前面(緩衝區大),要不在它後面(緩衝區小)。

  • 結構爲:nops+shellcode+retaddr。
    • nop一爲是了填充,二是做爲「着陸區/滑行區」。
    • 猜想的返回地址只要落在任何一個nop上,就能滑到shellcode。
  • 輸入perl -e 'print "\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90\x4\x3\x2\x1\x00"' > input_shellcode,最後的\x4\x3\x2\x1將覆蓋到堆棧上的返回地址的位置。把\x4\x3\x2\x1改成這段shellcode的地址。

  • 打開一個終端注入這段攻擊buf(cat input_shellcode;cat) | ./pwn4_155330
  • 再開另一個終端,用gdb來調試進程。
  • ps -ef | grep pwn4_155330查看進程號。grep pwn4_155330的進程號是2481
  • gdb調試這個進程,查看注入buf的內存地址
  • 設置斷點

  • 繼續運行

  • 查看esp寄存器值,

  • 計算出地址值爲d300,修改地址重定向到input_shellcode文件



相關文章
相關標籤/搜索