abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · PMA-5.2.3-WebAuthn-2FA
phpMyAdmin 5.2.3 - phpMyAdmin
默认 tarball。web-auth/webauthn-lib 属于 suggest / require-dev。composer install --no-dev 不会安装它。因此 createServer 使用 CustomServer。该类会解析 response.signature(该字段必须存在且可解码),但从不进行 COSE 验证。它从不使用已存储的 credentialPublicKey。产品自带的 CustomServerTest 接受一个没有公钥的断言。
在 MySQL 密码之后,一个垃圾 WebAuthn 签名,只要仍能匹配 challenge、origin、rpIdHash 和 user-present,就能获得完整的 phpMyAdmin 会话。那就是数据库。
| ID | 暂无 CVE |
| CWE | CWE-347, CWE-287 |
| CVSS | High: 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 默认 tarball(缺少 web-auth/webauthn-lib) |
| 认证 | MySQL 密码,随后 WebAuthn 被跳过 |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅 127.0.0.1 |
他们仍然需要 MySQL 密码(cookie 登录)。获得该密码后,他们 POST webauthn_request_response,其中包含匹配的 challenge、origin 主机、rpIdHash、user-present、已注册的 credential id,以及一个垃圾签名。他们便进入正常 UI。2FA 已失效。这是对数据的 RCE,而不是主机上的 PHP shell。
如果你确实安装了 web-auth/webauthn-lib,你使用的是 WebauthnLibServer,不受此漏洞影响。
我阅读了 createServer,然后是 parseAndValidateAssertionResponse,再然后是没有传入公钥的单元测试。结构性检查是真实存在的:credential id 在 allowCredentials 中、clientData.type == webauthn.get、challenge 与会话匹配、origin 主机、rpIdHash、user-present。签名被解析后即被忽略。
我指向此处的第一个客户端很守规矩。它在没有先前密码会话的情况下 POST 了一个 WebAuthn JSON。登录页面。它 POST 了 route=/,附带一个甚至不满足结构性检查的签名。你仍停留在 2FA。webauthn_request_response 仍在 HTML 中。
已记录的弯路:存在 Webauthn\Server(错误的服务器类);challenge 不是来自此会话;origin 主机不匹配;user-present 标志未设置;credential id 不在 allowCredentials 中;未认证,没有 MySQL 密码;一个反向 shell。全是演戏。破绽是 2FA 字段消失,出现 phpMyAdmin 导航页面。
客户端 bug 看起来像产品 bug。一个遮蔽 http.client 的辅助程序从不发送数据包。对 HTTPResponse 调用 .recv() 不是 .read()。我提一次是因为它耗费了时间,并且有一分钟看起来像是 phpMyAdmin 没问题。
然后:POST username/password/token。从 2FA 页面提取会话 challenge。POST 伪造的断言。still_2fa=False landed=True。实验环境 Dockerfile 复制 5.2.3,composer install --no-dev,然后删除 vendor/web-auth,以便 CustomServer 是实际生效的那个。最后的 php -r 如果 Webauthn\Server 存在则退出码为 1。如果该库仍然存在,镜像必须构建失败。init.sql 为 appuser 注册 WebAuthn 2FA,无需硬件密钥。
cd lab
./run.sh
仅针对 http://127.0.0.1:18080。先将 phpMyAdmin 5.2.3 作为 src/ 放置在 Dockerfile 旁边。
password-login status=200 webauthn=True
2fa-post status=200 still_2fa=False landed=True
SUCCESS PMA-WEBAUTHN-BYPASS WebAuthn 2FA accepted with garbage signature
安装 web-auth/webauthn-lib,使 createServer 使用该库,或者在 CustomServer 中真正对 response.signature 与存储的公钥进行 COSE 验证。在此之前,请禁用 WebAuthn 2FA,或不要暴露此 phpMyAdmin。
CustomServer::parseAndValidateAssertionResponse · WebAuthn::createServer · CustomServerTestGNU Affero GPL v3.0。参见 LICENSE。仅限回环实验环境。不提供任何担保。