Sploitus

Exploit for wp2shell

kitploit · 2026-08-27

Exploit Code

MARKDOWN157 lines
## https://sploitus.com/exploit?id=KITPLOIT:TOOLS-GITHUB-MCIPEKCI-WP2SHELL
# wp2shell — RCE без аутентификации в ядре WordPress

> RCE PoC без аутентификации для ядра WordPress, объединяющий в цепочку CVE-2026-63030 + CVE-2026-60137. Только авторизованное тестирование.

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

CVE| Компонент| Ошибка  
---|---|---  
**CVE-2026-63030**|  обработчик REST `/batch/v1`| **desync** из-за путаницы маршрутов — batch-обработчик теряет синхронизацию между таблицей _обработчиков_ и таблицей _валидации_ , когда путь под-запроса не удаётся разобрать, поэтому под-запрос направляется через обработчик, для которого он никогда не проходил валидацию.  
**CVE-2026-60137**| `WP_Query`| скалярная **SQL-инъекция** — значение `author__not_in` вставляется прямо в SQL, поэтому строка, попадающая в него, инъектируема.  
  
Ни одна из них по отдельности не даёт RCE. Desync — это _доставка_ (он протаскивает строку атакующего в запрос, до которого она никогда не должна дойти); инъекция — это _примитив_. Вместе они дают атакующему без аутентификации полный SQL-оракул чтения/записи, а оттуда — рабочую оболочку.

> ⚠️ **Только авторизованное тестирование.** Этот эксплойт атакует реально работающие WordPress-установки. Используйте его только против систем, которыми вы владеете или на тестирование которых у вас есть явное письменное разрешение.

* * *

## Затронутые версии

Уязвимые версии: **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** (и более поздние) **Сообщил** Адам Кьюс (Assetnote / Searchlight Cyber); вклад в обнаружение SQLi также внесли TF1T, dtro, haongo.

**RCE-способны только версии 6.9.0–7.0.1.** На ветке 6.8.x desync по-прежнему срабатывает, но ветвь, которая должна сместить обработчик, вместо этого упирается в фатальную ошибку `WP_Error::get_method()` — так что 6.8.x — это **отказ в обслуживании / краш** , а не оболочка. Инструмент определяет это и сообщает, какой примитив доступен.

* * *

## Как работает цепочка

Эксплойт построен по слоям; каждый из них — мост к следующему.

  1. **Desync (CVE-2026-63030).** Batch-запрос вкладывает в себя второй batch. Один под-запрос несёт намеренно повреждённый путь (`http://:`, который отклоняет `wp_parse_url()`). В версиях 6.9.0+ неудачный разбор заставляет таблицу обработчиков и таблицу валидации разойтись на одну запись, поэтому _следующий_ под-запрос выполняется через обработчик, для которого он не проходил валидацию, — публичную коллекцию записей.

  2. **Инъекция (CVE-2026-60137).** Этот ошибочно направленный вызов достигает `WP_Query` с контролируемым атакующим `author__not_in`. `UNION ALL SELECT` там не _читает_ строки — он **фабрикует** их, позволяя подделывать произвольные записи в результате запроса.

  3. **Мост SQL → запись.** Сфабрикованные записи содержат разметку `[embed]`. WordPress послушно разрешает и **кэширует** их как настоящие строки post-meta `oembed_cache` — превращая инъекцию только для чтения в произвольный примитив _записи_.

  4. **Смена привилегий.** Используя этот мост записи, мы подделываем (a) **changeset** кастомайзера, автором которого указан настоящий администратор, и (b) самоссылающуюся запись `request`. Вместе они заставляют WordPress **повторно выполнить собственный конвейер запросов от имени этого администратора** — окно, которого как раз хватает, чтобы поставленный в очередь вызов  создал нового администратора.




### Оракулы извлечения

Для чтения (`--dump`, определение префикса, кэшированные ID) инструмент автоматически выбирает самый быстрый работающий оракул и **останавливается на первом же срабатывании** :

  1. **`union`** — in-band UNION: `post_title` сфабрикованной строки содержит `|||HEX(value)|||`, который дословно отражается в теле ответа `/wp/v2/posts`. Считывает целое значение (любой длины) за **один запрос**. Если UNION отражается, булевы оракулы не опрашиваются.
  2. **`bool`** — булев оракул X-WP-Total: заголовок `X-WP-Total` спутанного под-ответа равен `count>0` при true / `0` при false. Один бит за запрос (бисекция).
  3. **`time`** — time-based `SLEEP()`: запасной вариант, когда тело ответа удаляется _и_ ответ — 500 (например, фатальная ошибка после диспетчеризации, вызванная кэширующим mu-плагином). Работает даже на целях, которые падают при каждом REST-вызове.



