Elasticsearch RCE via Groovy Script Injection
Elasticsearch 1.x enabled dynamic Groovy scripting by default, allowing arbitrary Groovy code execution through the search API. CVE-2014-3120 and CVE-2015-1427 (Shellshock) are sandbox escape vulnerabilities that allow code execution even when the sandbox is enabled. These vulnerabilities are fixed in Elasticsearch 1.6+ and removed entirely in 2.x, but they appear regularly on older lab environments and legacy internal deployments.
The attack requires the REST API to be accessible. Unauthenticated access makes it trivial. Authenticated access with a user that can run searches is sufficient.
Verify Version and Scripting State
Confirm the Elasticsearch version before attempting script-based exploitation. Dynamic scripting is only enabled by default on 1.x and only exploitable with these CVEs on specific sub-versions:
{
"name": "node-1",
"cluster_name": "elasticsearch",
"version": {
"number": "1.4.2",
"build_flavor": "default"
}
}
Versions 1.3.x and earlier are vulnerable to CVE-2014-3120 with no sandbox. Versions 1.3.0 to 1.5.x are vulnerable to CVE-2015-1427 sandbox escape. Versions 1.6+ have scripting disabled by default. Confirm scripting is active by running a benign script test first:
{
"hits": {
"hits": [
{
"fields": {
"test": [2]
}
}
]
}
}
A response returning 2 confirms dynamic scripting is active. If you get a script_lang_not_supported or disabled error, scripting is off and these CVEs are not applicable.
CVE-2014-3120 — No Sandbox RCE (1.3.x and earlier)
On versions without the sandbox, Groovy executes directly. The script_fields parameter accepts arbitrary Groovy including Java runtime calls. Confirm command execution with a simple id check:
{
"hits": {
"hits": [
{
"fields": {
"cmd": ["uid=1000(elasticsearch) gid=1000(elasticsearch) groups=1000(elasticsearch)\n"]
}
}
]
}
}
Command output in the cmd field confirms RCE. Get a reverse shell by replacing the id command with a bash reverse shell payload. Set up the listener first:
CVE-2015-1427 — Groovy Sandbox Escape (1.3.0 to 1.5.x)
The Groovy sandbox introduced in 1.3.0 can be escaped by using Java reflection to access restricted classes. The following payload bypasses the sandbox and executes system commands:
The Runtime.exec call via reflection bypasses the sandbox method whitelist. This returns a Process object rather than output text, so combine with a callback or out-of-band technique to confirm execution. A curl beacon to your listener is cleaner than trying to capture output inline:
GET /rce-confirm HTTP/1.1 Host: $LHOST:$LPORT User-Agent: curl/7.x
An incoming request to the listener confirms out-of-band code execution. Follow up with a reverse shell payload using the same reflection-based exec call.
Using searchsploit for Payload Reference
Searchsploit has documented payloads for both CVEs that are useful as a reference if the above variants need adjustment for the specific sub-version:
Elasticsearch - Remote Code Execution (CVE-2014-3120) | exploits/linux/webapps/33370.py Elasticsearch - Remote Code Execution (CVE-2015-1427) | exploits/linux/webapps/36337.py
References
-
Elasticsearch — Security Advisorieswww.elastic.co/community/security (opens in new tab)
CVE-2014-3120 and CVE-2015-1427 advisory details and affected versions
-
Exploit-DB 36337 — Elasticsearch CVE-2015-1427www.exploit-db.com/exploits/36337 (opens in new tab)
Groovy sandbox escape payload reference for 1.3.0 to 1.5.x
Was this helpful?
Your feedback helps improve this page.