2026年4月6日,Voorivex 红队向 Adminer 官方上报了三个 0-day 漏洞,覆盖预认证 RCE、存储型 XSS 和认证后 RCE 三种攻击路径。官方在 5.4.3 版本中修复了全部问题,但这些漏洞的存在本身值得所有 Adminer 用户警惕——一个被遗忘在服务器上的 adminer.php,可能正在静默等待被攻陷。
一、漏洞概述
Adminer 是一款相当流行的开源数据库管理工具,只以一个 PHP 文件的形式分发,全球数百万开发者把它部署在服务器上管理数据库。“单文件搞定一切”确实方便,但反过来也意味着:一旦这个文件暴露在公网,攻击面就会成倍放大。
这次 Voorivex 团队披露的三个 0-day 汇总如下:
| 漏洞编号 |
类型 |
认证要求 |
CVSS |
影响版本 |
| CVE-2026-56705 |
MSSQL PDO DSN注入RCE |
预认证 |
9.8 |
< 5.4.3 |
| CVE-2026-56704 |
MySQL版本字符串存储型XSS |
预认证 |
6.1 |
< 5.4.3 |
| CVE-2026-56703 |
SQLite VACUUM INTO文件写入RCE |
已认证 |
7.2 |
< 5.4.3 |
其中危害最高的是 CVE-2026-56705:完全不需要认证,只要 Adminer 配置了 MSSQL/Azure SQL 后端,攻击者在未登录状态下就能拿到服务器远程命令执行权限。
二、CVE-2026-56705:MSSQL PDO DSN 注入(预认证 RCE)
攻击面为何这么大
这个漏洞最危险的地方在于触发条件几乎为零:攻击者只要能访问 Adminer 登录页,无需任何凭证就可以发起攻击。而且 MSSQL/Azure SQL 在企业环境里非常常见,不少开发者图省事把 adminer.php 留在 Web 根目录,等于给了攻击者现成的入口。
漏洞原理:ODBC 参数的注入链
根源在于 Adminer 在构建 MSSQL PDO DSN 时,没有对用户提交的服务器地址做充分过滤。攻击者只要在连接参数里注入一个分号(;),就能往 DSN 字符串中追加任意 ODBC 驱动参数。
核心用到的两个 ODBC 参数是 TraceFile 和 TraceOn。当 DSN 被构造成下面这样:
sqlsrv:Server=127.0.0.1;TraceFile=shell.php;TraceOn=1
ODBC 驱动在建立连接之前,会先打开 TraceFile 指定的文件并写入连接元数据。关键点在于:这个写入过程会把攻击者控制的 UID={...} 字段一并记录进去,而这一字段完全可以注入 PHP 代码。
攻击流程
完整攻击链大致如下:
- 攻击者构造恶意服务器地址,例如
Server=127.0.0.1;TraceFile=shell.php;TraceOn=1;UID=<?php system($_GET['cmd']);?>
- 在登录页的服务器地址字段里提交该内容。
- Adminer 把这个字段直接拼进 PDO DSN 字符串,交给 sqlsrv PDO 驱动。
- ODBC 驱动尝试连接,先把包含攻击者注入 PHP 代码的连接元数据写入
shell.php。
- 连接随后失败并返回错误,但恶意文件已经落到 Web 目录。
- 攻击者再请求
shell.php?cmd=id,即可执行任意命令。
这是一种典型的“副作用型”文件写入:连接失败了,写入却在失败之前完成。
影响范围
所有使用 Adminer 连接 MSSQL 或 Azure SQL、并且 adminer.php 暴露在公网的部署都会受影响。由于漏洞触发于登录认证之前,攻击门槛几乎为零。
三、CVE-2026-56704:MySQL 版本字符串存储型 XSS
CSP 绕过的精妙之处
Content Security Policy(CSP) 是现代浏览器提供的核心安全机制之一,可以有效阻断存储型 XSS 的脚本执行。不过 CSP 并非牢不可破:一旦攻击者能控制带有效随机数(nonce)的 script 标签内容,CSP 防护就基本失效了。
CVE-2026-56704 正是踩中了这个点。Adminer 会在登录页展示所连数据库服务器的版本信息,这个版本字符串被直接渲染到一个带 nonce 属性的 <script> 标签内:
<script nonce="random_token">
var version = "5.7.33";
</script>
Adminer 的 SQL 查询层本来已经对 ATTACH 等危险命令做了限制,但 MySQL 的版本字符串是个特殊存在——它不来自用户查询,而来自数据库服务器本身。攻击者只需要在网络中架设一个恶意 MySQL 服务器,当 Adminer 尝试连接时,服务器返回的版本字符串就会被直接渲染进 DOM。
Voorivex 团队发现的绕过技巧在于:版本字符串需要匹配一个数字格式的正则,但攻击者可以用精心构造的非数字字符破坏正则匹配,让字符串“逃逸”出 JavaScript 上下文,插入任意 HTML 或脚本。因为渲染位置本身就处于有效的 <script nonce> 标签里,浏览器会照常执行其中的 JavaScript。
实际危害
配合钓鱼或中间人攻击,可以窃取登录凭据、劫持会话令牌,甚至进一步利用窃取的凭证登录 Adminer 并触发 CVE-2026-56703 达成 RCE。
四、CVE-2026-56703:SQLite VACUUM INTO 文件写入 RCE
被遗漏的 VACUUM 命令
Adminer 对 SQLite 的 ATTACH 命令做了限制,阻止用户附加外部数据库文件。但研究人员发现,ATTACH 的封禁名单里漏掉了同样危险的 VACUUM INTO 命令。
VACUUM INTO 本用于将 SQLite 数据库导出到文件,语法为 VACUUM INTO 'filename'。攻击者通过 Adminer 执行以下 SQL 就能写马:
ATTACH DATABASE '/var/www/html/shell.php' AS shell;
CREATE TABLE shell.pwn (data TEXT);
INSERT INTO shell.pwn VALUES ('<?php system($_GET["cmd"]); ?>');
VACUUM INTO '/var/www/html/shell.php';
SQLite 会把一整个数据库文件(含 PHP payload)写到指定路径。和 CVE-2026-56705 不同,这个漏洞要求攻击者已经握有 Adminer 的有效登录凭证,属于认证后RCE范畴,但最终危害同样是远程代码执行。
为什么 VACUUM INTO 被漏掉
开发者的防护思路是封禁 ATTACH 命令本身,防止用户操作外部数据库文件。但 VACUUM INTO 并不依赖 ATTACH,它能直接从当前数据库向任意路径写数据,所以压根不在 ATTACH 的封禁规则里。这是典型的“封禁名单不完整”缺陷。
五、修复建议
首先要做的,是强烈建议所有 Adminer 用户立即升级到 5.4.3 或更高版本。Adminer 更新很直接,下载最新的 adminer.php 替换旧文件即可。
暂时无法升级的环境,建议先做以下临时缓解:
- 把 adminer.php 移出 Web 根目录,或加访问控制只放行可信 IP。
- 使用 MSSQL 驱动的用户尤其要警惕,因为 CVE-2026-56705 在登录前就能触发。
- 必须保留公网访问时,坚持最小权限原则,禁止 Adminer 连接生产库。
六、总结与趋势预测
Adminer 的安全问题,本质上是便捷性与安全性的长期博弈。单 PHP 文件的分发模式让它极容易部署,但也意味着安全更新高度依赖开发者主动替换文件,而不是通过包管理器自动推送。
从这次披露看,企业环境中数据库管理工具的暴露面,是一个长期被忽视的攻击向量。CTO 和 DevOps 团队理应将 adminer.php 纳入资产清点,定期审查访问控制与版本状态。
可以预见,随着自动化漏洞扫描工具的普及,这类“被遗忘的 adminer.php”会成为红队和攻击者重点照顾的目标。后续安全研究很可能继续在 PostgreSQL、Oracle 等其他数据库后端上寻找类似攻击路径。相关复现经验与工具分享,也欢迎到云栈社区发帖交流。
本文原始内容由华盟网原创发布。