
Atlassian Jira unauthentifizierte Template-Injection
4.4.x
5.x.x
6.x.x
7.0.x
7.1.x
7.2.x
7.3.x
7.4.x
7.5.x
7.6.x before 7.6.14 (the fixed version for 7.6.x)
7.7.x
7.8.x
7.9.x
7.10.x
7.11.x
7.12.x
7.13.x before 7.13.5 (the fixed version for 7.13.x)
8.0.x before 8.0.3 (the fixed version for 8.0.x)
8.1.x before 8.1.2 (the fixed version for 8.1.x)
8.2.x before 8.2.3 (the fixed version for 8.2.x)
set JVM_SUPPORT_RECOMMENDED_ARGS= in der Datei ./bin/setenv.bat (oder analog in ./bin/setenv.sh unter Linux), um Remote-Debugging zu ermöglichen.set JVM_SUPPORT_RECOMMENDED_ARGS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
Remote JVM Debug mit host und port als localhost:5005 und Command line arguments for remote JVM-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
Führe die Datei ./bin/config.bat aus (oder unter Linux die Datei config.sh) und setze "Jira home" auf dein Jira-Home-Verzeichnis.

Führe die Datei ./bin/start-jira.bat aus (oder ./bin/start-jira.sh unter Linux). Prüft, ob die Java-Version passt und die Ports 8080 und 5005 frei sind, falls es nicht startet!
Wir wählen den privaten Modus.

An diesem Punkt müsst ihr unbedingt eine E-Mail-Adresse verwenden, die E-Mails empfangen kann :)

Konfiguriert und testet die Verbindung vollständig.

Unter http://localhost:8080/secure/admin/EditApplicationProperties!default.jspa aktivieren wir die Funktion Contact Administrators Form.

Ich notiere nur ein paar Hinweise zum Build; ihr könnt Building Jira from Source nachlesen.
Nach dem Lesen des Advisories wissen wir, dass dieser Bug in ContactAdministrators und SendBulkMail liegt (Letzteres überspringe ich, da es eine Authentifizierung erfordert). Deshalb beginne ich, die Funktion ContactAdministrators zu testen, und fange die Anfrage ab.

Ich sehe, dass die Anfrage an /secure/ContactAdministrators.jspa geht; also schaue ich in die Datei ./atlassian-jira/WEB-INF/web.xml, um herauszufinden, an welche Klasse diese Anfrage weitergeleitet wird.


Die Anfrage wird also von JiraWebworkActionDispatcher verarbeitet. Deshalb setze ich in dieser Klasse Haltepunkte in init und server und starte das Debugging.

Damit stoppt das Programm in der Methode server; nach etwas Tracing springt es zu ContactAdministrators.doExecute().

Danach geht es durch send; hier listet das Programm die aktiven Admin-Konten auf.

Danach durchläuft das Programm die Funktion sendTo. Hier sehen wir, dass das Programm eine MailQueueItem erstellt und sie zur mailQueue hinzufügt.

Das Programm ruft die Funktion EmailBuilder.withSubject auf. Hier wird der Subject-String der E-Mail (vom Angreifer gesendet) von String in TemplateSources umgewandelt und dem Parameter subjectTemplate des EmailBuilder zugewiesen.

In der Funktion renderLater erstellt das Programm einen EmailRenderer und verwendet ihn, um eine RenderingMailQueueItem zu erzeugen.

Von hier aus zurück in der Funktion ContactAdministrators.sendTo: Nachdem eine MailQueueItem erstellt wurde, fügt das Programm das Element zur mailQueue hinzu und kehrt zur Funktion doExecute zurück, um eine Weiterleitung durchzuführen. Wenn wir diesem Debug-Fluss folgen, können wir nicht zu dem Teil springen, in dem das Programm die E-Mail rendert, und erreichen daher die Stelle nicht, an der die Template-Injection auftritt. Was also tun, um die E-Mail-Verarbeitung zu verfolgen???
Ich sehe, dass EmailRenderer eine Funktion renderNow hat (das Programm ruft nur renderLater auf). Ich vermute, dass eine E-Mail in der Warteschlange, wenn sie zum Rendern aufgerufen wird, dem gleichen Ablauf wie renderNow folgt. Deshalb beschließe ich, ab renderNow zu tracen.

Von renderNow ruft das Programm EmailRenderer.render() auf. Ich setze hier einen Haltepunkt und sende die Anfrage erneut, um zu sehen, ob das Programm tatsächlich bis hierher läuft.

Glücklicherweise folgt das Programm genau der vermuteten Richtung. Als Nächstes ruft es renderEmailSubject auf.

Danach ruft das Programm DefaultVelocityTemplatingEngine.render(this.subjectTemplate) auf.

Es gelangt zu DefaultVelocityTemplatingEngine.applying und DefaultVelocityTemplatingEngine.asPlainText.

Weiter geht es mit dem Aufruf von asPlainText(Writer writer).

Bei toWriterImpl springt das Programm, da der übergebene writer ein Fragment ist, in den else-Zweig.
private void toWriterImpl(Writer writer, boolean attachCartridge) throws IOException {
if (this.source instanceof File) {
File template = (File)this.source;
if (attachCartridge) {
this.context.attachEventCartridge(DefaultVelocityTemplatingEngine.this.createDefaultCartridge());
}