
Детектор PoC и безопасный валидатор для цепочки уязвимостей WP2Shell WordPress: CVE-2026-63030 (путаница пакетных маршрутов REST) + CVE-2026-60137 (SQL-инъекция author__not_in). Только для авторизованного тестирования безопасности.
Охват CVE: CVE-2026-63030 и CVE-2026-60137 Назначение: Только авторизованное тестирование безопасности, защитная валидация и одноразовые локальные лаборатории
WP2Shell — это цепочка уязвимостей ядра WordPress, объединяющая баг путаницы пакетных маршрутов REST API до аутентификации (CVE-2026-63030) с примитивом SQL-инъекции author__not_in в WP_Query (CVE-2026-60137). Этот репозиторий предоставляет Python-сканер доказательства концепции и безопасный валидатор, чтобы защитники могли идентифицировать затронутые установки WordPress, подтвердить уязвимое поведение в изолированной лаборатории и проверить исправление — без необходимости извлечения данных или достижения выполнения кода.
Этот проект идентифицирует установки WordPress и проверяет два примитива уязвимости, связанных с цепочкой уязвимостей ядра WordPress WP2Shell:
WP_Query::author__not_in, что может привести к SQL-инъекции, когда подконтрольные злоумышленнику данные достигают параметра.Когда оба условия присутствуют, неаутентифицированный запрос может достичь уязвимой SQL-конструкции через конечную точку пакетного REST API WordPress. Публичные уведомления описывают совокупное воздействие как потенциально ведущее к удаленному выполнению кода.
Этот репозиторий следует использовать только на системах, которыми вы владеете или на тестирование которых у вас есть явное разрешение. Предпочтительнее использовать изолированную лабораторию Docker или виртуальной машины, привязанную к 127.0.0.1.
Текущий исходный файл содержит функциональность, изменяющую состояние, включая попытки извлечения данных из базы данных, попытки записи в файлы, рабочие процессы аутентификации, создание администратора, загрузку плагинов и выполнение команд.
Затронутые релизы WordPress могут терять согласованность между внутренними массивами, используемыми для отслеживания:
Когда искаженный элемент пакета принимается в один внутренний массив, но не в другой, последующие запросы могут быть связаны с неправильным обработчиком. Таким образом, запрос может быть проверен как один маршрут, но выполнен с использованием функции обратного вызова другого маршрута.
Влияние на безопасность:
author__not_inЗатронутая реализация WP_Query не всегда нормализует author__not_in перед использованием для построения SQL-условия NOT IN (...).
Параметр обычно ожидает список целочисленных идентификаторов авторов. Если скалярная строка попадает в уязвимую конструкцию запроса без предусмотренной проверки схемы REST, небезопасная SQL-структура может сохраниться в запросе к базе данных.
Влияние на безопасность:
WordPress выпустила исправления 17 июля 2026 года и включила принудительные автоматические обновления для затронутых установок из-за серьезности.
Unauthenticated client | v WordPress REST batch endpoint | v Malformed batch member creates request/handler misalignment | v Later request is validated against one route but dispatched using another route's handler | v Scalar author_exclude reaches WP_Query as author__not_in | v Unsafe value reaches SQL NOT IN (...) construction | v Blind SQL timing or Boolean oracle | v Potential database compromise | v Potential application-level compromise and RCE
Детектор должен остановиться после подтверждения примитивов route-confusion и SQL-инъекции. Ему не нужно извлекать данные или выполнять команды, чтобы установить, что скомпрометированная установка уязвима.
---
## Процесс обнаружения
### Этап 1 — Нормализация цели
Инструмент:
1. Добавляет схему по умолчанию `http` или `https`, если она отсутствует.
2. Нормализует путь установки WordPress.
3. Отклоняет неподдерживаемые схемы URL и встроенные учётные данные.
4. Применяет политики перенаправлений, прокси, TLS и тайм-аутов.
### Этап 2 — Идентификация WordPress
Сканер проверяет:
- ссылки на `wp-content/`;
- ссылки на `wp-includes/`;
- метаданные генератора WordPress;
- ссылки обнаружения REST API;
- структуру индекса WordPress REST;
- пространство имён `wp/v2`;
- необязательные фид и `readme.html`.
### Этап 3 — Определение версии
Доказательства версии могут поступать из:
- метаданных HTML-генератора;
- метаданных фид-генератора;
- строк запроса основных ресурсов WordPress;
- HTTP-заголовков генератора;
- `readme.html`;
- локального файла `wp-includes/version.php`.
Доказательства оцениваются и сопоставляются. Противоречивые удалённые индикаторы версии снижают достоверность.
### Этап 4 — Проверка доступности пакетного маршрута
Сканер пытается обнаружить `/batch/v1` через:```text
/?rest_route=/
/wp-json/
Маршрут можно указать, используя:```text /?rest_route=/batch/v1 /wp-json/batch/v1
### Фаза 5 — Безопасный зонд на путаницу маршрутов
Безопасный зонд содержит:
1. Намеренно искажённый внутренний путь.
2. Запрос к недействительному ID поста с безвредным вложенным публичным `GET`.
3. Последующий запрос `/batch/v1`.
Уязвимый сервер возвращает внешний ответ `207 Multi-Status`, в котором запрос к недействительному посту обрабатывается как вложенный пакетный запрос.
Детектор сообщает:```text
route-confusion-observed
when it sees:
parse_path_failed.207.responses, показывающий, что безвредный внутренний запрос выполнен.Нерарушающий валидатор SQLi должен отправлять парные запросы, отличающиеся только константным булевым условием:```text False control -> no deliberate database delay True test -> deliberate database delay
Валидатор должен:
- Принимать ожидаемый внешний HTTP `207`.
- Разбирать как внешние, так и вложенные пакетные конверты.
- Проверять маркеры некорректных запросов.
- Убеждаться, что вложенный запрос с SQL-инъекцией вернул допустимый ответ.
- Собирать несколько истинных и ложных образцов.
- Перемешивать или чередовать порядок образцов.
- Сравнивать медианы, а не единичный запрос.
- Сообщать о недостаточных измерениях как `inconclusive`.
Повторяемый разрыв между истинными и ложными образцами подтверждает, что контролируемый атакующим ввод достиг SQL-оценки. Нет необходимости выбирать или извлекать содержимое базы данных.
---
## Требования
- Python 3.9 или новее.
- Для предоставленного скрипта не требуется сторонних Python-пакетов.
- Сетевой доступ к авторизованной установке WordPress.
- Для локального тестирования:
- Одноразовая лабораторная установка WordPress 7.0.1 или 6.9.4.
- Контейнер базы данных или выделенная тестовая база данных.
- Веб-сервис, привязанный к `127.0.0.1`.
- Без производственных учётных данных или данных.
Проверка Python:```bash
python3 --version
Опциональная проверка синтаксиса:```bash python3 -m py_compile WP2Shell_CVE-2026-63030_POC.py
## Установка
Переименуйте предоставленный скрипт в предсказуемое имя файла:```bash
mv 'poc(1).py' WP2Shell_CVE-2026-63030_POC.py
chmod +x WP2Shell_CVE-2026-63030_POC.py
Показать глобальную справку:```bash python3 WP2Shell_CVE-2026-63030_POC.py --help
Отобразить версию:```bash
python3 WP2Shell_CVE-2026-63030_POC.py --version
Скрипт определяет три команды:```text remote Fingerprint and scan HTTP(S) WordPress targets. local Read the installed WordPress version from a source tree. exploit State-changing proof-of-concept path.
### Текущее состояние сборки
| Команда | Статус |
|---|---|
| `local` | Реализовано |
| `remote` | CLI определён, но `run_remote()` в настоящее время является заглушкой и возвращает ошибку |
| `exploit` | Содержит функциональность, изменяющую состояние; ограничьте использование одноразовой локальной лабораторией и отделите от защитного сканирования |
В настоящее время источник выводит следующее для `remote`:
``````text
Remote scanning not fully implemented in this snippet. Use 'local' or 'exploit'.
Восстановите полную реализацию run_remote() перед тем, как рекламировать массовое удаленное сканирование как рабочее.
Команда local читает:```text
/wp-includes/version.php
и извлекает `$wp_version`.
## Основное использование```bash
python3 WP2Shell_CVE-2026-63030_POC.py local \
--wordpress-root /var/www/html
python3 WP2Shell_CVE-2026-63030_POC.py local
--wordpress-root /var/www/html
--format json
--output local-result.json
## Установка WordPress на основе Docker
Когда контейнер WordPress называется `wordpress`, скопируйте или смонтируйте исходное дерево на хост, или выполните проверку версии внутри контейнера:```bash
docker compose exec wordpress php -r \
'require "/var/www/html/wp-includes/version.php"; echo $wp_version, PHP_EOL;'
Используйте предоставленный compose.yaml для запуска одноразовой локальной лаборатории, привязанной к 127.0.0.1:8080:```bash
docker compose up -d
После того, как первоначальная установка WordPress завершится в браузере по адресу `http://127.0.0.1:8080`, вы можете запустить:```bash
python3 WP2Shell_CVE-2026-63030_POC.py remote \
--authorized \
--target http://127.0.0.1:8080 \
--active-probe \
--format json
Чтобы остановить и удалить лабораторию:```bash docker compose down -v
## Параметры локальной команды
| Опция | Описание |
|---|---|
| `--wordpress-root PATH` | Обязательная директория, содержащая `wp-includes/version.php` |
| `-f, --format` | `table`, `json`, `jsonl` или `csv` |
| `-o, --output FILE` | Записать отчёт в файл |
| `--fail-on` | Политика кода выхода: `never`, `vulnerable` или `unknown` |
## Пример вывода vulnerable-version```json
[
{
"selected_version": "7.0.1",
"version_assessment": "affected-wp2shell",
"verdict": "CONFIRMED_AFFECTED_VERSION",
"severity": "critical"
}
]
Результат локальной версии подтверждает, что установленный релиз попадает в опубликованный диапазон уязвимых версий. Сам по себе он не демонстрирует эксплуатацию во время выполнения или влияние обратно перенесенного патча.
Парсер remote поддерживает следующие аргументы, но представленная реализация run_remote() в настоящее время неполна.
Ожидаемый интерфейс после восстановления run_remote():```bash
python3 WP2Shell_CVE-2026-63030_POC.py remote
--authorized
--target https://wordpress.example
--active-probe
## Несколько явных целей```bash
python3 WP2Shell_CVE-2026-63030_POC.py remote \
--authorized \
--target https://site-one.example \
--target https://site-two.example \
--active-probe
Создайте targets.txt:```text
https://site-one.example/
https://site-two.example/blog/
Ожидаемый интерфейс:```bash
python3 WP2Shell_CVE-2026-63030_POC.py remote \
--authorized \
--targets-file targets.txt \
--active-probe \
--format jsonl \
--output results.jsonl
cat targets.txt | python3 WP2Shell_CVE-2026-63030_POC.py remote
--authorized
--stdin
## Использование прокси```bash
python3 WP2Shell_CVE-2026-63030_POC.py remote \
--authorized \
--target https://wordpress.example \
--active-probe \
--proxy http://127.0.0.1:8081
python3 WP2Shell_CVE-2026-63030_POC.py remote
--authorized
--target https://wordpress.example
--header 'Authorization: Bearer TEST_TOKEN'
## Удалённые параметры
| Параметр | Назначение |
|---|---|
| `-u, --target URL` | Целевой URL; повторяемый |
| `-l, --targets-file FILE` | Один целевой объект на строку; повторяемый |
| `--stdin` | Читать цели из stdin |
| `--authorized` | Требуется подтверждение авторизации |
| `--default-scheme` | Схема, применяемая по умолчанию |
| `-c, --concurrency` | Одновременные рабочие процессы |
| `--rate` | Совокупная частота запросов |
| `--timeout` | Таймаут на запрос |
| `--retries` | Количество повторных попыток |
| `--max-targets` | Максимальное количество принимаемых целей |
| `--max-body-bytes` | Максимальный сохраняемый размер тела ответа |
| `-k, --insecure` | Отключить проверку TLS |
| `--no-redirects` | Отключить перенаправления |
| `--allow-cross-host-redirects` | Разрешить перенаправления на другой хост |
| `--proxy` | HTTP/HTTPS прокси |
| `-H, --header` | Пользовательский заголовок; повторяемый |
| `--user-agent` | Переопределить User-Agent |
| `--fingerprint-level` | `quick`, `standard` или `extended` |
| `--active-probe` | Отправить безопасный зонд route-confusion |
| `--rest-endpoint` | `query`, `pretty` или `both` |
| `--include-request-log` | Добавить метаданные URL, статуса и времени |
| `-f, --format` | `table`, `json`, `jsonl` или `csv` |
| `-o, --output` | Записать вывод в файл |
| `--fail-on` | Политика кода выхода |
---
## Безопасная проверка во время выполнения
Для неразрушающей локальной проверки обоих примитивов используйте специальный валидатор, который:
- Отказывается от не-loopback хостов.
- Подтверждает route confusion в первую очередь.
- Запускает образцы времени постоянного состояния только после успешного route confusion.
- Не извлекает данные и не выполняет команды.
Пример рабочего процесса:```bash
python3 wp2shell_local_validator.py check \
--authorized \
--target http://127.0.0.1:8080 \
--sqli \
--delay 2 \
--samples 4 \
--warmups 2 \
--debug \
--dump-dir evidence \
--output result.json
Ожидаемый временной шаблон уязвимой лаборатории:```text False controls: approximately 0.03–0.10 seconds True tests: consistently delayed
Ожидаемый вердикт:```text
FULL_VULNERABILITY_PRIMITIVES_CONFIRMED
Тест на время выполнения может выполнять выражение задержки более одного раза, поэтому настроенная двухсекундная задержка может привести к наблюдаемой задержке около четырех секунд. Важным сигналом является повторяемое различие между истинными и ложными условиями.
Лучше всего для интерактивного терминала:```bash --format table
### JSON
Лучше всего подходит для доказательств и интеграции:```bash
--format json --output result.json
Лучше всего подходит для больших наборов целей:```bash --format jsonl --output results.jsonl
### CSV
Лучше всего подходит для электронных таблиц и отчетности:```bash
--format csv --output results.csv
Сканер использует коды завершения на основе политики.
Таким образом, обнаружение уязвимости может намеренно вернуть ненулевой статус.
Пример:```bash
python3 WP2Shell_CVE-2026-63030_POC.py local
--wordpress-root /var/www/html
--fail-on vulnerable
echo $?
---
## Дифференциальный тест уязвимой и исправленной версий
### Уязвимая среда```text
WordPress 7.0.1
Ожидается:```text route-confusion-observed repeatable true/false SQL timing difference
### Фиксированное окружение```text
WordPress 7.0.2
Ожидается:```text route-confusion-not-observed SQLi timing test not reached or no valid timing oracle
Всегда пересоздавайте том WordPress при смене версий. Повторное использование тома может сохранить старые или автоматически обновленные основные файлы.```bash
docker compose down -v
docker compose pull
docker compose up -d
Немедленно обновитесь до одного из исправленных выпусков или более поздней поддерживаемой версии:
Временные меры должны охватывать обе формы пакетных конечных точек:```text /wp-json/batch/v1 /?rest_route=/batch/v1
Дополнительные защитные меры:
1. Проверяйте журналы на наличие анонимных пакетных запросов, некорректных внутренних URL-адресов, вложенных пакетных структур и необычных значений `author_exclude`.
2. После любого периода воздействия проверяйте учетные записи администраторов, изменения плагинов, неожиданные PHP-файлы и доступ к базе данных.
3. Подтверждайте контрольные суммы ядра WordPress и восстанавливайте из заведомо исправной резервной копии, если есть подозрения на компрометацию.
4. Если могла иметь место эксплуатация SQL-инъекции, смените секреты и учетные данные, хранящиеся в базе данных WordPress.
Блокировка конечной точки — временная мера, а не замена обновления ядра WordPress.
---
## Идеи для обнаружения
Потенциальные индикаторы включают:
- Анонимные `POST`-запросы к любой из форм пакетных конечных точек.
- HTTP-ответы `207`, содержащие вложенные массивы `responses`.
- Некорректные внутренние URL-адреса в телах пакетных запросов.
- Вложенные объекты `requests` внутри другого элемента пакета.
- Скалярные или SQL-образные значения `author_exclude`.
- Повторяющиеся парные запросы с чередованием быстрых и задержанных ответов.
- Неожиданное создание администратора WordPress.
- Неожиданная установка или активация плагина.
- Новые PHP-файлы в каталогах WordPress с правом записи.
- Запросы к базе данных, содержащие необычные выражения `author__not_in`.
---
## Известные ограничения в предоставленном скрипте
- Обработка cookie-файлов не эквивалентна постоянной сессии браузера.
- В некоторых путях кода предполагаются префиксы таблиц базы данных.
- Привилегия `FILE` базы данных и пути файловой системы различаются в зависимости от развёртывания.
- `INTO OUTFILE` обычно ограничен и не может перезаписывать существующие файлы.
- WordPress может отключать установку плагинов через `DISALLOW_FILE_MODS`.
- Пороги задержки могут зависеть от прокси, WAF, тайм-аутов PHP, тайм-аутов базы данных и нагрузки.
- Строки версий могут быть скрыты, подделаны, кэшированы или противоречивы.
- Наблюдаемая подверженная версия не доказывает отсутствие бэкпорта безопасности.
- Отсутствие временного сигнала не доказывает, что сервер исправлен.
---
## Ссылки
- Релиз безопасности WordPress 7.0.2:
https://wordpress.org/news/2026/07/wordpress-7-0-2-release/
- Документация WordPress 7.0.2 и изменённые файлы:
https://wordpress.org/documentation/wordpress-version/version-7-0-2/
- NVD — CVE-2026-63030:
https://nvd.nist.gov/vuln/detail/CVE-2026-63030
- NVD — CVE-2026-60137:
https://nvd.nist.gov/vuln/detail/CVE-2026-60137
- Архив релизов WordPress:
https://wordpress.org/download/releases/
---
## Юридическое и этическое использование
Используйте этот проект только если:
- Вы владеете системой, или
- У вас есть явное письменное разрешение, и
- Запрашиваемая тестовая деятельность соответствует согласованному объёму.
Не выставляйте заведомо уязвимые установки WordPress в открытый Интернет. Используйте одноразовые учётные данные, синтетические данные, изолированные сети и чистые снимки. Уничтожайте или сбрасывайте лабораторию после тестирования.
Наиболее безопасным доказательством уязвимости является минимально необходимые доказательства для демонстрации проблемы:```text
Affected version
+
Route-confusion behavior
+
Repeatable constant-condition SQL timing oracle
Кража учетных данных, установка постоянного доступа, установка веб-шелла и выполнение команд не обязательны для подтверждения существования уязвимости.
| Ветвь WordPress | Затронуты | Исправленный релиз |
|---|
| 6.8.x | CVE-2026-60137 only: 6.8.0–6.8.5 | 6.8.6 |
| 6.9.x | Обе проблемы: 6.9.0–6.9.4 | 6.9.5 |
| 7.0.x | Обе проблемы: 7.0.0–7.0.1 | 7.0.2 |
| 7.1 prerelease | Бета 1 затронута | Бета 2 |
| Ранее 6.8 | Не затронуты этими двумя CVE | N/A |
| Вердикт | Значение |
|---|
CONFIRMED_VULNERABLE_BEHAVIOR | Наблюдалось поведение путаницы маршрутов во время выполнения |
CONFIRMED_AFFECTED_VERSION | Локальная версия исходного кода находится в уязвимом диапазоне |
LIKELY_VULNERABLE | Данные удаленной версии указывают на уязвимый выпуск |
VULNERABLE_SQLI_ONLY | Версия затронута CVE-2026-60137, но находится вне полного диапазона путаницы маршрутов |
AFFECTED_VERSION_BUT_BEHAVIOR_NOT_OBSERVED | Обнаружена уязвимая версия, но безопасное поведение во время выполнения отсутствовало |
PATCHED_VERSION | Версия соответствует опубликованной исправленной границе |
NOT_AFFECTED | Версия находится вне затронутой ветки |
POTENTIALLY_EXPOSED_VERSION_UNKNOWN | WordPress и пакетный маршрут найдены, но версия скрыта |
WORDPRESS_VERSION_UNKNOWN | WordPress обнаружен без надежных доказательств версии |
ERROR | Цель не может быть оценена |
NOT_WORDPRESS_OR_NOT_DETECTED | Нет надежных доказательств WordPress |
| Код | Значение |
|---|
0 | Нет результата, вызывающего политику, или --fail-on never |
2 | Результат уязвимый или затронутый по умолчанию политике |
3 | Неизвестный или неубедительный результат при выборе --fail-on unknown |
1 | Ошибка аргумента, ввода или неполной команды |