Недавно мир узнал о серьезной уязвимости в системе управления контентом Drupal — мы тогда подробно писали об этом. Однако, разобрав проблему в ветке 8.x, мы оставили за кадром аналогичную брешь в Drupal 7. А ведь на этой версии сейчас работает куда больше сайтов! Эксплуатировать уязвимость в ней сложнее, но не намного. Сейчас я покажу, как это делается.
Подготовка
Для демонстрации уязвимости проще всего использовать официальный репозиторий Drupal на Docker Hub. Разворачиваем контейнер с нужной версией CMS. Сначала поднимаем сервер БД.
Не забудь поменять IP-адрес 192.168.99.1 на свой и обрати внимание на путь до скомпиленной библиотеки xdebug.so. После перезагрузки конфигов Apache можешь запускать свой любимый дебаггер. В работе я по-прежнему использую PhpStorm и расширение Xdebug helper для Chrome.
Теперь скачиваем исходники CMS, слушаем 9000-й порт — и вперед, к победам.
Первые шаги
Перейдем на страницу создания нового аккаунта. В седьмой версии она значительно аскетичнее, чем в восьмой.
Создание нового аккаунта в Drupal 7
Создание нового аккаунта в Drupal 8
Из-за того, что отсутствует возможность загрузить аватар, стандартный вектор эксплуатации тут не сработает. Значит, нужно найти новый! Суть бага все та же — это внедрение элементов в Renderable Arrays, которые будут обработаны с помощью Render API. Существуют специальные элементы, которые вызывают функцию call_user_func с кастомными параметрами.
Для начала посмотрим, как обрабатываются роуты в приложении. Если у тебя на сервере включены семантические URL, то URI перенаправляются на файл index.php как GET-параметр q.
Далее путь разбивается при помощи функции array_slice и выполняется запрос к базе данных для выборки путей из таблицы с роутами. По умолчанию menu_router.
473:
$parts = array_slice($original_map, 0, MENU_MAX_PARTS);
474:
$ancestors = menu_get_ancestors($parts);
475:
$router_item = db_query_range('SELECT * FROM {menu_router} WHERE path IN (:ancestors) ORDER BY fit DESC', 0, 1, array(':ancestors' => $ancestors))->fetchAssoc();
В таблице хранятся колбэки, которые нужно выполнять при обращении к соответствующим путям.