
Exploit for the CVE-2026-8181 - Burst Statistics WordPress Plugin Authentication Bypass
Эксплойт для 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 и передает предоставленные атакующим / в функцию ядра WordPress .
Таким образом, одного 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, поэтому маршрутизация конечных точек никогда не является препятствием — только пересылка заголовка.
usernamepasswordwp_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 ) с пользователем, полученным исключительно из предоставленного атакующим имени пользователя, что устанавливает глобально аутентифицированного пользователя на весь запрос.