House Of Force

CH13hh發表於2024-04-22

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

相關文章