House Of Force
首先介紹一下什麼是House Of Force
House Of Force 是一種堆利用方法,但是並不是說 House Of Force 必須得基於堆漏洞來進行利用。如果一個堆 (heap based) 漏洞想要透過 House Of Force 方法進行利用,需要以下條件:
- 能夠以溢位等方式控制到 top chunk 的 size 域
- 能夠自由地控制堆分配尺寸的大小
一句話來說,如果我們可以控制top chunk的指標,那麼我們就可以達到任意地址寫,但是glibc對申請chunk進行了驗證
// 獲取當前的top chunk,並計算其對應的大小
victim = av->top;
size = chunksize(victim);
// 如果在分割之後,其大小仍然滿足 chunk 的最小大小,那麼就可以直接進行分割。
if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE))
{
remainder_size = size - nb;
remainder = chunk_at_offset(victim, nb);
av->top = remainder;
set_head(victim, nb | PREV_INUSE |
(av != &main_arena ? NON_MAIN_ARENA : 0));
set_head(remainder, remainder_size | PREV_INUSE);
check_malloced_chunk(av, victim, nb);
void *p = chunk2mem(victim);
alloc_perturb(p, bytes);
return p;
}
但是當我們把size的值改成一個很大的值比如0xffffffffffffffff,那麼就可以輕鬆繞過這個驗證,一般的做法是把size改成-1,因為在進行比較時會把 size 轉換成無符號數,因此 -1 也就是說 unsigned long 中最大的數,所以無論如何都可以透過驗證。
remainder = chunk_at_offset(victim, nb);
av->top = remainder;
/* Treat space at ptr + offset as a chunk */
#define chunk_at_offset(p, s) ((mchunkptr)(((char *) (p)) + (s)))
之後會把top指標進行更新,然而size段也會更新更新方法如下
victim = av->top;
size = chunksize(victim);
remainder_size = size - nb;
set_head(remainder, remainder_size | PREV_INUSE);
所以,如果我們想要下次在指定位置分配大小為 x 的 chunk,我們需要確保 remainder_size 不小於 x+ MINSIZE。
題目連結:連結:https://pan.baidu.com/s/1lr2jAQwL9Ow5FVjzrSfbWA 提取碼:tx88
檢視保護,pie保護關閉
64位ida載入
首先發現了後門函式
add函式
edit函式
值得注意的是這個函式並沒有對我們輸入的新長度進行判斷,那麼我們就可以修改到top chunk的siez域,實現House Of Force
先貼一下wp我再詳細解釋
現在看看除錯
-0x70怎麼來的
前面我說了需要將top thunk指向我們想要的地方,那麼0xf262a0-0xf26260=0x50,而0x10是因為chunk頭部有0x10大小,因此我我們下次申請的chunk的起始地址是0xf26250 + 0x10 = 0xf26260,然後我們再修改地址為flag地址再進行呼叫就可以得到flag
以上均為本人理解,有任何錯誤煩請各位師傅即使指出
參考文章 https://tty-flag.github.io/2021/04/20/House-Of-Force.html