標(biāo)?題
:?
【技術(shù)專題】軟件漏洞分析入門_5_初級(jí)棧溢出D_植入任意代碼
作?者
:?
failwest
時(shí)?間
:?
2007
-
12
-
16
,
17
:
06
鏈?接
:?
http
:
//bbs.pediy.com/showthread.php?t=56656
第
5
講??初級(jí)棧溢出D——植入任意代碼
To?be?the?apostrophe?which?changed?“Impossible”?into?“I’m?possible”
——?failwest
麻雀雖小,五臟俱全
如果您順利的學(xué)完了前面
4
講的內(nèi)容,并成功的完成了第
2
講和第
4
講中的實(shí)驗(yàn),那么今天請(qǐng)跟我來(lái)一起挑戰(zhàn)一下劫持有漏洞的進(jìn)程,并向其植入惡意代碼的實(shí)驗(yàn),相信您成功完成這個(gè)實(shí)驗(yàn)后,學(xué)習(xí)的興趣和自信心都會(huì)暴增。
開始之前,先簡(jiǎn)要的回答一下前幾講跟貼中提出的問(wèn)題
代碼編譯少頭文件問(wèn)題:可能是個(gè)人習(xí)慣問(wèn)題,哪怕幾行長(zhǎng)的程序我也會(huì)丟到project里去build,而不是用cl,所以沒(méi)有注意細(xì)節(jié)。如果你們嫌麻煩,不如和我一樣用project來(lái)build,應(yīng)該沒(méi)有問(wèn)題的。否則的話,實(shí)驗(yàn)用的程序?qū)嵲谔?jiǎn)單了,這么一點(diǎn)小問(wèn)題自己決絕吧。另外,看到幾個(gè)同學(xué)說(shuō)為了實(shí)驗(yàn),專門恢復(fù)了古老的VC6
.0
,我也感動(dòng)不已啊,呵呵。
地址問(wèn)題:溢出使用的地址一般都要在調(diào)試中重新確定,尤其是本節(jié)課中的哦。所以照抄我的實(shí)驗(yàn)指導(dǎo),很可能會(huì)出現(xiàn)地址錯(cuò)誤。特別是本節(jié)課中有若干個(gè)地址都需要在調(diào)試中重新確定,請(qǐng)大家務(wù)必注意。能夠屏蔽地址差異的通用溢出方法將會(huì)在后續(xù)課程中逐一講解。
還有就是抱歉周末中斷了一天的講座——無(wú)私奉獻(xiàn)也要過(guò)周末啊,大家體諒一下了。另外就是下周項(xiàng)目很緊張,估計(jì)不能每天都發(fā)貼了,爭(zhēng)取兩到三天發(fā)一次,請(qǐng)大家體諒。
如果有什么問(wèn)題,歡迎在跟貼中提出來(lái),一起討論,實(shí)驗(yàn)成功完成的同學(xué)記住要吱——吱——吱啊,呵呵
在基礎(chǔ)知識(shí)方面,本節(jié)沒(méi)有新的東西。但是這個(gè)想法實(shí)踐起來(lái)還是要費(fèi)點(diǎn)周折的。我設(shè)計(jì)的實(shí)驗(yàn)是最最簡(jiǎn)單的情況,為了防止一開始難度高,刻意的去掉了真正的漏洞利用中的一些步驟,為的是讓初學(xué)者理解起來(lái)更加清晰,自然。
本節(jié)將涉及極少量的匯編語(yǔ)言編程,不過(guò)不要怕,非常簡(jiǎn)單,我會(huì)給于詳細(xì)的解釋,不用專門去學(xué)匯編語(yǔ)言也能扛下來(lái)
另外本節(jié)需要最基本的使用OllyDbg進(jìn)行調(diào)試,并配合一些其他工具以確認(rèn)一些內(nèi)存地址。當(dāng)然這些地址的確認(rèn)方法有很多,我只給出一種解決方案,如果大家在實(shí)驗(yàn)的時(shí)候有什么心得,不妨在跟貼中拿出來(lái)和大家一起分享,一起進(jìn)步。
開始前簡(jiǎn)單回顧上節(jié)的內(nèi)容:
password
.
txt?文件中的超長(zhǎng)畸形密碼讀入內(nèi)存后,會(huì)淹沒(méi)verify_password函數(shù)的返回地址,將其改寫為密碼驗(yàn)證正確分支的指令地址
函數(shù)返回時(shí),錯(cuò)誤的返回到被修改的內(nèi)存地址處取指執(zhí)行,從而打印出密碼正確字樣
試想一下,如果我們把buffer
[
44
]
中填入一段可執(zhí)行的機(jī)器指令(寫在password
.
txt文件中即可),再把這個(gè)返回地址更改成buffer
[
44
]
的位置,那么函數(shù)返回時(shí)不就正好跳去buffer里取指執(zhí)行了么——那里恰好布置著一段用心險(xiǎn)惡的機(jī)器代碼!
本節(jié)實(shí)驗(yàn)的內(nèi)容就用來(lái)實(shí)踐這一構(gòu)想——通過(guò)緩沖去溢出,讓進(jìn)程去執(zhí)行布置在緩沖區(qū)中的一段任意代碼。
圖
1
??
??
如上圖所示,在本節(jié)實(shí)驗(yàn)中,我們準(zhǔn)備向password
.
txt文件里植入二進(jìn)制的機(jī)器碼,并用這段機(jī)器碼來(lái)調(diào)用windows的一個(gè)API函數(shù)?MessageBoxA,最終在桌面上彈出一個(gè)消息框并顯示“failwest”字樣。事實(shí)上,您可以用這段代碼來(lái)做任何事情,我們這里只是為了證明技術(shù)的可行性。
為了完成在棧區(qū)植入代碼并執(zhí)行,我們?cè)谏瞎?jié)的密碼驗(yàn)證程序的基礎(chǔ)上稍加修改,使用如下的實(shí)驗(yàn)代碼:
#include?
<
stdio
.
h
>
#include?
<
windows
.
h
>
#define?
PASSWORD?
"1234567"
int?
verify_password?
(
char?
*
password
)
{
??
int?
authenticated
;
??
char?
buffer
[
44
];
??
authenticated
=
strcmp
(
password
,
PASSWORD
);
??
strcpy
(
buffer
,
password
);
//over?flowed?here!??
??
return?
authenticated
;
}
main
()
{
??
int?
valid_flag
=
0
;
??
char?
password
[
1024
];
??
FILE?
*?
fp
;
??
LoadLibrary
(
"user32.dll"
);
//prepare?for?messagebox
??
if
(!(
fp
=
fopen
(
"password.txt"
,
"rw+"
)))
??{
????
exit
(
0
);
??}
??
fscanf
(
fp
,
"%s"
,
password
);
??
valid_flag?
=?
verify_password
(
password
);
??
if
(
valid_flag
)
??{
????
printf
(
"incorrect?password!\n"
);
??}
??
else
??
{
????
printf
(
"Congratulation!?You?have?passed?the?verification!\n"
);
??}
??
fclose
(
fp
);
}
這段代碼在底
4
講中使用的代碼的基礎(chǔ)上修改了三處:
增加了頭文件windows
.
h,以便程序能夠順利調(diào)用LoadLibrary函數(shù)去裝載user32
.
dll
verify_password函數(shù)的局部變量buffer由
8
字節(jié)增加到
44
字節(jié),這樣做是為了有足夠的空間來(lái)“承載”我們植入的代碼
main函數(shù)中增加了LoadLibrary
(
"user32.dll"
)
用于初始化裝載user32
.
dll,以便在植入代碼中調(diào)用MessageBox
用VC6
.0
將上述代碼編譯(默認(rèn)編譯選項(xiàng),編譯成debug版本),得到有棧溢出的可執(zhí)行文件。在同目錄下創(chuàng)建password
.
txt文件用于程序調(diào)試。
我們準(zhǔn)備在password
.
txt文件中植入二進(jìn)制的機(jī)器碼,在password
.
txt攻擊成功時(shí),密碼驗(yàn)證程序應(yīng)該執(zhí)行植入的代碼,并在桌面上彈出一個(gè)消息框顯示“failwest”字樣。
??
讓我們?cè)趧?dòng)手之前回顧一下我們需要完成的幾項(xiàng)工作:
1
:分析并調(diào)試漏洞程序,獲得淹沒(méi)返回地址的偏移——在password
.
txt的第幾個(gè)字節(jié)填偽造的返回地址
2
:獲得buffer的起始地址,并將其寫入password
.
txt的相應(yīng)偏移處,用來(lái)沖刷返回地址——填什么值
3
:向password
.
txt中寫入可執(zhí)行的機(jī)器代碼,用來(lái)調(diào)用API彈出一個(gè)消息框——編寫能夠成功運(yùn)行的機(jī)器代碼(二進(jìn)制級(jí)別的哦)
這三個(gè)步驟也是漏洞利用過(guò)程中最基本的三個(gè)問(wèn)題——淹到哪里,淹成什么以及開發(fā)shellcode
首先來(lái)看淹到什么位置和把返回地址改成什么值的問(wèn)題
本節(jié)驗(yàn)證程序里verify_password中的緩沖區(qū)為
44
個(gè)字節(jié),按照前邊實(shí)驗(yàn)中對(duì)棧結(jié)構(gòu)的分析,我們不難得出棧幀中的狀態(tài)如下圖所示:
?
圖
2
如果在password
.
txt中寫入恰好
44
個(gè)字符,那么第
45
個(gè)隱藏的截?cái)喾鹡ull將沖掉authenticated低字節(jié)中的
1
,從而突破密碼驗(yàn)證的限制。我們不妨就用
44
個(gè)字節(jié)做為輸入來(lái)進(jìn)行動(dòng)態(tài)調(diào)試。
??出于字節(jié)對(duì)齊、容易辨認(rèn)的目的,我們把“
4321
”作為一個(gè)輸入單元。
??buffer
[
44
]
共需要
11
個(gè)這樣的單元
??第
12
個(gè)輸入單元將authenticated覆蓋
??第
13
個(gè)輸入單元將前棧幀EBP值覆蓋
??第
14
個(gè)輸入單元將返回地址覆蓋
分析過(guò)后我們需要進(jìn)行調(diào)試驗(yàn)證分析的正確性。首先在password
.
txt中寫入
11
組“
4321
”共
44
個(gè)字符:
??
圖
3
如我們所料,authenticated被沖刷后程序?qū)⑦M(jìn)入驗(yàn)證通過(guò)的分支:
?
圖
4
用OllyDbg加載這個(gè)生成的PE文件進(jìn)行動(dòng)態(tài)調(diào)試,字符串拷貝函數(shù)過(guò)后的棧狀態(tài)如圖:
?
圖
5
??
此時(shí)的棧區(qū)內(nèi)存如下表所示
局部變量名??內(nèi)存地址??偏移
3
處的值??偏移
2
處的值??偏移
1
處的值??偏移
0
處的值
buffer
[
0
~
3
]??
0x0012FAF0??0x31?
(
‘
1
’
)??
0x32?
(
‘
2
’
)??
0x33?
(
‘
3
’
)??
0x34?
(
‘
4
’
)
……??(
9
個(gè)雙字)??
0x31?
(
‘
1
’
)??
0x32?
(
‘
2
’
)??
0x33?
(
‘
3
’
)??
0x34?
(
‘
4
’
)
buffer
[
40
~
43
]??
0x0012FB18??0x31?
(
‘
1
’
)??
0x32?
(
‘
2
’
)??
0x33?
(
‘
3
’
)??
0x34?
(
‘
4
’
)
authenticated
(被覆蓋前)??
0x0012FB1C??0x00??0x00??0x00??0x31?
(
‘
1
’
)
authenticated
(被覆蓋后)??
0x0012FB1C??0x00??0x00??0x00??0x00?
(
NULL
)
前棧幀EBP??
0x0012FB20??0x00??0x12??0xFF??0x80
返回地址??
0x0012FB24??0x00??0x40??0x11??0x18
??
動(dòng)態(tài)調(diào)試的結(jié)果證明了前邊分析的正確性。從這次調(diào)試中我們可以得到以下信息:
buffer數(shù)組的起始地址為
0x0012FAF0
——注意這個(gè)值只是我調(diào)試的結(jié)果,您需要在自己機(jī)器上重新確定!
password
.
txt文件中第
53
到第
56
個(gè)字符的ASCII碼值將寫入棧幀中的返回地址,成為函數(shù)返回后執(zhí)行的指令地址
也就是說(shuō)將buffer的起始地址
0x0012FAF0
寫入password
.
txt文件中的第
53
到第
56
個(gè)字節(jié),在verify_password函數(shù)返回時(shí)會(huì)跳到我們輸入的字串開始出取指執(zhí)行。
我們下面還需要給password
.
txt中植入機(jī)器代碼。
讓程序彈出一個(gè)消息框只需要調(diào)用windows的API函數(shù)MessageBox。MSDN對(duì)這個(gè)函數(shù)的解釋如下:
int?
MessageBox
(
??
HWND?hWnd
,??????????
//?handle?to?owner?window
??
LPCTSTR?lpText
,?????
//?text?in?message?box
??
LPCTSTR?lpCaption
,??
//?message?box?title
??
UINT?uType??????????
//?message?box?style
);
hWnd?
[
in
]?
消息框所屬窗口的句柄,如果為NULL的話,消息框則不屬于任何窗口?
lpText?
[
in
]?
字符串指針,所指字符串會(huì)在消息框中顯示?
lpCaption?
[
in
]?
字符串指針,所指字符串將成為消息框的標(biāo)題?
uType?
[
in
]?
消息框的風(fēng)格(單按鈕,多按鈕等),NULL代表默認(rèn)風(fēng)格?
雖然只是調(diào)一個(gè)API,在高級(jí)語(yǔ)言中也就一行代碼,但是要我們直接用二進(jìn)制指令的形式寫出來(lái)也并不是一件容易的事。這個(gè)貌似簡(jiǎn)單的問(wèn)題解決起來(lái)還要用一點(diǎn)小心思。不要怕,我會(huì)給我的解決辦法,不一定是最好的,但是能解決問(wèn)題。
??我們將寫出調(diào)用這個(gè)API的匯編代碼,然后翻譯成機(jī)器代碼,用
16
進(jìn)制編輯工具填入password
.
txt文件。
注意:熟悉MFC的程序員一定知道,其實(shí)系統(tǒng)中并不存在真正的MessagBox函數(shù),對(duì)MessageBox這類API的調(diào)用最終都將由系統(tǒng)按照參數(shù)中字符串的類型選擇“A”類函數(shù)(ASCII)或者“W”類函數(shù)(UNICODE)調(diào)用。因此我們?cè)趨R編語(yǔ)言中調(diào)用的函數(shù)應(yīng)該是MessageBoxA。多說(shuō)一句,其實(shí)MessageBoxA的實(shí)現(xiàn)只是在設(shè)置了幾個(gè)不常用參數(shù)后直接調(diào)用MessageBoxExA。探究API的細(xì)節(jié)超出了本書所討論的范圍,有興趣的讀者可以參閱其他書籍。
用匯編語(yǔ)言調(diào)用MessageboxA需要三個(gè)步驟:
1.
裝載動(dòng)態(tài)鏈接庫(kù)user32
.
dll。MessageBoxA是動(dòng)態(tài)鏈接庫(kù)user32
.
dll的導(dǎo)出函數(shù)。雖然大多數(shù)有圖形化操作界面的程序都已經(jīng)裝載了這個(gè)庫(kù),但是我們用來(lái)實(shí)驗(yàn)的consol版并沒(méi)有默認(rèn)加載它
2.
在匯編語(yǔ)言中調(diào)用這個(gè)函數(shù)需要獲得這個(gè)函數(shù)的入口地址
3?
在調(diào)用前需要向棧中按從右向左的順序壓入MessageBoxA的四個(gè)參數(shù)。當(dāng)然,我肯定壓如failwest啦,哈哈
對(duì)于第一個(gè)問(wèn)題,為了讓植入的機(jī)器代碼更加簡(jiǎn)潔明了,我們?cè)趯?shí)驗(yàn)準(zhǔn)備中構(gòu)造漏洞程序的時(shí)候已經(jīng)人工加載了user32
.
dll這個(gè)庫(kù),所以第一步操作不用在匯編語(yǔ)言中考慮。
對(duì)于第二個(gè)問(wèn)題,我們準(zhǔn)備直接調(diào)用這個(gè)API的入口地址,這個(gè)地址需要在您的實(shí)驗(yàn)機(jī)器上重新確定,因?yàn)閡ser32
.
dll中導(dǎo)出函數(shù)的地址和操作系統(tǒng)版本和補(bǔ)丁號(hào)有關(guān),您的地址和我的地址不一定一樣。
MessageBoxA的入口參數(shù)可以通過(guò)user32
.
dll在系統(tǒng)中加載的基址和MessageBoxA在庫(kù)中的偏移相加得到。為啥?看下看雪老大《軟件加密與解密》中關(guān)于虛擬地址這些基礎(chǔ)知識(shí)的論述吧,相信版內(nèi)也有很多相關(guān)資料。
這里簡(jiǎn)單解釋下,MessageBoxA是user32
.
dll的一個(gè)導(dǎo)出函數(shù),要確定它首先要知道user32
.
dll在虛擬內(nèi)存中的裝載地址(與操作系統(tǒng)版本有關(guān)),然后從這個(gè)基地址算起,找到MessageBoxA這個(gè)導(dǎo)出函數(shù)的偏移,兩者相加,就是這個(gè)API的虛擬內(nèi)存地址。
具體的我們可以使用VC6
.0
自帶的小工具“Dependency?Walker”獲得這些信息。您可以在VC6
.0
安裝目錄下的Tools下找到它:
?
圖
6
??
運(yùn)行Depends后,隨便拖拽一個(gè)有圖形界面的PE文件進(jìn)去,就可以看到它所使用的庫(kù)文件了。在左欄中找到并選中user32
.
dll后,右欄中會(huì)列出這個(gè)庫(kù)文件的所有導(dǎo)出函數(shù)及偏移地址;下欄中則列出了PE文件用到的所有的庫(kù)的基地址。
?
圖
7
??
如上圖示,user32
.
dll的基地址為
0x77D40000
,MessageBoxA的偏移地址為
0x000404EA
。基地址加上偏移地址就得到了MessageBoxA在內(nèi)存中的入口地址:
0x77D804EA
??
有了這個(gè)入口地址,就可以編寫進(jìn)行函數(shù)調(diào)用的匯編代碼了。這里我們先把字符串“failwest”壓入棧區(qū),消息框的文本和標(biāo)題都顯示為?“failwest”,只要重復(fù)壓入指向這個(gè)字符串的指針即可;第一個(gè)和第四個(gè)參數(shù)這里都將設(shè)置為NULL。寫出的匯編代碼和指令所對(duì)應(yīng)的機(jī)器代碼如下:
???????????
機(jī)器代碼(
16
進(jìn)制)??匯編指令??注釋
33?
DB??XOR?EBX
,
EBX??壓入NULL結(jié)尾的”failwest”字符串。之所以用EBX清零后入棧做為字符串的截?cái)喾菫榱吮苊狻癙USH?
0
”中的NULL,否則植入的機(jī)器碼會(huì)被strcpy函數(shù)截?cái)唷?br />
53??????????????????
PUSH?EBX??
68?77?65?73?74??
PUSH?
74736577??
68?66?61?69?6C??
PUSH?
6C696166??
8B?
C4????????????????MOV?EAX
,
ESP??EAX里是字符串指針
53??????????????????
PUSH?EBX??四個(gè)參數(shù)按照從右向左的順序入棧,分別為
:
?????????????????????????????????????????????????(
0
,
failwest
,
failwest
,
0
)
??????????????????????????????????????????????????
消息框?yàn)槟J(rèn)風(fēng)格,文本區(qū)和標(biāo)題都是“failwest”
50???????????????????
PUSH?EAX??
50???????????????????
PUSH?EAX??
53???????????????????
PUSH?EBX??
B8?EA?
04?
D8?
77??
MOV?EAX
,?
0x77D804EA??
調(diào)用MessageBoxA。注意不同的機(jī)器這里的????????????????????????????????????
????????????????????????????????????????????????????????????????????函數(shù)入口地址可能不同,請(qǐng)按實(shí)際值填入
!
FF?D0?????????????????CALL?EAX??
從匯編指令到機(jī)器碼的轉(zhuǎn)換可以有很多種方法。調(diào)試匯編指令,從匯編指令中提取出二進(jìn)制機(jī)器代碼的方法將在后面逐一介紹。由于這里僅僅用了
11
條指令和對(duì)應(yīng)的
26
個(gè)字節(jié)的機(jī)器代碼,如果您一定要現(xiàn)在就弄明白指令到機(jī)器碼是如何對(duì)應(yīng)的話,直接查閱Intel的指令集手工翻譯也不是不可以。
??將上述匯編指令對(duì)應(yīng)的機(jī)器代碼按照上一節(jié)介紹的方法以
16
進(jìn)制形式逐字抄入password
.
txt,第
53
到
56
字節(jié)填入buffer的起址
0x0012FAF0
,其余的字節(jié)用
0x90
(
nop指令
)
填充,如圖:
?
圖
8
換回文本模式可以看到這些機(jī)器代碼所對(duì)應(yīng)的字符:
?
圖
9
這樣構(gòu)造了password
.
txt之后在運(yùn)行驗(yàn)證程序,程序執(zhí)行的流程將按下圖所示:
圖
10
程序運(yùn)行情況如圖:
?
圖
11
成功的彈出了我們植入的代碼!
您成功了嗎?如果成功的喚出了藏在password
.
txt中的消息框,請(qǐng)?jiān)诟N中吱一下,和大家一起分享您喜悅的心情,這是我們學(xué)習(xí)技術(shù)的源動(dòng)力。
最后總結(jié)一下本節(jié)實(shí)驗(yàn)的幾個(gè)要點(diǎn):
確認(rèn)函數(shù)返回地址與buffer數(shù)組的距離——淹哪里
確認(rèn)buffer數(shù)組的內(nèi)存地址——把返回地址淹成什么(需要調(diào)試確定,與機(jī)器有關(guān))
編制調(diào)用消息框的二進(jìn)制代碼,關(guān)鍵是確定MessageBoxA的虛擬內(nèi)存地址(與機(jī)器有關(guān))
我實(shí)驗(yàn)用的PE和password
.
txt在這里:
想要PE的請(qǐng)點(diǎn)這里:stack_overflow_exec
.
rar
想要Passwrd
.
txt的請(qǐng)點(diǎn)這里:password
.
txt
這節(jié)課的題目是麻雀雖小,五臟俱全。這是因?yàn)檫@節(jié)課第一次把漏洞利用的全國(guó)程展現(xiàn)給了大家:
密碼驗(yàn)證程序讀入一個(gè)畸形的密碼文件,竟然蹦出了一個(gè)消息框!
Word在解析doc文檔時(shí),不知有多少個(gè)內(nèi)存復(fù)制和操作的函數(shù)調(diào)用,如果哪一個(gè)有溢出漏洞,那么office讀入一個(gè)畸形的word文檔時(shí),會(huì)不會(huì)彈出個(gè)消息框,開個(gè)后門,起個(gè)木馬啥的?
IIS和APACHE在解析WEB請(qǐng)求的時(shí)候,也不知道有多少內(nèi)存復(fù)制操作,如果存在溢出漏洞,那么攻擊者發(fā)送一個(gè)畸形的WEB請(qǐng)求,會(huì)不會(huì)導(dǎo)致server做出點(diǎn)奇怪的事情?
RPC調(diào)用中如果出現(xiàn)……
上面說(shuō)的并不是危言聳聽,全都是真實(shí)世界中曾經(jīng)出現(xiàn)過(guò)的漏洞攻擊案例。本節(jié)的例子是現(xiàn)實(shí)中的漏洞利用案例的精簡(jiǎn)版,用來(lái)闡述基本概念并驗(yàn)證技術(shù)可行性。隨著后面的深入討論,您會(huì)發(fā)現(xiàn)漏洞研究是多么有趣的一門技術(shù)。
在本節(jié)最后,我給出一個(gè)課后作業(yè)和幾個(gè)思考題——因?yàn)橄乱恢v可能會(huì)稍微隔幾天,大家不妨自己動(dòng)手練習(xí)練習(xí),記住光聽課是沒(méi)有的,動(dòng)手非常重要!
課后作業(yè):如果您細(xì)心的話,在點(diǎn)擊上面的ok按鈕之后,程序會(huì)崩潰:
?圖
12
??
這是因?yàn)镸essageBoxA調(diào)用的代碼執(zhí)行完成之后,我們沒(méi)有寫安全退出的代碼的緣故。您能把我給出的二進(jìn)制代碼稍微修改下,使之能夠在點(diǎn)擊之后干凈利落的退出進(jìn)程么?
如果你能做到這一點(diǎn),不妨把你的解決方案也拿出來(lái)和大家一起分享,一起進(jìn)步。
思考題:
1
:我反復(fù)強(qiáng)調(diào),buffer的位置在實(shí)驗(yàn)中需要自己在調(diào)試中確定,不同機(jī)器環(huán)境可能不一樣。
大家都知道,程序運(yùn)行中,棧的位置是動(dòng)態(tài)變化的,也就是說(shuō)buffer的內(nèi)存地址可能每次都不一樣,在真實(shí)的漏洞利用中,尤其是遇到多線程的程序,每次的緩沖區(qū)位置都是不同的。那么我們?cè)趺幢WC在函數(shù)返回時(shí)總能夠準(zhǔn)確的跳回buffer,找到植入的代碼呢
?
比較通用的定位植入代碼(shellcode)的方法我會(huì)在后面的講座中系統(tǒng)介紹,這里先提一下,大家可以思考思考
2
:我也反復(fù)強(qiáng)調(diào),API的地址需要自己確定,不同環(huán)境會(huì)有不同。這樣植入代碼的通用性還是會(huì)大打折扣。有沒(méi)有通用的定位windows?API的方法呢?
以上兩個(gè)問(wèn)題是影響windows平臺(tái)下漏洞利用穩(wěn)定性的兩個(gè)很關(guān)鍵的問(wèn)題。我選擇了windows平臺(tái)來(lái)講解,是為了照顧初學(xué)者對(duì)linux的進(jìn)入門檻和windows下美輪美奐的調(diào)試工具。但windows的溢出是相對(duì)linux較難的,進(jìn)入簡(jiǎn)單,深造難。不過(guò)我相信大家能啃下來(lái)的。
為了不至于在一節(jié)課中引入太多新東西,我在本節(jié)課中均采用現(xiàn)場(chǎng)調(diào)試確定的方法,并沒(méi)有考慮通用性問(wèn)題。在這里鼓勵(lì)大家積極思考,有想法別忘了在跟貼中分享出來(lái)。
|
|
公告
常用鏈接
留言簿(113)
隨筆分類
隨筆檔案
文章分類
相冊(cè)
Link
搜索
最新評(píng)論

閱讀排行榜
評(píng)論排行榜
|
|
不知道返回地址是植入的代碼在內(nèi)存中的地址還是在棧中的地址呢?在linux中,我將返回地址設(shè)置成棧中存放BUF的地址會(huì)造成錯(cuò)誤,提示內(nèi)存不可讀。(位置應(yīng)沒(méi)有設(shè)錯(cuò),可以改動(dòng)返回地址到別的函數(shù)去),但就是不能回到棧,這是怎么回事呢?
期待你的回答。
zhang_yuanming@126.com