
Analyse technique et preuve de concept d'exploitation pour CVE-2021-26084, une vulnérabilité d'injection OGNL dans Atlassian Confluence Server. Comprend une analyse de la cause racine, un mappage des paramètres vulnérables et des conseils de détection.
Versions affectées
Version < 6.13.23
6.14.0 ≤ Version < 7.4.11
7.5.0 ≤ Version < 7.11.6
7.12.0 ≤ Version < 7.12.5
Cause, Méthode d'exploitation
Confluence utilise un framework pour mapper les URL vers des classes Java, créant ce qu’on appelle une « action ». Les URL d’action se terminent par « .action » et sont définies dans le fichier xwork.xml dans confluence-.jar et dans le fichier atlassian-plugin.xml dans les fichiers JAR des plugins inclus. Chaque action contient au moins un attribut name, définissant le nom de l’action, un attribut class, définissant la classe Java qui exécute l’action, et au moins un élément result qui détermine le template Velocity à afficher après que l’action est appelée en fonction du résultat de l’action. Les valeurs courantes renvoyées par les actions sont « error », « input », « success », mais tout résultat peut être utilisé s’il correspond à un élément result dans le XML XWork. Les actions peuvent contenir un attribut method qui permet d’appeler une méthode spécifique de la classe Java spécifiée. Lorsqu’aucune commande n’est spécifiée, la méthode doDefault() est appelée. Ci-dessous se trouve l’entrée d’action pour l’action createpage-entervariables :

La méthode doEnter() de la classe com.atlassian.confluence.pages.actions.PageVariablesAction traite les requêtes vers doenterpagevariables.action et renvoie les valeurs « error », « input », « success ». Cela conduit à l’affichage du template Velocity.
Ici, la valeur de l’attribut « name » d’un élément action correspond à un chemin /.action et l’élément détermine quel template sera affiché dans la réponse en fonction de error/success,... Donc selon cet exemple, il suffit d’accéder à /pages/doenterpagevariables.action pour afficher le fichier template Velocity.

Nous pouvons voir comment le template Velocity est affiché dans la page HTML

Saisir le nom de la balise dans le template comme paramètre et constater que les valeurs sont extraites du paramètre de la requête et renvoyées dans la réponse.

Utilisation de #tag : #tag (« attribute1 », « attribute2 », « attribute3 »)
Ces attributs pendant le rendu sont extraits dans AbstrctTagDirective.applyAttributes()

#tag ("Hidden" "name='queryString'" "value='ahihihi'")
Après que les attributs sont extraits par la méthode AbstrctTagDirective.applyAttributes(), ils sont passés à AbstrctUITag.doEndTag() → AbstractUITag.evaluateParams()

Ensuite, ils sont successivement passés à WebWorkTagSupport.findValue() → OgnlValueFinder.findValue() sous forme d’expression.

Puis passés à SafeExpressionUtil.isSafeExpression()

Ici, l’expression est passée à compile, vérifiée par la blacklist et mise en cache. Après la compilation, elle est compilée sous forme ASTConst et lorsqu’elle est évaluée, elle renvoie la chaîne déjà compilée.

Lorsque l’expression reçoit le caractère « ' » depuis l’entrée, il est échappé en entité HTML.

Le point d’échappement est dans HtmlAnnotationEscaper.annotatedValueInsert()

Ici, la méthode ognl.JavaCharStream.readChar() est appelée et évalue les caractères d’échappement Unicode, donc lors de l’envoi de « \u0027 », il le convertit en « ' ». Ainsi, il est possible d’échapper et d’ajouter une expression OGNL.

Mais il faut franchir la blacklist d’OGNL comme suit :

On peut la contourner en utilisant des accesseurs de tableau au lieu d’utiliser la méthode « getClass » ou la propriété « .class ».
queryString=aaa\u0027%2b#{\u0022\u0022[\u0022class\u0022]}%2b\u0027bbb

Méthode de détection
Surveiller toutes les requêtes HTTP où le composant chemin de l’URI de la requête contient l’une des chaînes de la colonne « URI Path » du tableau suivant :
URI Path | Vulnerable Parameters
/users/darkfeatures.action | featureKey
/users/enabledarkfeature.action | featureKey
/users/disabledarkfeature.action | featureKey
/login.action | token
/dologin.action | token
/signup.action | token
/dosignup.action | token
/pages/createpage-entervariables.action | queryString, linkCreation
/pages/doenterpagevariables.action | queryString
/pages/createpage.action | queryString
/pages/createpage-choosetemplate.action | queryString
/pages/docreatepagefromtemplate.action | queryString
/pages/docreatepage.action | queryString
/pages/createblogpost.action | queryString
/pages/docreateblogpost.action | queryString
/pages/copypage.action | queryString
/pages/docopypage.action | queryString
/plugins/editor-loader/editor.action | syncRev
Si une telle requête est trouvée, il faut vérifier la méthode HTTP de la requête. Si la méthode de la requête est POST, rechercher les paramètres vulnérables correspondants dans le corps de la requête HTTP ; si la méthode est GET, rechercher les paramètres dans l’URI de la requête. Vérifier si la valeur de l’un des paramètres vulnérables contient la chaîne « \u0027 » ou sa forme encodée en URL. Si c’est le cas, le trafic est considéré comme malveillant et une attaque exploitant cette vulnérabilité pourrait être en cours.