
Apache mod_http2 double-free 취약점(CVE-2026-23918)에 대한 개념 증명 익스플로잇으로, 정찰, 익스플로잇 및 RCE 위험 평가 단계를 포함합니다.
영향받는 버전: Apache HTTP Server 2.4.66에 mod_http2 + Event MPM
수정 버전: Apache 2.4.67 (mod_h2 v2.0.37)
CVSS 3.1: 8.8 HIGH — 인증되지 않은 원격 코드 실행 가능
CWE: CWE-415 (이중 해제)
Apache 2.4.66의 mod_http2는 h2_mplx.c:m_stream_cleanup() 내부에 이중 해제 버그가 있습니다. 이 문제는 클라이언트가 동일한 스트림에서 HEADERS 프레임을 보낸 직후 RST_STREAM을 보낼 때 발생합니다. 타이밍이 맞으면 스트림이 m->spurge 정리 배열에 두 번 푸시됩니다. mplx가 소멸될 때 APR 풀이 두 번 해제되어 힙이 손상되고 SIGABRT 또는 SIGSEGV가 발생합니다.
Apache는 mod_h2 v2.0.37에서 add_for_purge() 함수를 도입하여 이 문제를 패치했습니다. 이 함수는 동일한 스트림이 두 번 추가되는 것을 방지하는 간단한 중복 제거 검사입니다.
// Vulnerable (< v2.0.37)
APR_ARRAY_PUSH(m->spurge, h2_stream *) = stream; // can happen twice
// Fixed (v2.0.37+)
static int add_for_purge(h2_mplx *m, h2_stream *stream) {
for (int i = 0; i < m->spurge->nelts; ++i)
if (APR_ARRAY_IDX(m->spurge, i, h2_stream*) == stream)
return FALSE;
APR_ARRAY_PUSH(m->spurge, h2_stream *) = stream;
return TRUE;
}
기본적으로 스크립트는 대상에 대해 3단계 파이프라인을 실행합니다:
| 단계 | 설명 |
|---|---|
| 1 — 정찰 | Apache 버전, ALPN을 통한 HTTP/2 지원, MPM 유형을 탐지합니다. |
| 2 — 익스플로잇 | 스레드 기반 HEADERS+RST_STREAM 버스트를 전송하고 인라인 모드와 스테이지드 모드를 순차적으로 시도합니다. |
| 3 — RCE 평가 | 충돌 일관성을 측정하고 위험 수준을 점수화합니다. |
RCE 점수는 원격으로 감지 가능한 세 가지 신호로 계산됩니다. 첫째, Apache 2.4.66이 실행 중인지 여부. 둘째, Event 또는 Worker MPM이 사용 중인지 여부 (mod_http2는 Prefork와 함께 시작되지 않으므로 HTTP/2가 작동하면 스레드 MPM입니다). 셋째, 충돌이 얼마나 결정적인지 — 첫 번째 라운드에서 충돌이 발생하면 힙 손상이 제어 가능하고 재현 가능하다는 의미이며, 이는 RCE에 필요한 조건입니다.
pip install hpack requests
# Full PoC on a single target (default behavior)
python poc.py -t 192.168.1.100
# Increase pressure with more rounds, bigger bursts and more threads
python poc.py -t 192.168.1.100 -n 20 -b 500 -w 5
# Passive check only, nothing is sent to the target
python poc.py -t example.com --check-only
# Scan a whole list of targets
python poc.py -l sites.txt -o results.json
# Passive check on a list
python poc.py -l sites.txt --check-only
# Generate a Markdown report after the run
python poc.py -t target.com --report report.md
# one target per line, comments are ignored
192.168.1.100
example.com
example.com:8443
https://example.com
http://example.com:8080
올바른 수정 방법은 Apache를 2.4.67 이상으로 업그레이드하는 것입니다. 즉시 업그레이드할 수 없는 경우 HTTP/2를 비활성화하면 공격 표면이 완전히 제거됩니다:
# Before
Protocols h2 http/1.1
# After (disables HTTP/2)
Protocols http/1.1
이 도구는 공인된 보안 테스트 및 연구 목적으로만 사용됩니다. 어떤 대상에 대해 이 도구를 실행하기 전에 반드시 명시적인 서면 허가를 받으십시오. 작성자는 오용에 대해 책임을 지지 않습니다.
| 플래그 | 기본값 | 설명 |
|---|
-t | — | 단일 대상 (호스트명 또는 IP) |
-l | — | 대상이 한 줄에 하나씩 있는 파일 |
-p | 443 | 포트 |
-n | 10 | 익스플로잇 라운드 수 |
-b | 200 | 라운드당 HEADERS+RST 쌍 수 |
-w | 3 | 라운드당 병렬 연결 수 |
-d | 0.1 | 라운드 간 지연 시간(초) |
-m | inline | 공격 모드: inline 또는 staged |
--no-tls | — | TLS 대신 h2c 사용 |
--check-only | — | 수동 정찰만 수행, 익스플로잇 없음 |
-o | — | 결과를 JSON 파일로 저장 |
--report | — | Markdown 보고서 생성 |
-v | — | 상세 출력 |
| 수준 | 의미 |
|---|
| CRITICAL | 2.4.66 확인됨, HTTP/2 활성화, Event MPM 감지, 충돌이 결정적 — 지금 바로 패치하세요 |
| HIGH | 2.4.66 확인됨, HTTP/2 활성화, 스레드 MPM 사용 중 |
| MEDIUM | 2.4.66 감지되었지만 HTTP/2 또는 충돌이 아직 확인되지 않음 |
| LOW | 버전이 일치하지 않거나 HTTP/2가 감지되지 않음 |
| NONE | 이미 2.4.67+로 패치되었거나 영향을 받지 않음 |