
phpMyAdmin — высокий уровень 8.1 — аутентифицированный POST /index.php — обход 2FA
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 продукта принимает assertion без публичного ключа.
После пароля 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, id зарегистрированного credential и мусорной подписью. Он попадает в обычный интерфейс. 2FA больше нет. Это RCE над данными, а не PHP-шелл на хосте.
Если вы действительно установили 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; reverse shell. Театр. Признак успеха — исчезнувшее поле 2FA и страница навигации phpMyAdmin.
Ошибки клиента выглядят как ошибки продукта. Хелпер, который затеняет http.client, вообще не отправляет пакет. .recv() у HTTPResponse — это не .read(). Упоминаю это один раз, потому что это стоило времени и на минуту выглядело так, будто с phpMyAdmin всё в порядке.
Затем: POST с username/password/token. Вытащить challenge сессии со страницы 2FA. Отправить POST с поддельным assertion. still_2fa=False landed=True. Dockerfile лаборатории копирует 5.2.3, выполняет composer install --no-dev, затем удаляет vendor/web-auth, чтобы в игре был именно CustomServer. Последний php -r завершается с кодом 1, если Webauthn\Server существует. Образ должен проваливать сборку, если библиотека всё ещё на месте. init.sql регистрирует WebAuthn 2FA для appuser без аппаратного ключа.
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 использовал библиотеку, или реализуйте фактическую COSE-проверку response.signature по сохранённому открытому ключу в CustomServer. До этого отключите 2FA WebAuthn или не выставляйте этот phpMyAdmin наружу.
CustomServer::parseAndValidateAssertionResponse · WebAuthn::createServer · CustomServerTestGNU Affero GPL v3.0. См. LICENSE. Только для лабораторной среды с loopback. Без гарантий.