##
# wpsqli — экстрактор SQL-инъекций для WordPress (CVE-2026-60137)
> Быстрый инструмент извлечения данных из базы с меню-интерфейсом, эксплуатирующий уязвимость SQL-инъекции `author__not_in` в ядре WordPress. Инструмент сфокусирован исключительно на перечислении и дампе базы данных, используя путаницу маршрутов REST batch-эндпоинта (CVE-2026-63030) для достижения SQLi-приёмника без аутентификации.
`wpsqli` — это инструмент на чистом Python, предназначенный для эксплуатации цепочки уязвимостей в ядре WordPress, позволяющей выполнять неаутентифицированную SQL-инъекцию в базу данных. Он обходит проверки WordPress REST API через баг путаницы batch-маршрутов, доставляя сырую строковую нагрузку напрямую в SQL-приёмник `WP_Query`.
Инструмент создан для скорости и гибкости: он автоматически пытается выполнить UNION-based in-band извлечение (мгновенно), при неудаче переключается на параллельное boolean-blind извлечение в 8 потоков и, наконец, на последовательное time-based извлечение, если это необходимо.
Инструмент связывает две независимые уязвимости для достижения неаутентифицированного извлечения данных:
### Баг A — SQL-инъекция `author__not_in` (CVE-2026-60137)
**Расположение:** `wp-includes/class-wp-query.php`, `WP_Query::get_posts()`
Параметр `author__not_in` применяет санитизацию `absint()` только в том случае, если входные данные являются массивом. Если передана строка, проверка `is_array()` пропускается, строка проходит через `implode()` без изменений и конкатенируется как есть в SQL-условие `$where`.
// Строка 2404: защита срабатывает только для МАССИВОВ
if ( is_array( $query_vars['author__not_in'] ) ) {
$query_vars['author__not_in'] = array_unique( array_map( 'absint', $query_vars['author__not_in'] ) );
$author__not_in = implode( ',', (array) $query_vars['author__not_in'] );
$where .= " AND {$wpdb->posts}.post_author NOT IN ($author__not_in) ";
### Баг B — Путаница REST batch-маршрутов (CVE-2026-63030)
Эндпоинт REST API для записей сопоставляет `author_exclude` с `author__not_in`, но объявляет его как `type => 'array'` целых чисел, поэтому ядро приводит/отклоняет строку. Баг B протаскивает строку мимо проверки, используя баг рассинхронизации в REST batch-эндпоинте (`/wp-json/batch/v1`). Путём внедрения повреждённого path-праймера, который отклоняет `wp_parse_url()`, в список batch-запросов внедряется `WP_Error`, что рассинхронизирует `$matches` с `$validation`. Это позволяет следующему подзапросу быть отправленным под неправильным обработчиком без проверки параметров.
**Предупреждение:** SQLi-приёмник достижим только при условии, что постоянный объектный кеш (Redis/Memcached) НЕ используется.
* **Без зависимостей:** Чистая стандартная библиотека Python. `pip install` не требуется.
* **UNION-based:** Формирует поддельную строку `wp_posts` для извлечения целых строк за один HTTP-запрос (мгновенно).
* **Boolean-blind (параллельно):** Если UNION заблокирован объектным кешированием, использует 8 параллельных потоков с бинарным поиском для извлечения ~7 запросов на символ.
* **Time-based (последовательно):** Запасной вариант, если boolean-оракул не возвращает строк.
* **Полное перечисление:** Вывод списка баз данных, таблиц и колонок.
* **Дамп таблиц:** Дамп отдельных таблиц, всех таблиц в БД или полный «ядерный» дамп в текстовый файл с меткой времени.
* **Корректное прерывание:** `Ctrl+C` во время извлечения останавливает текущий запрос и возвращает частичные результаты без завершения сеанса.
* **Постоянство сеанса:** Подключитесь один раз и выполняйте несколько запросов через интерактивное меню.
* **Санитизация URL:** Автоматически удаляет пути/запросы из введённого хоста, чтобы предотвратить дублирование эндпоинтов.
* **Вывод, готовый к взлому:** Дампы пользователей включают формат `ID|user_login|user_pass` с bcrypt-хешами, готовыми для `hashcat -m 35500`.
Установка не требуется. Просто скачайте и запустите:
git clone
* Внешние пакеты не требуются (только стандартная библиотека)
============================================================
============================================================
------------------------------------------------------------
1. Проверить цель (версия + подтверждение уязвимости)
------------------------------------------------------------
------------------------------------------------------------
------------------------------------------------------------
14. Полный дамп в файл (все таблицы + все строки)
------------------------------------------------------------
============================================================
Target (
[+] Batch endpoint:
[!] UNION not available — trying boolean blind (8 parallel threads) ...
[+] Boolean-blind mode active (8 threads, ~7 reqs/char)
[+] Time-based also works (0.69s vs 3.78s)
`0`| Подключение к цели (URL автоматически санитизируется)
`1`| Проверка уязвимости и активного режима извлечения
`9`| Список всех баз данных на MySQL-сервере
`10`| Список всех таблиц в текущей или указанной базе данных
`11`| Список всех имён колонок для конкретной таблицы
`12`| Дамп одной таблицы (с опциональным лимитом строк и сохранением в файл)
`13`| Дамп всех таблиц в текущей базе данных
`14`| Полный «ядерный» дамп — все таблицы + все строки в файл с меткой времени
Инструмент автоматически пробует три режима извлечения в порядке убывания скорости:
Формирует поддельную строку `wp_posts` с извлечённым значением, закодированным в hex в колонке `post_title` (обёрнутым в маркеры `||..||`). REST API отражает её в ответе — вся строка за один HTTP-запрос.
* Работает только при отсутствии активного постоянного объектного кеша
* Использует `CONCAT(0x7c7c, HEX(CAST(( ) AS CHAR)), 0x7c7c)` для кодирования результата
Если UNION недоступен, использует 8 параллельных потоков с бинарным поиском для извлечения каждого символа. Boolean-оракул проверяет, возвращает ли внедрённое `AND (condition)` строки.
* **~7 запросов на символ** (распараллелено на 8 потоков)
* Бинарный поиск по диапазону ASCII 32-126
* Предварительное сканирование длины строки бинарным поиском перед извлечением
* Прогресс отображается как количество завершённых символов
Запасной вариант, если boolean-оракул не возвращает строк (например, сайт с 0 опубликованных записей). Использует `IF(condition, SLEEP(N), 0)` для кодирования истины в задержке ответа.
* **~7 × sleep_delay секунд на символ** (последовательно)
* Самый медленный режим, но работает на пустых базах данных
### Примеры замеров времени (Boolean, 8 потоков)
Этот инструмент предназначен только для авторизованного тестирования безопасности и образовательных целей. Вы должны использовать этот инструмент только против систем, которыми владеете или на тестирование которых имеете явное письменное разрешение. Несанкционированный доступ к компьютерным системам противозаконен.
Авторы и участники этого инструмента не несут ответственности за любое неправомерное использование или ущерб, причинённый данным программным обеспечением. Используйте на свой страх и риск.
* Цепочка уязвимостей обнаружена **Adam Kues** (Assetnote / Searchlight Cyber)
* Техника UNION поддельной записи: **sergiointel/wp2shell-poc** (первоисточник)
* Реализация адаптирована из: **Icex0/wp2shell-poc**
* Техника обнаружения путаницы маршрутов: **Hadrian / Icex0**
Этот инструмент предоставляется исключительно для образовательных целей и авторизованного тестирования.
The full story
This article is one source in a clustered incident — the cluster page carries the summary, timeline and every other outlet covering it.
