常回家看看之off_by_one

CH13hh發表於2024-05-20

❗off_by_one這個漏洞比較特殊,它不像上一期的堆溢位,可以溢位很多位元組,它只能溢位一個位元組,在棧裡面也可以透過這個漏洞修改返回地址什麼的,在堆裡面我們主要利用它來修改堆塊的大小形成fake_chunk也就可以進行堆的重疊,在64位的時候如果申請0x18,0x28,0x38這樣的堆它的size位是0x21,0x31和0x41,那為什麼,頭部0x10加申請的0x18大小已經是0x28大小了為啥size還是0x21,別忘了,當上一個chunk正在使用的時候下一個chunk的prev_size位也拿來當我們的資料部分。

那麼我們就可以利用這個特性來進行off_by_one,那樣就可以修改下一個chunk的size位。

我們拿一道題目來具體復現一下這個漏洞。✅

題目連結:https://pan.baidu.com/s/1BBT95PNOuffZv1r_1Cacbg?pwd=kj9t
提取碼:kj9t

1.養成好習慣首先看保護

常回家看看之off_by_one

2.不如不看🙃,哈哈,開玩笑的,保護全開,但是不要慌,對於堆題目這很正常,我們用64位ida看一下

常回家看看之off_by_one

常回家看看之off_by_one

3.還是一些功能函式,add新增chunk

常回家看看之off_by_one

4.edit函式

常回家看看之off_by_one

這裡主要在輸入size的時候進行了一次判斷,就是sub_E3A這個函式

常回家看看之off_by_one

如果輸入的size減去申請chunk的size等於10的話會返回a1加1,也就是我們在chunk size的基礎上可以多輸入一個位元組,滿足off_by_one

5.show函式和delete函式

常回家看看之off_by_one

我們先申請兩個chunk,第一個是0x18,0x28,0x38之類的

常回家看看之off_by_one

現在編輯第一個堆進行溢位一個位元組修改下一個chunk的size位

常回家看看之off_by_one

修改之前

常回家看看之off_by_one

修改之後

常回家看看之off_by_one

常回家看看之off_by_one

注意此時雖然修改成功了,但是堆結構被我們破壞了,top chunk距離上一個chunk距離不是0x40了,所以我們繼續申請一個堆,來恢復堆結構

常回家看看之off_by_one

恢復之後此時堆結構
常回家看看之off_by_one

之後我們把chunk1 free掉

常回家看看之off_by_one

常回家看看之off_by_one

我們再次申請回來,發現原來的0x91不見了

常回家看看之off_by_one

那麼我們再次構造unsortbin chunk

常回家看看之off_by_one

常回家看看之off_by_one

我們free2 的時候就會得到unsortbin,但是記得再申請一個堆,不然free的時候會和top chunk合併

常回家看看之off_by_one

常回家看看之off_by_one

在2.23版本里面洩露出的地址-0x58就是main_arena的地方而main_arena-0x10就是__malloc_hook地址

常回家看看之off_by_one

然後這裡使用fatsbin attack 申請到_malloc_hook和recalloc_hook附近修改它們的值,(一般都是__malloc_hook-0x23)

因為這裡符合size的結構

常回家看看之off_by_one

這裡要注意並不是修改__malloc_hook為one_gadget就可以getshell,通常可以使用realloc_hook 調整棧幀使 onegadget 生效

將 malloc_hook 劫持為 realloc ,realloc_hook 劫持為 onegadget ,實際執行順序:

malloc -> malloc_hook -> realloc -> realloc_hook -> onegadget

這樣就能經過 realloc 調整棧幀後再執行 onegadget 。但是實際情況中,並不是直接劫持 malloc_hook 為 realloc ,而是要加上一定的偏移,也就是調整 push 的數量,讓棧幀結構滿足 onegadget 執行

常回家看看之off_by_one

最後放上exp: 程式碼還是有點多的

常回家看看之off_by_one

常回家看看之off_by_one

相關文章