
Technische Analyse und Proof-of-Concept-Exploit für CVE-2021-26084, eine OGNL-Injection-Schwachstelle in Atlassian Confluence Server. Enthält Aufschlüsselung der Grundursache, Zuordnung anfälliger Parameter und Erkennungsanleitung.
Betroffene Versionen
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
Ursache und Ausnutzung
Confluence verwendet ein Framework, um URLs auf Java‑Klassen abzubilden, wodurch sogenannte „Actions“ entstehen. Action‑URLs enden mit „.action“ und werden in der Datei xwork.xml in confluence-.jar sowie in der Datei atlassian-plugin.xml in den JAR‑Dateien der mitgelieferten Plugins definiert. Jede Action enthält mindestens ein Attribut name, das den Aktionsnamen festlegt, ein Attribut class, das die ausführende Java‑Klasse bestimmt, und mindestens ein Element result, das die Velocity‑Vorlage festlegt, die nach dem Aufruf der Action basierend auf dem Ergebnis der Action angezeigt wird. Übliche von Actions zurückgegebene Werte sind „error“, „input“, „success“, aber jedes Ergebnis kann verwendet werden, wenn es mit einem result-Element im XWork‑XML übereinstimmt. Actions können ein Methodenattribut enthalten, das den Aufruf einer bestimmten Methode der angegebenen Java‑Klasse ermöglicht. Wenn kein Befehl angegeben ist, wird die Methode doDefault() aufgerufen. Nachfolgend der Action‑Eintrag für die createpage-entervariables-Action:

Die Methode doEnter() der Klasse com.atlassian.confluence.pages.actions.PageVariablesAction verarbeitet Anfragen an doenterpagevariables.action und gibt die Werte „error“, „input“, „success“ zurück. Dies führt dazu, dass die Velocity‑Vorlage angezeigt wird.
Hier entspricht der Wert des Attributs „name“ eines Action‑Elements einem Pfad /<nameValue>.action und das Element enthält die Vorlage, die als Teil der Antwort basierend auf error/success angezeigt wird. In diesem Beispiel reicht es also, /pages/doenterpagevariables.action aufzurufen, um die Velocity‑Vorlagendatei anzuzeigen.

Wir können sehen, wie die Velocity‑Vorlage in der HTML‑Seite angezeigt wird.

Geben Sie den Tag‑Namen in der Vorlage als Parameter ein und stellen Sie fest, dass die Werte aus den Request‑Parametern übernommen und in der Response zurückgegeben werden.

Verwendung von #tag: #tag („attribute1“, „attribute2“, „attribute3“)
Diese Attribute werden während des Renderings von AbstrctTagDirective.applyAttributes() abgerufen.

#tag ("Hidden" "name='queryString'" "value='ahihihi'")
Nachdem die Attribute von der Methode AbstrctTagDirective.applyAttributes() abgerufen wurden, werden sie an AbstrctUITag.doEndTag() → AbstractUITag.evaluateParams() übergeben.

Anschließend werden sie an WebWorkTagSupport.findValue() → OgnlValueFinder.findValue() mit der Expression übergeben.

Danach wird sie an SafeExpressionUtil.isSafeExpression() übergeben.

Hier wird die Expression zum Kompilieren übergeben, auf eine Blacklist geprüft und in den Cache aufgenommen. Beim Kompilieren wird sie in die Form ASTConst kompiliert. Wenn sie ausgewertet wird, wird die zuvor kompilierte Zeichenfolge zurückgegeben.

Wenn der Expression aus der Eingabe ein „’“ hinzugefügt wird, wird sie in eine HTML‑Entity escaped.

Der Escape‑Punkt befindet sich bei HtmlAnnotationEscaper.annotatedValueInsert().

Hier wird die Methode ognl.JavaCharStream.readChar() aufgerufen und Unicode‑Escape‑Sequenzen ausgewertet. Wenn also „\u0027“ übergeben wird, wird es in „’“ konvertiert. Daher kann man entkommen und einen OGNL‑Ausdruck anhängen.

Aber man muss die folgende Blacklist von OGNL umgehen:

Man kann sie umgehen, indem man Array‑Zugriff verwendet anstelle der Methode „getClass“ oder der Eigenschaft „.class“.
queryString=aaa\u0027%2b#{\u0022\u0022[\u0022class\u0022]}%2b\u0027bbb

Erkennungsmethode
Überwachen Sie alle HTTP‑Datenverkehrsanfragen, bei denen der Pfadkomponente der Anforderungs‑URI eine der Zeichenfolgen in der Spalte „URI Path“ der folgenden Tabelle enthält:
| 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 |
Wenn eine solche Anfrage gefunden wird, sollte die HTTP‑Anfragemethode überprüft werden. Wenn die Anfragemethode POST ist, suchen Sie die entsprechenden Vulnerable Parameters aus der obigen Tabelle im Body der HTTP‑Anfrage. Wenn die Anfragemethode GET ist, suchen Sie die Parameter in der Request‑URI der HTTP‑Anfrage. Prüfen Sie, ob der Wert eines der Vulnerable Parameters die Zeichenfolge „\u0027“ oder deren URL‑kodierte Form enthält. Wenn ja, wird der Datenverkehr als bösartig betrachtet und ein Ausnutzungsangriff dieser Schwachstelle könnte stattfinden.