❗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.養成好習慣首先看保護
2.不如不看🙃,哈哈,開玩笑的,保護全開,但是不要慌,對於堆題目這很正常,我們用64位ida看一下
3.還是一些功能函式,add新增chunk
4.edit函式
這裡主要在輸入size的時候進行了一次判斷,就是sub_E3A這個函式
如果輸入的size減去申請chunk的size等於10的話會返回a1加1,也就是我們在chunk size的基礎上可以多輸入一個位元組,滿足off_by_one
5.show函式和delete函式
我們先申請兩個chunk,第一個是0x18,0x28,0x38之類的
現在編輯第一個堆進行溢位一個位元組修改下一個chunk的size位
修改之前
修改之後
注意此時雖然修改成功了,但是堆結構被我們破壞了,top chunk距離上一個chunk距離不是0x40了,所以我們繼續申請一個堆,來恢復堆結構
恢復之後此時堆結構
之後我們把chunk1 free掉
我們再次申請回來,發現原來的0x91不見了
那麼我們再次構造unsortbin chunk
我們free2 的時候就會得到unsortbin,但是記得再申請一個堆,不然free的時候會和top chunk合併
在2.23版本里面洩露出的地址-0x58就是main_arena的地方而main_arena-0x10就是__malloc_hook地址
然後這裡使用fatsbin attack 申請到_malloc_hook和recalloc_hook附近修改它們的值,(一般都是__malloc_hook-0x23)
因為這裡符合size的結構
這裡要注意並不是修改__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 執行
最後放上exp: 程式碼還是有點多的