首页
社区
课程
招聘
[原创]house of orange的进一步利用(house of orange+)
发表于: 2024-7-16 16:03 7150

[原创]house of orange的进一步利用(house of orange+)

2024-7-16 16:03
7150

在最近的WKCTF2024中,遇到了一道简单题目easy_heap。但是偶然间发现在以下条件满足时的一种利用方法:

在此情况下,可以通过house of orange的进一步利用。这里简记为house of range+。

在house of orange中,我们经常利用修改topchunk的大小来获得一个unsorted bin,本质上是触发了_int_malloc在use_top段调用的sysmalloc:

这是sysmalloc中对旧的topchunk的处理:

这里本质上就是释放一个大小为old_top的chunk,如果我们通过构造topchunk的大小,让其小于等于0xa0,那么就可以让old_top置入0x80大小的fastbin中。而后可以继续基于fastbin的攻击,如fastbin attack。

这里分析的是对应题目环境的glibc版本,版本为2.23。但是这个方法在高版本中仍然可用,被释放的old_top满足条件的话会进入tcache。

house of orange+可以在没有free而且要求不太严格的情况下快速构造攻击payload。

题目只有add, show, edit三个选项:

ida1

而且edit中存在任意长度溢出:

ida2

而且show中只显示chunk的前8个字节:

ida3

由于没有free,可以先利用house of orange构造unsorted bin,泄露libc地址;然后考虑上文介绍的方法,构造进入fastbin的chunk,打fastbin attack。

先构造unsorted bin,这里由于题目远程环境不稳定,不能接收过长的payload,所以透过申请多个chunk来控制topchunk的大小

orange1

这里我们切割unsorted bin中的chunk,泄露libc

orange2

接下来我们控制topchunksize的低12位为0x091

topchunk

然后修改topchunk的大小为0x90,触发_int_free将old_top置入fastbin

fastbin

这样我们就得到了一个fastbin。

可以通过chunk6的溢出打fastbin attack:

getshell

虽然有很多别的方法可以利用,但house of orange+可以更方便快速地找到攻击payload

use_top:
    victim = av->top;
    size = chunksize (victim);
 
    /*如果可以,就切割topchunk,返回被切下的chunk*/
    if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE)) {...}
 
    /* 如果topchunk大小不足,则尝试触发malloc_consolidate,合并fastbin */
    else if (have_fastchunks (av)) {...}
 
    /*如果上述情况都不满足需求,则触发sysmalloc*/
    else
    {
        void *p = sysmalloc (nb, av);
        if (p != NULL)
        alloc_perturb (p, bytes);
        return p;
    }
use_top:
    victim = av->top;
    size = chunksize (victim);
 
    /*如果可以,就切割topchunk,返回被切下的chunk*/
    if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE)) {...}
 
    /* 如果topchunk大小不足,则尝试触发malloc_consolidate,合并fastbin */
    else if (have_fastchunks (av)) {...}
 
    /*如果上述情况都不满足需求,则触发sysmalloc*/
    else
    {
        void *p = sysmalloc (nb, av);
        if (p != NULL)
        alloc_perturb (p, bytes);
        return p;
    }
if (old_size >= MINSIZE)
{
    set_head (chunk_at_offset (old_top, old_size), (2 * SIZE_SZ) | PREV_INUSE);
    set_foot (chunk_at_offset (old_top, old_size), (2 * SIZE_SZ));
    set_head (old_top, old_size | PREV_INUSE | NON_MAIN_ARENA);
    _int_free (av, old_top, 1); //将old_top释放
}
if (old_size >= MINSIZE)

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 3
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//