abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · phpmyadmin-webauthn
类别: 2FA 绕过 可达性: 远程
phpMyAdmin 5.2.3(标签 RELEASE_5_2_3)。默认 tarball。web-auth/webauthn-lib 是 suggest / require-dev。composer install --no-dev 不会安装它。因此 createServer 使用 CustomServer。该类解析 response.signature(该字段必须存在且可解码),但从不进行 COSE 验证。它从不使用存储的 credentialPublicKey。产品自带的 CustomServerTest 接受一个没有公钥的断言。
结构性检查是真实的:allowCredentials 中的凭证 id、clientData.type == webauthn.get、challenge 与会话匹配、origin host、rpIdHash、user-present。签名被解析后即被忽略。在 MySQL 密码之后,一个仍然匹配这些字段的垃圾 WebAuthn 签名即可获得完整的 phpMyAdmin 会话。那就是数据库。如果你确实安装了 web-auth/webauthn-lib,你使用的是 WebauthnLibServer,则不存在此漏洞。
| ID | 暂无 CVE |
| 类别 | 2FA 绕过 / 缺少签名验证 |
| 可达性 | 远程(cookie 登录,然后 WebAuthn 被跳过) |
| CWE | CWE-347、CWE-287 |
| CVSS | 高危:8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| 产品 | phpMyAdmin |
| 受影响版本 | 5.2.3 标签 RELEASE_5_2_3。默认 tarball / composer install --no-dev |
| 认证 | Cookie 登录(MySQL 密码),然后 WebAuthn 被跳过 |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅 127.0.0.1:18080 |
他们仍然需要 MySQL 密码(cookie 登录)。在获得该密码后,他们 POST webauthn_request_response,携带匹配的 challenge、origin host、rpIdHash、user-present、已注册的凭证 id,以及一个垃圾签名。他们便进入正常 UI。2FA 已失效。那就是数据库(SQL、用户、导出),而不是主机上的 PHP shell。
如果你确实安装了 web-auth/webauthn-lib,你使用的是 WebauthnLibServer,则不存在此漏洞。
| 权限 | 方法 / 路径 | 实验验证或推断 |
|---|---|---|
| 在没有认证器的情况下完成 WebAuthn 2FA(第二因素完整性) | 密码后 POST webauthn_request_response,垃圾签名 | 实验验证。still_2fa=False landed=True |
| 以该 MySQL 用户身份获得完整 PMA(SQL 主机的完整性 + 侦察) | 同一会话 | 实验验证。存在主页 UI 标记 |
| 跳过 MySQL 密码 | 未认证 POST | 实验验证已关闭。停留在登录页 |
在安装了 web-auth/webauthn-lib 的情况下同样绕过 | WebauthnLibServer | 已关闭。不是此遗留问题 |
| 操作系统 RCE / 反弹 shell | 此遗留问题 | 已关闭 |
针对此遗留问题已关闭:未认证 PMA、主机上的 PHP shell,以及将实际安装了 web-auth/webauthn-lib 的 tarball 视为此漏洞。
我阅读了 createServer,然后是 parseAndValidateAssertionResponse,接着是那个不传入公钥的单元测试。结构性检查是真实的。签名被解析后即被忽略。
错误尝试:在没有先前密码会话的情况下 POST WebAuthn JSON;未通过结构性检查的签名;Webauthn\Server 仍然存在(错误的服务器类);challenge 不来自此会话;origin host 不匹配;user-present 标志未设置;凭证 id 不在 allowCredentials 中。
实验环境的 Dockerfile 复制 5.2.3,执行 composer install --no-dev,然后删除 vendor/web-auth,以便 CustomServer 是实际使用的那个。最后的 php -r 如果 Webauthn\Server 存在则退出码为 1。init.sql 为 appuser 注册 WebAuthn 2FA,无需硬件密钥。PoC POST 签名 not-a-real-signature-PMA-WEBAUTHN-BYPASS。
将固定版本克隆到 Dockerfile 旁边,然后运行:
cd lab
git clone --depth 1 --branch RELEASE_5_2_3 https://github.com/phpmyadmin/phpmyadmin.git src
./run.sh
或在克隆后从包根目录运行:
python3 phpmyadmin-webauthn-Abraxas-Labs.py
仅限回环:http://127.0.0.1:18080。Compose 项目 pma-webauthn-lab。固定 RELEASE_5_2_3。不要分发 src/。见证 PMA-WEBAUTHN-BYPASS。
SUCCESS PMA-WEBAUTHN-BYPASS WebAuthn 2FA accepted with garbage signature
使用存储的 COSE 公钥验证 authenticatorData || SHA-256(clientDataJSON);绑定 userHandle;强制 signCount。将 web-auth/webauthn-lib 设为真正的依赖并删除 CustomServer,或在库缺失时故障关闭。在此之前,禁用 WebAuthn 2FA 或不要暴露此 phpMyAdmin。
Plugins\TwoFactor\WebAuthn::createServerCustomServer::parseAndValidateAssertionResponseGNU Affero GPL v3.0。参见 LICENSE。仅限回环实验环境。无担保。