
CVE-2026-63030 и CVE-2026-60137 — proof-of-concept цепочки RCE
⚠ Этот инструмент создан исключительно в образовательных целях или для программ bug bounty. Несанкционированное использование вне контролируемых сред строго запрещено.
Доказательство концепции для цепочки уязвимостей wp2shell, затрагивающей ядро WordPress, объединяющей CVE-2026-63030 и CVE-2026-60137. Проект демонстрирует взаимодействие между уязвимостью путаницы маршрутов в REST API Batch и SQL-инъекцией в WP_Query, что приводит к неаутентифицированному пути к полной компрометации WordPress и удалённому выполнению кода (RCE).
Полный отчёт читайте здесь
wp2shell — это цепочка RCE до аутентификации в ядре WordPress, объединяющая CVE-2026-63030 (путаница маршрутов в batch-эндпоинте REST) и CVE-2026-60137 (SQL-инъекция в WP_Query).
Путаница маршрутов: /wp-json/batch/v1 обрабатывает несколько подзапросов через параллельные массивы $matches и $validation, индексируемые по позиции. Подзапрос с некорректным путём (например, http://:) добавляется в , но не в из-за оператора , что приводит к рассинхронизации массивов. Последующие запросы обрабатываются обработчиком, предназначенным для запроса, обходя проверку схемы и проверки прав.
$validation$matchescontinueSQL-инъекция: Два вложенных batch-вызова эксплуатируют это. Внешний batch обходит белый список методов (обычно блокирующий GET). Внутренний batch передаёт скалярную строку author_exclude в GET /wp/v2/posts — рассинхронизация проводит её мимо валидации, и WP_Query интерполирует несанитизированную строку напрямую в SQL, что даёт слепую инъекцию на основе UNION.
Отравление кэша: SQLi возвращает поддельные объекты WP_Post, которые WordPress кэширует в памяти. Эти фальшивые записи содержат шорткоды [embed], из-за которых WordPress создаёт реальные строки oembed_cache в базе данных из поддельных ссылок.
Эскалация через changeset: Используя SQLi, атакующий подделывает запись customize_changeset в памяти с "user_id": 1 в её JSON. Гаджет обнаружения циклов запускает wp_update_post() без перезаписи post_content, сохраняя полезную нагрузку атакующего. Применение changeset временно принимает личность администратора.
Повторный вход через хук: Сфабрикованная запись со статусом parse и типом request запускает хук parse_request, воспроизводя весь batch-запрос с принятой ролью администратора. На этот раз подзапрос POST /wp/v2/users успешно выполняется, создавая новую учётную запись администратора.
Выполнение кода: Атакующий входит как созданный администратор и загружает вредоносный плагин для выполнения произвольных команд.
| Версия | Статус |
|---|---|
| WordPress 6.9.0 – 6.9.4 | Уязвима |
| WordPress 7.0.0 – 7.0.1 | Уязвима |
| WordPress 6.9.5 | Исправлена |
| WordPress 7.0.2+ | Исправлена |
Для использования этого PoC единственное требование — Python 3.8+.
Запустите его из каталога репозитория для проверки уязвимости:
wp2shell.py http://victim.com
Выполняет одну проверку уязвимости. Отправляет безобидный batch-маркер, который обнаруживает ошибку путаницы маршрутов без выполнения SQLi-полезных нагрузок. Уязвимая цель возвращает HTTP 207 с шаблоном ошибок parse_path_failed, block_cannot_read и rest_batch_not_allowed.
Используйте --confirm-sqli, чтобы также отправить активную полезную нагрузку подтверждения SQLi. Подтверждение сначала пробует отражение UNION, затем переходит к пробам на основе таймингов.
Проверка одной цели (режим по умолчанию)
wp2shell.py http://target.com
Проверка с явным режимом
Check with explicit mode
wp2shell.py http://target.com --check
Проверка с подтверждением SQLi
wp2shell.py http://target.com --check --confirm-sqli
Извлекает данные из базы данных с помощью SQL-инъекции до аутентификации. По умолчанию использует --technique auto, который пробует доступные методы в следующем порядке:
WP_Post через UNION и читает её заголовок обратно из REST-ответа как ||HEX(value)||. Один запрос на значение. Самый быстрый.EXTRACTVALUE/UPDATEXML для утечки ~15 байт за запрос. Работает, когда цель отражает ошибки MySQL (например, при включённом WP_DEBUG_DISPLAY).X-WP-Total как сигнал true/false. Работает даже когда данные не отражаются.Принудительно задайте конкретную технику с помощью --technique union|error|blind. Эти пути чтения только для чтения и не записывают в базу данных.
Отпечаток сервера (запрос по умолчанию)
wp2shell.py http://target.com --read
Дамп логинов и хешей паролей
wp2shell.py http://target.com --read --preset users
Пользовательский SQL-запрос
wp2shell.py http://target.com --read --query "SELECT @@version"
Принудительно blind-техника
wp2shell.py http://target.com --read --technique blind --query "SELECT user_login FROM wp_users LIMIT 1"
Извлечение с помощью error-based техники
wp2shell.py http://target.com --read --technique error --query "SELECT user_pass FROM wp_users LIMIT 1"
Выполняет команды на целевом сервере. Работает в двух режимах:
С учётными данными (входит как существующий администратор и загружает плагин-шелл):
Выполнить конкретную команду
wp2shell.py http://target.com --shell --user admin --password '<recovered>' --cmd id
Интерактивный шелл
wp2shell.py http://target.com --shell --user admin --password '<recovered>' --interactive
Without credentials (pre-auth RCE - runs the full SQLi→admin bridge, logs in as generated admin, then uploads plugin shell):
Выполнить одну команду
wp2shell.py http://target.com --shell --cmd id
Интерактивный шелл
wp2shell.py http://target.com --shell --interactive
Плагин-вебшелл загружается со случайным путём и токеном для каждого запуска. Загруженный вебшелл удаляется автоматически. Когда pre-auth мост создаёт администратора, эта сгенерированная учётная запись автоматически удаляется после завершения сессии шелла.
Список всех флагов:
| Флаг | Описание |
|---|---|
--check | Запустить проверку уязвимости (режим по умолчанию, если не указан другой режим) |
--read | Извлечь данные через SQL-инъекцию |
--shell | Выполнить команды на сервере |
--query | Пользовательский SQL-запрос для режима чтения |
--preset | Предопределённый пресет запроса (users, config, versions) |
--technique | Техника извлечения SQLi: union, error, blind или auto (по умолчанию) |
--confirm-sqli | Отправить полезную нагрузку подтверждения SQLi после проверки |
--cmd | Команда для выполнения в режиме shell (по умолчанию: id) |
--interactive, -i | Интерактивный режим shell |
--user | Имя администратора для аутентифицированного shell |
--password | Пароль администратора для аутентифицированного shell |
--proxy | HTTP/HTTPS прокси (например, http://127.0.0.1:8080) |
--timeout | Таймаут запроса в секундах (по умолчанию: 30) |
--verbose, -v | Подробный вывод |
Этот инструмент создан исключительно в образовательных целях или для программ bug bounty. Несанкционированное использование вне контролируемых сред строго запрещено.