`--dump` использует `GROUP_CONCAT`, чтобы вытащить весь набор учётных данных одним заходом, когда доступен UNION.

* * *

## Установка

Установка не требуется. Только стандартная библиотека Python 3.7+ — без `pip install`.

root@kitploit:~
    
    
    chmod +x wp2shell.py
    

* * *

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

root@kitploit:~
    
    
    # 1. Is it vulnerable? (no injection, no writes, no account created)
    ./wp2shell.py http://target --check
    
    # 2. Read-only credential dump — FIRST administrator + option secrets
    ./wp2shell.py http://target --dump
    
    #    …every administrator
    ./wp2shell.py http://target --dump all
    
    # 3. Full RCE — create a temp admin, run a command, clean up
    ./wp2shell.py http://target --exec "id; uname -a"
    

### Разведка только для чтения (без создания администратора, обходит 2FA)

root@kitploit:~
    
    
    ./wp2shell.py http://target --user-list          # full user table (logins/emails/roles)
    ./wp2shell.py http://target --content            # every post type at status=any (private/draft)
    ./wp2shell.py http://target --content full        #   …including each item's raw body
    

### Сканирование множества хостов

root@kitploit:~
    
    
    ./wp2shell.py -f targets.txt --check --target-threads 8
    

* * *

## Параметры

### Обход WAF / защитных механизмов

* * *

## Примечания по выводу

  * **Хэши паролей** (`$wp$2y$…` / `$P$…` / `$2y$…`) передаются напрямую в hashcat (`-m 3200` для phpass или режим WP bcrypt). WordPress 6.8+ использует bcrypt `$wp$…`.
  * **`--dump`** по умолчанию извлекает данные только первого администратора. Используйте **`--dump all`** для получения полного списка администраторов.
  * **Цели с ошибкой 500 / крашем:** если фатальная ошибка после диспетчеризации (например, кэширующий mu-плагин в стиле Pantheon) превращает каждый REST-ответ в 500, создание администратора не сработает, но чтение по-прежнему работает — переключитесь на `--oracle time --dump`, чтобы получить хэши.



* * *

## Почему важна очистка

Сценарий `--exec` спроектирован так, чтобы не оставлять **ничего после себя** : временный администратор, его usermeta, сфабрикованные строки `oembed_cache` и загруженный веб-шелл удаляются до выхода из инструмента. Флага `--keep` нет — оператор никогда не должен оставлять живую учётную запись администратора, созданную атакующим, в системе клиента.

* * *

## Файлы

  * `wp2shell.py` — эксплойт (один файл, только стандартная библиотека).



* * *

## Авторство

Авторство в обнаружении уязвимостей, их раскрытии и оригинальном разборе «wp2shell» принадлежит исследовательской команде **Searchlight Cyber / Assetnote** :

  * **CVE-2026-63030** — desync из-за путаницы маршрутов в REST `/batch/v1`
  * **CVE-2026-60137** — SQL-инъекция в `WP_Query author__not_in`



Этот репозиторий — независимая proof-of-concept реализация цепочки эксплойтов, которую они раскрыли; он не претендует на обнаружение лежащих в основе уязвимостей. Если какая-то ссылка на авторство неполна или некорректна, откройте issue, и она будет исправлена.

## Ссылки

  * Searchlight Cyber / Assetnote — _wp2shell: Pre-Authentication RCE in WordPress core_ https://slcyber.io/research-center/wp2shell-pre-authentication-rce-in-wordpress-core/
  * Релиз WordPress 7.0.2 (исправление) — https://wordpress.org/news/2026/07/wordpress-7-0-2-release/
  * Уведомления об уязвимостях — GHSA-ff9f-jf42-662q, GHSA-fpp7-x2x2-2mjf



## Отказ от ответственности

Это proof of concept для исследований в области безопасности, предназначенный для авторизованного тестирования на проникновение и защитной проверки. Запуск его против систем, которыми вы не владеете или на тестирование которых у вас нет письменного разрешения, незаконен. Автор не несёт ответственности за неправомерное использование.