堆溢出
堆溢出是指程序向某個堆塊中寫入的字節數超過了堆塊本身可使用的字節數,因而導致了數據溢出,並覆蓋到物理相鄰的高地址的下一個堆塊。
前提
- 程序向堆上寫入數據
- 寫入的數據大小沒有被良好地控制
利用思路
1.覆蓋與其物理相鄰的下一個chunk的內容。
2.利用堆中的機制(如unlink等)來實現任意地址寫入或控制堆塊中的內容等效果,從而來控制程序的執行流。
off-by-one
off-by-one漏洞是一種特殊的溢出漏洞,off-by-one指程序向緩沖區中寫入時,寫入的字節數超過了這個緩沖區本身所申請的字節數並且只越界了一個字節。
前提
1.能夠溢出一個字節。
利用思路
1.溢出字節為可控制的任意字節:通過修改大小造成塊結構之間出現重疊,從而泄露其他塊數據,或是覆蓋其他塊數據。
2.溢出字節為NULL字節:在size為0x100的時候,溢出null字節可以使得prev_in_use位被清,這樣前塊會被認為是free塊。
- 這時可以選擇使用unlink方法進行處理。
- 另外,這時prev_size與就會啟用,就可以偽造prev_size,從而造成塊之間發生重疊。(2.28之前可以使用)
Chunk Extend and Overlapping
chunk extend是堆漏洞的一種常見利用手法,通過extend可以實現chunk overlapping的效果。
前提
- 程序中存在基於堆的漏洞。
- 漏洞可以控制chunk header中的數據。
利用思路
1.通過更改前一塊的大小來控制后一塊的內容。
2.通過更改pre_inuse域和pre_size域來控制當前塊的之前塊的內容。
unlink
unlink是bins中chunk的脫鏈操作,我們對chunk進行布局,然后借助unlink操作能夠達成修改指針的效果。
前提
1.unlink中存在檢查:
if (__builtin_expect (FD->bk != P || BK->fd != P, 0))
所以我們夠構造fakechunk的時候,要保證
fakeFD -> bk = fakeBK <=> *(fakeFD + 12) = fakeBK
fakeBK -> fd = fakeFD <=> *(fakeBK + 8) = fakeFD
2.存在UAF的chunk,可修改free狀態下smallbin或是unsorted bin的fd和bk指針。
3.已知位置存在一個指針指向可進行UAF的chunk。
利用思路
設指向可UAF chunk的指針的地址為ptr。
1.修改fd為ptr - 0x18
2.修改bk為ptr - 0x10
3.觸發unlink
ptr處的指針會變為ptr-0x18
use after free
Use After Free 就是其字面所表達的意思,當一個內存塊被釋放之后再次被使用。有以下幾種情況:
1.內存塊被釋放后,其對應的指針被設置為NULL,然后再次使用,程序自然會崩潰。
2.內存塊被釋放后,其對應的指針沒有被設置為NULL,然后在它下一次被使用之前,沒有代碼對這塊內存塊進行修改,那么程序和有可能可以正常運轉。
3.內存塊被釋放后,其對應的指針沒有被設置為NULL,但是在它下一次使用之前,有代碼對這塊內存進行了修改,,那么當程序再次使用這塊內存時,就很有可能出現奇怪的問題。
而我們一般所指的use after free漏洞主要是后兩種。我們一般稱被釋放后沒有被設置為NULL的內存指針為dangling pointer。
前提
1.存在dangling pointer。
利用思路
配合其他堆利用技巧使用。
fastbin attack
fastbin attack是一類漏洞的利用方法,是指所有基於fastbin機制的漏洞利用方法。主要有以下幾種:
- fastbin double free
- house of spirit
- alloc to stack
- arbitrary alloc
其中,前兩種主要漏洞側重於利用free函數釋放真的chunk或偽造的chunk,然后再次申請chunk進行攻擊,后兩種側重於故意修改fd指針,直接利用malloc申請指定位置chunk進行攻擊。
前提
1.存在堆溢出、use-after-free等能控制chunk內容的漏洞。
2.漏洞發生於fastbin類型的chunk中。
fastbin double free
Fastbin Double Free是指fastbin的chun 可以被多次釋放,因此可以在fastbin鏈表中存在多次。這樣導致的后是多次分配可以從fastbin鏈表中取出同一個堆塊,相當於多個指針指向同一個堆塊,結合堆塊的數據內容可以實現類似於類型混淆 (type confused) 的效果。
check
1.free fastbin chunk時會檢查當前free的chunk與fastbin表頭的chunk是否一致,一致則報double free錯誤。
繞過:兩次free之間free一個其他size的fastbin chunk。
2.malloc會對預分配位置的chunk驗證其size與當前fastbin鏈表的size相同,不同則報錯。
繞過:fake chunk的size要與fasbin的size一致。(size域中的A|M|P可以不同)
利用思路
1.double free同一個chunk(兩次free之間需要free一個其他size的fastbin chunk來繞過檢測)
2.通過fastbin double free后,我們實現了使用多個指針控制同一個堆塊,這可以用於篡改一些堆塊中的關鍵數據域或者是實現類似於類型混淆的效果。如果更進一步修改fd指針,則能夠實現任意地址分配堆塊的效果,這就相當於任意地址寫任意值的效果。
house of spirit
該技術的核心在於在目標位置處偽造fastbin chunk,並將其釋放,從而達到分配指定地址的chunk的目的。
check
1.fake chunk的ISMMAP位不能為1,因為free時,如果是mmap的chunk,會單獨處理。
2.fake chunk的size大小需要滿足對應的fastbin的需求。
3.fake chunk的next chunk的大小不能小於2 * SIZE_SZ,同時也不能大於av->system_mem。
4.fake chunk對應的fastbin鏈表頭部不能是該fake chunk,既不能構成double free的情況。
利用思路
構造好fake chunk,通過free再malloc的方式使得分配到fake chunk處,達到控制fake chunk地址處內容的目的。
alloc to stack
該技術的核心點在於劫持fastbin鏈表中chunk的fd指針,把fd指針指向我們想要分配的棧上,從而實現控制棧中的一些關鍵數據,比如返回地址等。
check
1.fake chunk的size大小需要滿足對應的fastbin的需求,也就是需要棧上存在有滿足條件的size值。
利用思路
通過該技術我們可以把fastbin chunk分配到棧中,從而控制返回地址等關鍵數據。
arbitrary alloc
Arbitrary Alloc其實與Alloc to stack是完全相同的,唯一的區別是分配的目標不再是棧中。事實上只要滿足目標地址存在合法的size域(這個size域是構造的,還是自然存在的都無妨),我們可以把chunk分配到任意的可寫內存中,比如bss、heap、data、stack等等。
check
1.fake chunk的size大小需要滿足對應的fastbin的需求。
利用思路
利用字節錯位等方法來繞過size域的檢驗,實現任意地址分配chunk,最后的效果也就相當於任意地址寫任意值。
unsorted bin attack
Unsorted Bin Attack,顧名思義,該攻擊與Glibc堆管理中的Unsorted Bin的機制緊密相關。
前提
1.能控制Unsorted Bin Chunk的bk指針。
利用思路
將bk指針改為target addr -16,再次malloc大於fast bin大小的chunk時(注意選擇的chunk不會被small bin分配),我們可以將target addr修改為較大的值。看起來似乎沒有什么用處,但是還可以這樣用:
1.通過修改循環的次數來使得程序可以執行多次循環。
2.修改heap中global_max_fast來使得更大的chunk可以被視為fast bin,這樣我們就可以去執行一些fast bin attack了。
large bin attack
基於large bin的漏洞利用方法
前提
1.可以修改一個large bin chunk的data。
2.從unsorted bin中來的large bin chunk要緊跟在被構造過的chunk后面。
利用思路
1.修改已經free的large bin中的bk為&stack_var1-2,bk_nextsize為&stack_var2-4
2.再次free一個比當前large bin大的large bin,就能把stack_var1和stack_var2的值為較大值(victim的地址)。
運用方法與unsorted bin類似,可以修改golbal_max_fast之類的全局變量為一個很大的值。
注意在堆風水排布時,注意每個chunk之間分配一個fastbin,防止free時chunk合並。
目前large bin題目較少,預計未來題目有更深入的large bin attack利用。
tcache attack
tcache是libc2.26以后引進的一種新的機制,有點類似與fast bin,不過它的優先級比fast bin高。free的時候當tcache滿了才放入fastbin,unsorted bin。tcache幾乎沒有什么檢測機制,使得利用方法較為多樣。
pwn tcache
利用思路
類似於fast bin attack
1.free掉一個chunk進入tcache bin。
2.修改tcache bin的next指針(也就是fd指針)為想要分配的地址。
3.malloc兩次,即分配到想要的地址。
而且相比較於fast bin attack,tcache bin attack沒有對size的檢查,利用空間更大。
tcache dup
利用思路
與fast bin dup類似,但是因為其沒有任何檢查,可以直接double free。
tcache house of spirit
利用思路
利用方法於fast bin的house of spirit一樣,一樣是構造fake chunk,先free在malloc,就能分配到fake chunk的地址。
smallbin unlink
利用思路
在申請內存塊符合smallbin大小並在smallbin內找到可用的空閑塊時,會把該smallbin鏈上的其他內存塊放入tcache中。放入tcache中時,一樣是做解鏈操作,但是沒有調用unlink宏來做,也就少了unlink中的檢查。使得可以通過unlink實現任意地址任意寫。
tcache stashing unlink attack
利用思路
這種攻擊利用的是tcache bin有剩余 (數量小於 TCACHE_MAX_BINS ) 時,同大小的small bin會放進tcache中 (這種情況可以用calloc分配同大小堆塊觸發,因為calloc分配堆塊時不從 tcache bin 中選取)。在獲取到一個smallbin中的一個chunk后會如果tcache仍有足夠空閑位置,會將剩余的small bin鏈入tcache ,在這個過程中只對第一個bin進行了完整性檢查,后面的堆塊的檢查缺失。當攻擊者可以寫一個small bin的bk指針時,其可以在任意地址上寫一個libc地址 (類似unsorted bin attack的效果)。構造得當的情況下也可以分配fake chunk到任意地址。
house of einherjar
house of einherjar是一種堆利用技術,由Hiroki Matsukuma提出。該堆利用技術可以強制使得malloc返回一個幾乎任意地址的chunk 。其主要在於濫用free中的后向合並操作(合並低地址的chunk),從而使得盡可能避免碎片化。
check
unlink有兩個檢查
1.需要滿足FD->bk == P && BK->fd == P
2.需要滿足chunksize(P) == prev_size (next_chunk(P)
利用思路
1.構造相應的fake chunk。
2.修改物理相鄰的高地址的chunk的 prev_size 與 PREV_INUSE 部分。
3.free掉高地址的chunk。
這樣我們就能獲得一個大的fake chunk,而且再次分配能分配到fake chunk地址處。如果高地址的chunk與top chunk相鄰,構造得當能夠分配任意地址。
house of force
基於top chcunk分配機制的利用
前提
1.能夠以溢出等方式控制到top chunk的size域。
2.能夠自由地控制堆分配尺寸的大小
check
glibc會對用戶請求的大小和top chunk現有的size進行驗證,如果size不夠大。就不會使用top chunk來進行分配。我們可以篡改size為一個很大值來繞過這個驗證。一般的做法是把top chunk的size改為-1,因為在進行比較時會把size轉換成無符號數,因此-1也就是說unsigned long中最大的數。
利用思路
1.篡改top chunk size。
2.計算想要分配的地址到top chunk的偏移(注意宏的計算,如果偏移不是MALLOC_ALIGN,需要具體調試才能確定malloc分配的大小)
3.malloc偏移大小的chunk,就能將top chunk移到想要分配的地址處。
4.再次malloc就能分配到想要分配的地址。
House of Lore
House of Lore攻擊與Glibc堆管理中的Small Bin的機制緊密相關。House of Lore可以實現分配任意指定位置的chunk,從而修改任意地址的內存。
前提
1.能夠控制small bin chunk的bk指針。
2.能夠控制指定位置chunk的fd指針。
check
分配small bin的時候,需要滿足bck->fd == victim。
利用思路
1.構造滿足條件的fake chunk1,然后分配大小一樣的small bin。
2.此時small bin尾部的bin返回給了用戶,fake chunk鏈接進small bin尾部。
3.故技重施,構造滿足條件的fake chunk2,然后分配一樣的small bin。
4.現在我們就能分配到fake chunk1處。
house of orange
House of Orange 的利用比較特殊,首先需要目標漏洞是堆上的漏洞但是特殊之處在於題目中不存在 free 函數或其他釋放堆塊的函數。我們知道一般想要利用堆漏洞,需要對堆塊進行 malloc 和 free 操作,但是在 House of Orange 利用中無法使用 free 函數,因此 House of Orange 核心就是通過漏洞利用獲得 free 的效果。這種操作的原理簡單來說是當前堆的 top chunk 尺寸不足以滿足申請分配的大小的時候,原來的 top chunk 會被釋放並被置入 unsorted bin 中,通過這一點可以在沒有 free 函數情況下獲取到 unsorted bins。
check
想要偽造top chunk size,必須滿足以下要求
1.偽造的size必須要對齊到內存頁。
2.size要大於MINSIZE。
3.size要小於之后申請的chunk size + MINISIZE。
4.size的prev inuse位必須為1。
5.malloc的大小不能大於mmap分配閾值。
利用思路
1.篡改top chunk size(注意size需要對齊內存頁)
2.分配比top chunk size大的chunk。
3.現在原來的top chunk進入了unsorted bin中,再次malloc就會從unsored bin中切分出需要的大小,剩余部分作新的unsorted bin。
house of rabbit
House of rabbit 是一種偽造堆塊的技術,我們一般運用在 fastbin attack 中,因為 unsorted bin 等其它的 bin 有更好的利用手段。
前提
1.可以修改fastbin的fd指針或size。
2.可以觸發malloc consolidate。
利用思路
原理很簡單,就是通過修改 fastbin chunk 的 size 直接構造 overlap chunk,或者修改 fd,讓它指向一個 fake chunk,觸發 malloc consolidate 之后讓這個 fake chunk 成為一個合法的 chunk。
house of roman
House of Roman 這個技巧說簡單點其實就是 fastbin attack 和 Unsortbin attack 結合的一個小 trick。該技術用於 bypass ALSR,利用 12-bit 的爆破來達到獲取 shell 的目的。且僅僅只需要一個 UAF 漏洞以及能創建任意大小的 chunk 的情況下就能完成利用。
利用思路
內容來源
(CTF Wiki)[https://ctf-wiki.github.io/ctf-wiki/]