
phpMyAdmin 5.2.3 — высокий уровень — удалённо — остаточный — setup/validate всё ещё доступен
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · phpmyadmin-setup-validate
Класс: SSRF Достижимость: Удалённая
phpMyAdmin 5.2.3 (тег RELEASE_5_2_3, коммит 962857e). setup/index.php завершается, если присутствует config.inc.php. setup/validate.php — нет. Он всё ещё загружается в рамках $isMinimumCommon, берёт CSRF-токен с публичной страницы входа и вызывает Validator::testDBConnection -> mysqli_connect к хосту, порту, пользователю и паролю из поля JSON values.
Неаутентифицированный клиент выполняет GET /, чтобы получить сессионную куку и токен, затем отправляет POST на setup/validate.php с id=Server и выбранными им Servers/1/host и Servers/1/port. Хост phpMyAdmin открывает TCP-рукопожатие MySQL к этому адресу. Это SSRF через протокол MySQL: внутренний 3306, перебор учётных данных против внутреннего сервера, оракул портов по таймингам и ошибкам mysqli. Это не HTTP metadata SSRF, если только что-то на этом порту не говорит на MySQL. hide_db также интерполирует пользовательскую регулярку в preg_match. Я не запускал этот путь ReDoS в данной лаборатории.
Официальный образ phpmyadmin:5.2.3 удаляет setup/. Этот остаток применим только когда этот каталог всё ещё находится в корне веб-сервера, что является обычным остатком после установки. Лаборатория восстанавливает setup/ из тарбола 5.2.3, чтобы пин соответствовал RELEASE_5_2_3.
PMASA-2016-44 / CVE-2016-6621 покрывал часть setup SSRF. Проверка «отключить setup при наличии config» никогда не применялась к validate.php / config.php.
| ID | пока нет CVE |
| Класс | SSRF (протокол MySQL) |
| Достижимость | Удалённая (неаутентифицированная, если setup/ всё ещё доступен по вебу) |
| CWE | CWE-918 |
| CVSS | High: 7.2 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N |
| Продукт | phpMyAdmin |
| Затронуто | 5.2.3 тег RELEASE_5_2_3 (962857e) с setup/ всё ещё в docroot |
| Аутентификация | Неаутентифицированная. CSRF-токен с публичной страницы входа. Без входа в MySQL. |
| Лицензия | GNU Affero GPL v3.0 |
| Лаборатория | только 127.0.0.1:19230 |
Любой, кто может достичь оставшегося дерева setup/, может заставить хост phpMyAdmin открыть TCP-соединение по протоколу MySQL к выбранному им хосту и порту.
| Привилегия | Метод / путь | Доказано в лаборатории или выведено |
|---|---|---|
| Открыть TCP с хоста PMA к хосту:порту атакующего (целостность исходящего соединения; разведка этого порта) | Неаутентифицированный POST /setup/validate.php id=Server с Servers/1/host + Servers/1/port плюс токен из GET / | Доказано в лаборатории. Оракул на oracle:13306 залогировал PMA-SETUP-VALIDATE-WITNESS из контейнера PMA |
| Подтвердить, что setup UI отключён, а validate остаётся включённым | GET /setup/index.php | Доказано в лаборатории. Тело содержит "setup is disabled" / configuration already exists |
| Отказ в закрытом состоянии без CSRF-токена со страницы входа | Тот же POST, без token | Доказано в лаборатории. Ноль попаданий в оракул |
| Оракул портов / учётных данных по ошибкам mysqli и таймингам | Тот же testDBConnection | Выведено. Тело в лаборатории было mysqli_connect(): (HY000/2006): MySQL server has gone away после того, как оракул принял, а затем закрыл соединение |
| Говорить на MySQL с внутренним 3306 и попробовать отправленные user/password | Тот же mysqli_connect | Выведено. Не направлено на сервис db лаборатории |
ReDoS через validateRegex, интерполирующий пользовательскую регулярку | id=Servers/1/hide_db | Выведено. Не проверялось |
Закрыто в этой лаборатории: HTTP metadata SSRF (рукопожатие — это MySQL, а не GET /latest/meta-data), неаутентифицированный вход в PMA, OS shell и сам мастер настройки (index.php остаётся отключённым). FAIL, если setup/ не развёрнут (по умолчанию в официальном образе).
Восемь параллельных поисков по исходникам RELEASE_5_2_3. В setup/index.php есть фатальная ошибка при существующем config. В setup/validate.php — нет. setup/lib/common.inc.php устанавливает $isMinimumCommon и не ищет CONFIG_FILE.
Неверные пути: считать официальный образ этим остатком (он удаляет setup/); отправлять POST без токена со страницы входа (ноль попаданий в оракул); считать это HTTP metadata SSRF (рукопожатие — это MySQL).
python3 phpmyadmin-setup-validate-Abraxas-Labs.py
или
cd lab
./run.sh
Только loopback: http://127.0.0.1:19230. Compose-проект phpmyadmin-setup-validate. Dockerfile восстанавливает setup/ из тарбола 5.2.3 и запускает TCP-оракул на порту 13306. Свидетель PMA-SETUP-VALIDATE-WITNESS.
SUCCESS phpmyadmin-setup-validate how=live tcp=yes setup-index-disabled=yes PMA-SETUP-VALIDATE-WITNESS
Поместите фатальную проверку file_exists(CONFIG_FILE) в setup/lib/common.inc.php, чтобы каждый скрипт setup завершался. Ограничьте хосты testDBConnection. Не стройте разделители preg_match из пользовательских строк.
962857e)setup/index.php фатальная ошибка при существующем configsetup/validate.php без этой проверкиlibraries/classes/Config/Validator.php testDBConnection / mysqli_connectGNU Affero GPL v3.0. См. LICENSE. Только loopback-лаборатория. Без гарантий.