學(xué)習(xí)地址:pan.baidu.com/s/1EzedMxjmP8lyxlJ_KMMlig?pwd=gdwa
個人視角剖析PWN棧溢出核心難點:從“崩潰”到“控制”
在二進制安全領(lǐng)域,棧溢出(Stack Overflow)是最經(jīng)典、最基礎(chǔ),也最能考驗學(xué)習(xí)者底層功底的漏洞類型。很多人對它的認知停留在“輸入超長數(shù)據(jù)覆蓋返回地址”的淺層理解上。然而,當(dāng)我真正深入PWN的世界,嘗試編寫Exploit繞過層層防護機制時,才意識到棧溢出的核心難點遠不止于此。
本文從一個學(xué)習(xí)者的個人視角出發(fā),不貼大量匯編代碼,而是剖析棧溢出利用過程中真正令人頭疼的思維斷點與技術(shù)卡點,希望能幫助那些在PWN入門路上感到困惑的朋友,看清迷霧背后的本質(zhì)。
一、難點的本質(zhì):看不見內(nèi)存布局與寄存器狀態(tài)
棧溢出的第一個核心難點,在于抽象思維到具體內(nèi)存的映射。
編程時,我們習(xí)慣于變量名、函數(shù)名、指針等抽象概念。但PWN要求我們必須在腦海中時刻構(gòu)建出具體的棧幀布局圖:局部變量在哪個地址?返回地址保存在哪里?EBP/RBP寄存器指向何處?當(dāng)輸入一個200字節(jié)的字符串時,它是如何從低地址向高地址填充棧空間的?
很多初學(xué)者在學(xué)習(xí)ret2text(直接跳轉(zhuǎn)到代碼段中的后門函數(shù))時,容易犯一個根本性錯誤:他們以為只要覆蓋返回地址即可,卻忽視了棧幀平衡。實際上,當(dāng)函數(shù)返回時,不僅會彈出返回地址到EIP/RIP,還會恢復(fù)舊的EBP/RBP。如果覆蓋的數(shù)據(jù)不慎將保存的EBP也破壞成非法值,即使EIP跳轉(zhuǎn)成功,程序后續(xù)的棧行走也可能崩潰。
這個難點通過大量畫圖可以逐漸克服——每次分析漏洞時,在紙上畫出被攻擊函數(shù)的棧布局,標(biāo)注每個輸入字節(jié)對應(yīng)覆蓋哪個位置。幾個月后,這種“腦內(nèi)調(diào)試”的能力會成為本能。
二、防護機制下的“矛與盾”:需要逐層突破的壁壘
現(xiàn)代操作系統(tǒng)開啟了層層防護,使得基礎(chǔ)的棧溢出利用幾乎失效。每個防護都對應(yīng)一個需要理解并設(shè)法繞過的技術(shù)難點。
1. ASLR(地址空間布局隨機化):庫函數(shù)、?;贰⒍训刂访看芜\行都隨機化。直接硬編碼shellcode地址或system函數(shù)地址是不行的。核心難點在于:如何在沒有泄漏的情況下獲取有效地址?解決思路通常是先利用信息泄漏漏洞(如格式化字符串、未初始化的變量)讀出某個地址,再基于固定偏移計算出所需地址。換句話說,單純的棧溢出往往不夠,還需要信息泄漏原語配合。
2. NX(數(shù)據(jù)執(zhí)行保護):棧內(nèi)存不可執(zhí)行。Shellcode放在棧上跳轉(zhuǎn)過去沒有意義。核心難點:如何讓程序執(zhí)行已有代碼(如libc中的system或execve)?這就引出了ret2libc技術(shù)——需要知道libc基址,且需要布置函數(shù)參數(shù)到正確寄存器或棧上。難點升級為:參數(shù)如何傳遞(32位棧傳參、64位寄存器優(yōu)先)?如果system函數(shù)地址含有x00字節(jié)怎么辦?這些都涉及到對調(diào)用約定的精細控制。
3. Canary(棧 cookies):函數(shù)序言時在棧上放置一個隨機值,返回前檢查是否被修改。這是最令人頭疼的防護。直接覆蓋返回地址必然同時覆蓋canary,觸發(fā)__stack_chk_fail。核心難點:如何在不觸發(fā)檢測的情況下繞過canary?常見思路包括:泄漏canary值(通過同時存在的其他漏洞,或者按字節(jié)爆破)、攻擊線程存儲的canary副本、或者覆蓋異常處理句柄而非返回地址。但無論如何,canary的存在迫使攻擊者從“單步覆蓋”升級為“多階段信息搜集”。
三、64位與32位的差異:寄存器的陌生世界
從32位轉(zhuǎn)向64位,棧溢出利用的難度陡增。32位下函數(shù)參數(shù)全部壓棧,覆蓋返回地址后直接在棧上布置參數(shù)即可。而64位遵循System V調(diào)用約定:前六個整數(shù)或指針參數(shù)依次通過RDI、RSI、RDX、RCX、R8、R9傳遞,多出的參數(shù)才壓棧。
這意味著:僅僅覆蓋返回地址調(diào)用system還不夠,還需要控制RDI寄存器指向"/bin/sh"字符串。核心難點:如何控制寄存器?這就需要ROP(返回導(dǎo)向編程)——尋找程序中的pop rdi; ret等指令片段(gadget),將它們串聯(lián)起來。第一步是溢出后跳轉(zhuǎn)到pop rdi的地址,將棧上的下一個值("/bin/sh"地址)彈出到RDI,再執(zhí)行ret跳轉(zhuǎn)到system。這個過程必須精確計算棧指針的移動,稍有不慎就會導(dǎo)致段錯誤。
尋找gadget、計算偏移、構(gòu)造ROP鏈,是64位棧溢出利用的核心門檻。它要求學(xué)習(xí)者對指令編碼和棧的變化有精確的理解。
四、調(diào)試能力的瓶頸:紙上談兵終覺淺
所有理論在遇到實際二進制時,都會受到嚴(yán)峻考驗。真正的難點在于:如何確認exploit失敗的原因?
是覆蓋的偏移算錯了?是ROP鏈中某個gadget地址含有x0a導(dǎo)致輸入函數(shù)截斷?還是system成功執(zhí)行但shell一閃而過(因為標(biāo)準(zhǔn)輸入輸出被重定向)?新手往往面對Program received signal SIGSEGV束手無策。
我個人的經(jīng)驗證明,突破瓶頸的唯一方法是耐心地在調(diào)試器(GDB + pwndbg/peda)中單步跟蹤。觀察每個push、pop、ret指令后RSP和RIP的變化;查看info registers確認寄存器是否為預(yù)期值;用tele命令查看棧上數(shù)據(jù)布局。無數(shù)次踩過坑,再回頭查閱調(diào)用約定、字節(jié)序、內(nèi)存布局等基礎(chǔ)概念,才能真正理解漏洞利用的底層邏輯。
五、刻意練習(xí):從“跟著寫”到“獨立推導(dǎo)”
最后一個核心難點,也是學(xué)習(xí)者最容易忽視的:如何形成獨立分析漏洞的能力。
觀看教學(xué)視頻時,師傅直接給出了偏移量、gadget地址和exploit代碼,一切行云流水。但輪到自己操作一個陌生的程序時,卻無從下手。這是因為在跟隨過程中沒有主動思考:為什么偏移是40字節(jié)而不是44?為什么選這個gadget而不選另一個?ROPgadget出來的地址如何驗證是否真的可用?
要跨過這道坎,必須進行刻意練習(xí)。拿到一個CrackMe或CTF題目后,盡量不要直接看Writeup,嘗試完成以下步驟:
自己計算偏移:用pattern create和pattern offset,或用手工輸入遞增字符串,通過崩潰時的RIP值反推偏移。
手動搜集gadget:用ROPgadget --binary 輸出所有結(jié)果,自己篩選需要的pop rdi; ret。然后結(jié)合二進制文件的基址(沒有PIE時直接使用)構(gòu)造ROP鏈。
構(gòu)建最小poc:先用最簡單的方式(如ret2text)驗證偏移是否正確;再升級到ret2libc或ROP鏈。每一步失敗了,就回到調(diào)試器找原因。
這個過程很煎熬,但只有走過幾次完整的獨立推導(dǎo),才能將零散的知識點串聯(lián)成動態(tài)的、可操作的漏洞利用方法論。
結(jié)語
棧溢出雖然經(jīng)典,但它的核心難點始終圍繞著內(nèi)存布局的可視化、防護機制的對抗策略、64位調(diào)用約定的控制、以及調(diào)試能力的耐心磨練。從“讓程序崩潰”到“精確控制它的執(zhí)行流”,這是一場對底層知識、逆向思維和調(diào)試功力的綜合考驗。
PWN的學(xué)習(xí)沒有捷徑。那些令人頭疼的SIGSEGV、錯位的棧幀、難以尋覓的gadget,都是走向深層理解的必經(jīng)路標(biāo)。每當(dāng)在黑暗中摸索并最終成功彈出Shell的那一刻,你會感到之前所有的掙扎都是有價值的。而你也在這一過程中,真正掌握了棧溢出利用的精髓。
審核編輯 黃宇
-
PWN
+關(guān)注
關(guān)注
0文章
14瀏覽量
17060
發(fā)布評論請先 登錄
DMA傳輸完成通知未在S32K324上的半滿緩沖區(qū)時觸發(fā),為什么?
C語言的緩沖區(qū)(緩存)詳解
CW32L052串口的緩沖區(qū)機制
飛凌嵌入式ElfBoard-標(biāo)準(zhǔn)IO接口之設(shè)置緩沖區(qū)
【道生物聯(lián)TKB-623評估板試用】+3、模塊深度測評:高頻率數(shù)據(jù)傳輸?shù)?b class='flag-5'>緩沖區(qū)陷阱與優(yōu)化方案
移植的lvgl,在運行的時候,緩沖區(qū)無法釋放怎么解決?
如何清除CYUSB3014的緩沖區(qū)數(shù)據(jù)?USB接口數(shù)據(jù)什么時候發(fā)送到電腦?
USB緩沖區(qū)中的內(nèi)容滿了之后,是否有標(biāo)志位進行反饋?
請問USB緩沖區(qū)取數(shù)據(jù)可以多次取嗎?
socket緩沖區(qū)溢出的原因?怎么解決?
解析RZ/N2L CANFD模塊的緩沖區(qū)機制(2)
解析RZ/N2L CANFD模塊的緩沖區(qū)機制(1)
緩沖區(qū)溢出-CTF-PWN
評論