
Эксплойт для CVE-2026-8181 - Обход аутентификации плагина Burst Statistics WordPress
Эксплойт для CVE-2026-8181, обнаруженный Chloe Chamberland и PRISM.
Этот репозиторий предоставлен только для исследований и целей защиты. Автор не несет ответственности за неправомерное использование этой информации.
Плагин Burst Statistics – Privacy-Friendly WordPress Analytics для WordPress уязвим к обходу аутентификации, ведущему к повышению привилегий до администратора в версиях 3.4.0 – 3.4.1.1.
Уязвимость существует в методе is_mainwp_authenticated() прокси MainWP плагина, который неправильно обрабатывает любое возвращаемое значение, отличное от WP_Error, из как успешную аутентификацию.
wp_authenticate_application_password()Это позволяет неаутентифицированным атакующим, знающим действительное имя пользователя администратора, выдавать себя за этого администратора на время любого REST API запроса, включая стандартные конечные точки WordPress, такие как POST /wp-json/wp/v2/users. Учетные данные существующего администратора никогда не компрометируются, но атакующий получает его привилегии на время, достаточное для создания новой учетной записи администратора.
Цепочка уязвимости следующая:
includes/class-burst.php:41 -> Плагин регистрирует init() на приоритете 9 хука plugins_loaded, который запускает bootstrap() и вызывает has_admin_access() для каждого запроса (включая REST).
includes/Traits/trait-admin-helper.php:202 -> Когда запрос содержит заголовок X-BurstMainWP: 1, has_admin_access() создает экземпляр MainWP_Proxy и делегирует аутентификацию методу is_mainwp_authenticated().
includes/Frontend/class-mainwp-proxy.php:314 -> Метод читает заголовок Authorization, декодирует учетные данные Basic и передает предоставленные атакующим username / password в функцию ядра WordPress wp_authenticate_application_password().
includes/Frontend/class-mainwp-proxy.php:328-329 -> Возвращаемое значение проверяется только с помощью is_wp_error(). Ядро WordPress возвращает неизменный $input_user (в данном случае null), когда прикладные пароли не используются или когда запрос не помечен как API-запрос. На приоритете 9 хука plugins_loaded REST API еще не установил фильтр application_password_is_api_request в true, поэтому второе условие всегда выполняется, когда выполняется уязвимый код — и null не является WP_Error, поэтому проверка проходит.
includes/Frontend/class-mainwp-proxy.php:336 -> Вызывается wp_set_current_user( $user->ID ) с пользователем, полученным исключительно из предоставленного атакующим имени пользователя, что устанавливает глобально аутентифицированного пользователя на весь запрос.
Таким образом, одного HTTP-запроса с поддельным паролем достаточно, чтобы выдать себя за любого администратора на уровне REST API ядра WordPress.
Активный плагин — HTML главной страницы ссылается на его ресурсы только когда плагин подключен:
echo http://127.0.0.1:8000 | httpx -silent -mr '/wp-content/plugins/burst-statistics/'
Версия — readme.txt отдается статически и показывает установленную версию (уязвимые: 3.4.0–3.4.1.1, исправленные: 3.4.2+):
echo http://127.0.0.1:8000 | httpx -silent -path /wp-content/plugins/burst-statistics/readme.txt -er 'Stable tag:\s*[0-9][0-9a-zA-Z.\-]*'
Встроенный шаблон CVE-2026-8181.yaml для nuclei автоматизирует обе проверки и сравнение версий:
nuclei -t CVE-2026-8181.yaml -u http://127.0.0.1:8000
После обнаружения уязвимой версии плагина для эксплуатации требуется знать действительное имя пользователя администратора. REST API WordPress'а на большинстве установок раскрывает их через публичную конечную точку пользователей:
echo http://127.0.0.1:8000 | httpx -silent -path '/wp-json/wp/v2/users' -er '"slug":"[^"]+"'
Когда эта конечная точка заблокирована (например, с помощью Disable REST API или Stop User Enumeration), трюк с архивом автора (/?author=N) обычно все еще раскрывает имя пользователя через перенаправление на /author/<username>/.
Имея действительное имя пользователя, эксплойт создает новую администраторскую учетную запись одним запросом:
Установите зависимости Python:
python3 -m venv venv
venv/bin/pip install -r requirements.txt
Запустите эксплойт против цели, указав известное имя пользователя администратора с помощью -u:
venv/bin/python3 CVE-2026-8181.py -t http://127.0.0.1:8000 -u admin
Пример вывода:
[2026-05-16] [12:20:20] [info] [config] Impersonating admin='admin', will create new admin 'pwn_322a4903' / 'kS8D^2A^P^%UtWyuUS3p8%64' ([email protected]).
[2026-05-16] [12:20:21] [success] [http://127.0.0.1:8000] Authentication bypass successful — new administrator created: username='pwn_322a4903' password='kS8D^2A^P^%UtWyuUS3p8%64'
Войдите в /wp-admin/ с новосозданной учетной записью администратора.
Обход срабатывает только если заголовок Authorization достигает PHP через $_SERVER['HTTP_AUTHORIZATION']. На Apache + mod_php с обычными постоянными ссылками (стандартная настройка WordPress по умолчанию) не создается .htaccess, и заголовок молча удаляется — эксплойт не может быть успешным.
Переключение на любые необычные постоянные ссылки в Настройки → Постоянные ссылки заставляет WordPress 5.6+ записать директиву RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] в .htaccess, восстанавливая пересылку. Nginx + PHP-FPM и LiteSpeed пересылают Authorization по умолчанию независимо от постоянных ссылок. ЧПУ (человеко-понятные URL) являясь нормой SEO в продакшене, являются причиной, по которой эта уязвимость оценивается как CVSS 9.8 неаутентифицированная.
Эксплойт сначала пробует /wp-json/wp/v2/users, затем отступает к /index.php?rest_route=/wp/v2/users, поэтому маршрутизация конечных точек никогда не является препятствием — только пересылка заголовка.