藉助hitcon training
的題目對三種堆的利用方法進行了一個系統的學習,剛入坑的堆小白們可以一起學習一下。題目鏈接:https://github.com/scwuaptx/HITCON-Training
Use after free
記錄一波建立文件過程
mkdir + name touch + name echo 'context' > name cat name
hacknote(Hitcon training lab10)
這是一個典型的use after free
很適合初次接觸的人進行練習
程序功能分析
可以發現是一個note
,這裏有三個功能
add_note
可以發現add的功能是添加字條,第一個段是8字節然後用來儲存函數指針 第二段是用來儲存我們的輸入的
del_note
這裏可以發現del是一個刪除操作,但是並沒有讓指針置0所以存在use after free
漏洞
ptint_note
是一個調用函數指針的一個過程
解題思路
- 一、先申請
chunk1
,chunk2
其中大小隨意不要超過fastbin
的範圍就可以了 - 二、
free chunk1
free chunk2
- 三、此時
fastbin
中的分佈是 chunk2(8) -> chunk1(8)
chunk2(32) -> chunk1(32)
- 四、這個時候申請一個
chunk3
大小爲8 這個時候系統先分配chunk1(8)
的大小存放puts函數
然後分配chunk2(8)
作爲我們的context
這個時候我們可以在這裏寫上magic函數
執行獲取flag
exp:
總結:
簡單的說use after free
就是利用free
之後指針沒有被設置成NULL
然後我們可以在此malloc
出來使用。
house of force(Hitcon training lab11)
read函數
第三個參數爲unsigned
符號,當-1
時及0xffffffff
任意大小讀
利用需要滿足的條件
- 首先,需要存在漏洞使得我們可以控制
top chunk
的size域
- 其次,需要我們可以自由的控制
malloc
分配的大小 - 分配的次數不能受限制
bamboobox
這裏利用house of force
進行利用,題目的下方會對house of force
進行一個原理講解
程序功能分析
main
- 這裏可以發現開始時程序分配了
0x10
的空間給hello message
和goodbye_message函數
- 進行一個循環讓我們進行菜單欄選項
menu
這裏可以看見這裏總共有5個選項其中選項1就是show item
,remove
就是正常的刪除操作,5是正常的退出操作。接下來我們仔細看2,3兩個選項
add a new item
- 這裏程序先讓我們選擇長度,驚喜驚喜!可以看出長度我們時可以任意控制的,隨意
malloc
- 然後輸入們的
item
值就可以了
change the item in the box
修改物品的名字,根據給定的索引,以及大小,向指定索引的物品中讀取指定長度名字。這裏長度由用戶來讀入,也存在任意長度堆溢出的漏洞。
magic
這裏有一個我們的flag文件
可以讓我們利用
利用思路
- 先
malloc
一個塊 - 利用
change the item in the box
進行長度的修改使得我們可以覆蓋到top chunk
的size位置修改top chunk size=-1
(因爲在其中size是無符號整數-1
會被解釋爲0xffffff
)所以size肯定就夠我們用了 - 接着我們利用
house of force
的方法將top chunk
的位置放在heap base地址
- 然後我們再申請一個
0x10
的塊,去修改函數指針爲我們Magic
的地址 整個利用這樣就完成
exp:
總結:
這裏利用house of force
- 這個利用過程的條件必須要滿足那三點
- 然後是修改
top chunk
的大小 - 然後是利用
malloc
將top chunk
放置到我們需要改寫的那個地址上,可以是got表
的地址可以是分配的堆塊地址。
Double free(Hitcon training lab12)
故名思義,就是對一個堆塊進行了兩次free, 但是free了同一個堆塊兩次,其中在glibc中對此有一個檢查
其中是檢查main_arean
是否指向向了原來的一個chunk
,這個就是非常容易繞過的只需要free(p1);free(p2);free(p1)
就可以繞過了。
利用過程
這是我們執行doublefree
之後的圖,此時malloc
出chunk1
,更改chunk1
的fd
,又因爲此時chunk1
是在fastbin list
,也就是結構變成了下圖
可以看見現在fastbin list
中會多指向一個我們的fakebin
(此時就可以進行任意地址寫了)
check_fail
if (__builtin_expect (fastbin_index (chunksize (victim)) != idx, 0)) { errstr = "malloc(): memory corruption (fast)"; errout: malloc_printerr (check_action, errstr, chunk2mem (victim)); return NULL; }
其中會有一個對fakebin
,size
大小的檢查,如果不滿足當前fastbin鏈
中應該有的大小則會顯示異常。
例題:
程序功能分析
main
堆題一般都是些菜單題,這又是一道菜單題
add
add函數就是正常的malloc出堆塊,然後輸入一些數據,這裏並沒什麼漏洞
visit
visit函數就是遍歷剛纔我們所有建立的東西
del
一個刪除函數,其中對指針進行了置0所以無法使用use after free,但是這裏似乎可以利用double free
clean
把所有已經創建了的都進行一個了刪除
magic
這是一個get_flag
的函數
利用思路
利用的思路還是比較明顯的,利用double free
進行一個got表
的改寫。首先add函數
建立2個堆塊,然後free(chunk1)->free(chunk2)->free(chunk1)
進行一個檢查的bypass
。然後再執行add函數
,進行chunk1堆塊
的fd指針
改寫,然後連續free出chunk2,chunk1
和我們構造的fake_chunk
(這個chunk
的地址在got表
上),對got表
進行一個覆寫,將puts函數``got表
改寫成magic函數
的地址。
注意事項
因爲要bypass
對fakebin_size
的檢查,所以在選got表
地址的時候需要gdb調試
一下,看存儲的數的低四位滿足要求,這裏就選用了0x601ffa
,剛好可以滿足條件
exp:
總結
從這些3個利用方式來看,堆的學習主要是建立在對源碼和對堆分配,回收等操作的熟悉的基礎上。這裏推薦用pwndbg
進行調試,還有一些大佬會用gef
和peda
以及一些插件的方法進行調試,具體看個人的習慣了。