20165309 《網絡對抗技術》實驗一:PC平臺逆向破解

20165309 《網絡對抗技術》實驗一:PC平臺逆向破解


目錄


1、實踐目標

  • 本次實踐的對象是一個名爲pwn1的linux可執行文件。該程序正常執行流程是:main調用foo函數,foo函數會簡單回顯任何用戶輸入的字符串。
  • 該程序同時包含另外一個代碼片斷,getShell,會返回一個可用Shell。正常狀況下這個代碼是不會被運行的。
  • 咱們實踐的目標就是想辦法運行這個代碼片斷,而後學習如何注入運行任何Shellcode。

返回目錄安全


2、基礎知識

  • 什麼是漏洞?漏洞有什麼危害?
    • 我以爲漏洞就是攻擊者進行未受權訪問和破壞的「機會」,也是程序產生非預期行爲的隱患。
    • 漏洞會致使諸多安全問題,甚至會影響到軟、硬件設備。被侵入後,咱們的數據、隱私等會很容易被竊取、利用,因此,勤打補丁很重要。
  • 掌握NOP, JNE, JE, JMP, CMP彙編指令的機器碼
    • 咱們能夠利用objdump -d獲得彙編代碼,而後對應起來看彙編指令和機器碼。(如下指令的機器碼均在括號中標出)
    • NOP:「NULL」,通常用來控制CPU的時間週期,達到時鐘延時的效果。(90)
    • JNE:條件轉移指令,若是不相等則跳轉。(75)
    • JE:條件轉移指令,若是相等則跳轉。(74)
    • JMP:無條件轉移指令可轉到內存中任何程序段。段內直接短轉Jmp short(EB)段內直接近轉移Jmp near(E9)段內間接轉移Jmp word(FF)段間直接遠轉移Jmp far(EA)。
    • CMP:比較指令,CPU將目的操做數和源操做數作減法從而根據運算結果修改標誌位的值,而後用相應的跳轉指令來進行選擇執行哪一段代碼。
    • 推薦一波參考資料:彙編指令和機器碼的對應表彙編指令機器碼對應列表
  • 反彙編
    • objdump -d : 將代碼段反彙編。
    • objdump -S : 將代碼段反彙編的同時,將反彙編代碼與源代碼交替顯示,編譯時須要使用-g參數調試信息。
    • objdump -l : 反彙編代碼中插入文件名和行號。
    • objdump -j section : 僅反彙編指定的section。
    • objdump -t :輸出目標文件的符號表。
    • objdump -h :輸出目標文件的全部段歸納。
    • objdump -x :以某種分類信息的形式把目標文件的數據組成輸出,可查到該文件的的全部動態庫。
  • 十六進制編程器
    • 在VIM裏時咱們能夠經過以下方式使用:
      • :%!xxd :進入十六進制模式。
      • :%!xxd -r :退出十六進制模式。

返回目錄bash


3、實驗原理、內容及步驟

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

1.1實驗原理

程序中的main函數會經過call指令調用foo這個函數,實驗的這一環節就是要改其地址、換其函數、實現「想要」的功能(詳見下述步驟)。網絡

1.2內容及步驟
  • 首先,來找一找共享文件夾的「pwn1」在哪兒:
  • 然而,咱們發現,它如今運行不了:
  • 由於須要裝個支持32位程序的庫,這裏參考了學長的博客,其中,用的更新源來自解決kali更新源時出現簽名無效問題

  • 如今可行了,如圖可見foo函數的功能:
  • 用反彙編,看一看實驗覈心函數的部分,這裏,咱們重點關注main函數的call指令這一行:call指令對應的e8,咱們要作的就是把四字節的偏移量ff ff ff d7(小端序,補碼)換成getShell函數對應的。


  • call指令在執行時,會EIP當前的值,也就是下一條指令的地址——0x080484ba壓棧,而後修改寄存器EIP,將EIP指向foo函數的起始地址(由於EIP+偏移量= 0x080484ba + 0xffffffd7 = 0x08048491目的地址)。
  • 因此要修改的是call指令的偏移量,由計算0x0804847d - 0x080484ba = 0xffffffc3,簡而言之,要把d7換成c3了。在vim下修改:以下圖指令進入十六進制模式,而後定位,換後回到二進制模式。


  • 保存退出後,咱們能夠看到call函數使程序跳轉到了getShell函數。
  • 運行後,咱們實現出了shell~

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

