
Schritt-für-Schritt-Analyse und Ausnutzungsanleitung für CVE-2019-3396, eine kritische SSTI-Schwachstelle in Confluence Server & Data Center, einschließlich Debugging und RCE-Payload-Ausführung.
Betroffenes Produkt: Confluence Server & Data Center
Betroffene Versionen: von 6.0.0 bis 6.15.4
Schweregrad: Kritisch (CVSS ~9.8)
Ursache:
Confluence verfügt über das Plugin Widget Connector (zum Einbetten von Videos, externen Inhalten wie YouTube, Vimeo...).
Diese Funktion überprüft die Benutzereingaben nicht ausreichend, was zu einer Server-Side Template Injection (SSTI) führt.
Ein Angreifer kann eine schädliche Payload senden → Confluence rendert sie mit der Velocity Template Engine → Code wird auf dem Server ausgeführt.
https://www.atlassian.com/software/confluence/downloads/binary/atlassian-confluence-6.9.0.zip
https://nguyendt.hashnode.dev/confluence-cve-2019-3396




Widget Connector erwähnt, suchen wir im Quellcode-Ordner von Confluence
com.atlassian.confluence.extra.widgetconnector.WidgetMacro.classDefaultRenderManager.class
getEmbeddedHtml() verwendet
YoutubeRendererurl → die ursprüngliche YouTube-URL, die der Benutzer eingegeben hatparams → eine Map mit Konfigurationsparametern für das Rendering (z. B. Breite, Höhe, verwendete Vorlage …)
getEmbedUrl(), setDefaultParam() und DefaultVelocityRenderService.render()setDefaultParam()
Wenn _template noch nicht vorhanden ist → wird die Standardvorlage youtube.vm zugewiesen.
=> Man kann _template manuell zum Programm hinzufügen
Als nächstes: DefaultVelocityRenderService.render()
Zweck der Funktion
url + Parameter params entgegen..vm), um eingebettetes HTML (iframe, embed, …) zu rendern.Vorlagenauswahl
params _template enthält → diese Vorlage verwenden.embed.vm.Erstelle den Standardkontext mit MacroUtils.defaultVelocityContext().
Füge alle Parameter aus params in den Kontext ein:
tweetHtml → HTML unverändert lassen.GeneralUtil.htmlEncode() kodieren.Füge urlHtml, width, height zum Kontext hinzu (falls leer, Standardwerte 400 × 300 setzen).

VelocityUtils.getRenderedTemplate()
VelocityUtilsgetRenderedTemplate und getRenderedTemplateWithoutSwallowingErrors() aufgerufen
getTemplate() aufgerufen
Hier ist templateName gleich dem obigen _template.
Dann wird VelocityEngine.Template() aufgerufen

VelocityEngine wird weiter RunimeInstance.getTemplate() aufgerufen
RuntimeInstance (Velocity-Kern)
Dies ist das „Herz“ der Velocity Engine. Es kümmert sich um:
Initialisierung der Engine (init)
Verwaltung von Konfiguration, Makros, Parser, Direktiven, Ereignisbehandlern …
Und insbesondere: Ressourcenverwaltung über ResourceManager
→ Das bedeutet, dass RuntimeInstance Ressourcen nicht selbst lädt, sondern an den resourceManager delegiert.
CompatibleVelocityResourceManager.getResource() aufgerufen
ConfigurableResourceManager (Confluence custom)
Dies ist eine Implementierung des Interfaces ResourceManager.
Es ist verantwortlich für:
Verwaltung der Resource-Loader (File Loader, Classpath Loader, URL Loader …).
Verwaltung des globalCache (Cache für Vorlagen nach resourceKey).
Laden/Aktualisieren von Vorlagen (.vm-Dateien), wenn von RuntimeInstance angefordert.

try {
this.refreshResource(resource, encoding);
} catch (ResourceNotFoundException var7) {
this.globalCache.remove(resourceKey);
return this.getResource(resourceName, resourceType, encoding);
}
Wenn eine Ressource im Cache vorhanden ist, wird sie nicht sofort zurückgegeben, sondern es wird refreshResource(...) aufgerufen.
refreshResource vergleicht den letzten Änderungszeitpunkt (lastModified) auf der Festplatte mit dem im Cache.
Wenn die Datei geändert wurde → wird die Ressource im Cache ungültig → neu von der Festplatte geladen → Cache aktualisiert.