PWN-堆基础之Unsafe Unlink
Unsafe Unlink
1.unsorted bin
首先介绍unsorted bin,unsortedbin 是一个双向链表的结构,因此a中这两个指针分别是bk和fd,分别指向前一个和后一个chunk;free时,若该chunk没有紧邻top chunk,则不会与top chunk进行合并,它首先被链入unsorted bin中,被首次分配时,unsorted bin会扫描各chunk并根据大小链入不同bin中。
2.Unsafe Unlink
简介
Unsafe Unlink指的是早期unlink,没有大小检查、双向链表完整性检查,并且没有NX保护
当进行unlink时,会执行如下操作:
1 | this->fd->bk = this->bk; |
因此,如果我们能够伪造fd和bk的指向,就可以实现任意地址写入,而要进行unlink操作我们需要修改next_chunk的pre_inuse为0,这是free掉next_chunk会使这两个chunk进行合并。
条件
未开启NX保护。
程序存在堆溢出漏洞可以覆盖next_chunk的prev_size和size域或存在UAF漏洞。
可以泄露出libc地址和堆的基地址。
利用
- 在当前chunk中写入shellcode,这里的shellcode比较特殊,由于unlink时会覆盖掉一部分
shellcode代码,因此需要jmp和nop配合。
伪造当前chunk的fd = &__free_hook - 0x18,bk = 当前chunk的地址 + 0x20(shellcode地址)。
利用堆溢出或UAF伪造next chunk的prev_size为当前chunk大小,然后将next chunk的size域中
prev_inuse标志位置0。
- free(next_chunk),程序会误认为当前chunk已释放而执行unlink操作:
首先,根据next_chunk的prev_size计算出当前chunk的地址。
然后,根据fd找到前面的fake_chunk,在fake_fd + 0x18地址写入bk指针。
然后,根据bk找到后面的fake_chunk,在fake_bk + 0x10地址写入fd指针。
完整构造如下:
1 | a = malloc(0x88) |