2.1實驗原理
  • 經過觀察上一環節的反彙編頁面,可知foo函數中使用了gets函數,該函數不會檢查用戶輸入的長度,經過「棧溢出」覆蓋棧中保存的RET地址,能夠改變程序的執行流。
  • 咱們這裏要作的就是利用foo函數的Bof漏洞,構造一個攻擊輸入字符串,覆蓋返回地址,觸發getShell函數。
2.2內容及步驟
  • 咱們要確認一下字符串的緩衝區長度,進gdb調試,輸入字符串如1111111122222222333333334444444455555555,發生段錯誤產生溢出。(注意EIP的值,是ASCII 5)

  • 若是輸入字符串1111111122222222333333334444444412345678,那1234這四個數最終會覆蓋到堆棧上的返回地址,進而CPU會嘗試運行這個位置的代碼。那隻要把這四個字符替換爲getShell的內存地址,輸給pwn2,pwn2就會運行getShell。
  • 這裏的字節序是小端序,getShell的地址(0x0804847d)放在字符串中就是\x7d\x84\x04\x08
  • 使用輸出重定向「>」將perl生成的字符串存儲到文件input中,再用16進制查看指令xxd查看input文件的內容是否如預期,而後將input的輸入經過管道符「|」做爲pwn2的輸入,再現shell功能:
  • PS.看到了不用perl語言的一種方式:

3.注入Shellcode並執行

3.1實驗原理
  • 植入代碼的構造類型(NSR、RNS、AR),可學習緩衝區溢出攻擊這篇報告。實驗中用的是RNS類型。
  • 在實際的應用中,凡是用來注入的機器指令段都通稱爲shellcode,像添加一個用戶、運行一條指令,注入shellcode即返回地址爲shellcode的起始地址。
3.2內容及步驟
  • 安裝execstack程序以便後續設置易於攻擊的環境:apt-get install execstack
  • 準備工做(搬運一下老師的實驗指導):
root@KaliYL:~# execstack -s pwn1    //設置堆棧可執行
root@KaliYL:~# execstack -q pwn1    //查詢文件的堆棧是否可執行
X pwn1
root@KaliYL:~# more /proc/sys/kernel/randomize_va_space 
2
root@KaliYL:~# echo "0" > /proc/sys/kernel/randomize_va_space //關閉地址隨機化
root@KaliYL:~# more /proc/sys/kernel/randomize_va_space 
0
  • 構造RNS攻擊結構:<32字節任意數據> + <4字節 RET覆蓋地址> + <NOP墊> + <shellcode>,最後一個字符千萬不能是\x0a
  • 注入:
  • 再開另一個終端,用gdb來調試pwn3這個進程。
  • 在gdb中鏈接進程,在foo函數的RET位置設置斷點,在斷點處暫停後,查看棧的狀況:

  • NOP墊的開始地址是0xffffd34c,shellcode在其基礎上加4字節,因而修改\x4\x3\x2\x1\x50\xd3\xff\xff。攻擊成功:

返回目錄dom


4、問題與解決

  • 問題1:報錯bash: ./pwn1: 沒有那個文件或目錄
  • 解決1:上述博客 3、1.2 中已詳解。
  • 注意2:十六進制下修改地址後要換回二進制再保存退出。

返回目錄函數


5、實驗收穫

我以爲這個實驗在操做上是很容易的,我也算是切身領會了BOF攻擊神奇的樂趣,但在理解方面我還須要下一些功夫,有些知識本身看的時候並不能弄清楚,上課聽老師講完才知道,自學成效堪憂...還有一點收穫是:謹防入坑。

返回目錄

相關文章
相關標籤/搜索