
Apache HTTP Server를 CVE-2026-23918(HTTP/2 double-free RCE) 및 관련 CVE 4건에 대해 점검하는 Python 툴킷. ALPN 검증 기능을 갖춘 패시브 스캐너 + 읽기 전용 로컬 감사 도구. 익스플로잇 미포함.
CVE-2026-23918(Apache HTTPD HTTP/2 이중 해제 RCE) 및 2026년 5월 4일 Apache Software Foundation 보안 권고에서 공개된 4개의 관련 CVE에 대한 방어적 감사 도구입니다.
| CVE | 심각도 | 구성 요소 | 영향 | 영향 버전 |
|---|---|---|---|---|
| CVE-2026-23918 | 높음 (CVSS 8.8) | HTTP/2 | 이중 해제 / RCE | 2.4.66만 해당 |
| CVE-2026-24072 | 중간 | mod_rewrite (ap_expr) | 권한 상승 | ≤ 2.4.66 |
| CVE-2026-28780 | 낮음 | mod_proxy_ajp | 힙 버퍼 오버플로 | ≤ 2.4.66 |
| CVE-2026-29168 | 낮음 | mod_md (OCSP) | 리소스 고갈 | 2.4.30 – 2.4.66 |
| CVE-2026-29169 | 낮음 | mod_dav_lock | NULL 포인터 역참조 / DoS | ≤ 2.4.66 |
모든 문제는 Apache HTTP Server 2.4.67에서 패치되었습니다.
이 도구는 소유하고 있거나 테스트에 대한 명시적인 서면 승인을 받은 시스템에만 사용하도록 제작되었습니다. 승인되지 않은 스캔은 해당 지역에서 불법일 수 있습니다.
이 툴킷은 설계상 방어적입니다:
Server: HTTP 헤더만 읽고 표준 TLS ALPN을 사용합니다. 이는 모든 최신 브라우저가 HTTP/2를 협상하는 데 사용하는 것과 동일한 메커니즘입니다..
├── apache_passive_audit.py # External asset audit (banner-grab + ALPN)
├── apache_local_audit.py # On-host / SSH local audit
├── LICENSE # MIT
├── .gitignore
└── README.md
python3 및 이후 모든 릴리스에서 작동합니다.git clone https://github.com/sibersan/cve-2026-23918.git
cd cve-2026-23918
chmod +x apache_passive_audit.py apache_local_audit.py
apache_passive_audit.pyHTTP Server: 헤더를 읽어 Apache 버전을 감지하고 CVE 테이블과 대조합니다. 또한 HTTPS 대상에 대해 표준 TLS ALPN 협상을 수행하여 HTTP/2가 노출되었는지 확인합니다. 이는 CVE-2026-23918이 악용 가능하기 위한 핵심 전제 조건입니다. 익스플로잇 페이로드는 전송되지 않습니다.
이 스크립트는 TLS 핸드셰이크의 ALPN 확장(RFC 7301)에서 h2와 http/1.1을 제공합니다. 서버의 선택은 "HTTP/2가 활성화되어 있습니까?"에 대한 표준적이고 명확한 답변입니다 — 모든 최신 브라우저와 curl이 사용하는 방식입니다. 취약점이나 비정상적인 동작을 유발하지 않습니다.
위험 판정은 이를 반영합니다:
# Single target
python3 apache_passive_audit.py -t https://web.example.com
# Multiple targets
python3 apache_passive_audit.py -t https://a.example.com -t https://b.example.com
# Targets file, parallel, CSV + JSON output
python3 apache_passive_audit.py -f targets.txt -w 20 -o report.csv --json report.json
# CI / log-friendly (no colors)
python3 apache_passive_audit.py -f targets.txt --no-color
targets.txt 형식 (한 줄에 대상 하나, 주석은 #):
https://www.example.com
intranet.example.local:8443
# old staging box
http://10.0.5.12
| 코드 | 의미 |
|---|---|
| 0 | 모든 대상 안전 |
| 1 | 하나 이상의 대상이 UNKNOWN 또는 ERROR |
| 2 | 하나 이상의 대상이 VULNERABLE 또는 AT_RISK |
ServerTokens Prod 또는 Minimal로 설정된 서버는 버전을 숨깁니다 — 스크립트는 정직하게 UNKNOWN을 반환합니다. 로컬 감사로 확인하세요.apache_local_audit.py대상 호스트에서(또는 SSH를 통해) 실행되어 Apache 바이너리, 버전, 로드된 모듈 및 HTTP/2 구성을 검사합니다. 또한 악용 가능성 전제 조건을 평가합니다: 예를 들어 버전이 2.4.66이지만 HTTP/2가 비활성화된 경우 CVE-2026-23918의 위험이 그에 따라 낮아집니다.
sudo python3 apache_local_audit.py
# JSON report (for centralized inventory)
sudo python3 apache_local_audit.py --json /var/log/apache_audit_$(hostname).json
# Custom binary path
sudo python3 apache_local_audit.py --binary /opt/apache/bin/httpd
httpd -v / apache2 -v — 버전httpd -V — 빌드 정보, HTTPD_ROOT, SERVER_CONFIG_FILEapache2ctl -M 또는 httpd -M — 로드된 모듈dpkg-query / rpm -q — 패키지 버전Include/IncludeOptional을 통해 포함된 모든 파일(Debian의 sites-enabled/, mods-enabled/ 포함) → Protocols 지시문 (h2 / h2c / http/1.1)| 플래그 | 설명 |
|---|---|
--binary | Apache 바이너리 경로 (자동 감지 재정의) |
--json | JSON 보고서 출력 |
--no-color | 색상 출력 비활성화 |
| 코드 | 의미 |
|---|---|
| 0 | SAFE |
| 1 | PATCH_NEEDED 또는 UNKNOWN |
| 2 | VULNERABLE 또는 AT_RISK |
전체 구성 읽기를 위해서는 sudo/root가 권장됩니다. 권한이 없으면 sites-enabled/, mods-enabled/ 또는 /etc/httpd/conf.d/의 일부 파일을 읽지 못할 수 있습니다.
여러 호스트에서 로컬 감사를 실행하고 보고서를 중앙에서 수집하려면 Ansible ad-hoc 예시:
ansible all -i inventory.ini -b -m script \
-a "apache_local_audit.py --json /tmp/apache_audit.json --no-color"
ansible all -i inventory.ini -b -m fetch \
-a "src=/tmp/apache_audit.json dest=./reports/ flat=no"
수집된 JSON 파일은 jq 또는 간단한 Python 스크립트로 병합할 수 있습니다.
CVE-2026-23918의 경우 (패치 적용 전까지):
Protocols 지시문에서 h2와 h2c를 제거하거나 Debian/Ubuntu에서 sudo a2dismod http2를 실행한 후 서비스를 리로드하세요.mod_dav_lock을 언로드하세요 (CVE-2026-29169)..htaccess 쓰기 권한이 있는 사용자/가상 호스트를 감사하세요 (CVE-2026-24072).공식 권고: https://httpd.apache.org/security/vulnerabilities_24.html
풀 리퀘스트를 환영합니다. 새 CVE를 추가할 때는 다음을 수행해 주세요:
match 람다를 사용하여 CVE_TABLE에 항목을 추가하세요.needs 필드를 정의하세요.from __future__ import annotations, PEP 585 제네릭(list[int]), subprocess.run(capture_output=True) 및 @dataclass를 피하세요.MIT © 2026 SiberSAN
이 소프트웨어는 어떠한 종류의 보증도 없이 "있는 그대로" 제공됩니다. 프로덕션 사용 전에 테스트 환경에서 검증하세요. 승인되지 않은 시스템에 대한 사용에 따른 모든 법적 책임은 사용자에게 있습니다.
| 플래그 | 설명 |
|---|
-t, --target | 단일 대상 (반복 가능) |
-f, --file | 대상 목록 파일 |
-o, --csv | CSV 보고서 출력 |
--json | JSON 보고서 출력 |
--timeout | 요청 제한 시간(초) (기본값 10) |
-w, --workers | 병렬 작업자 스레드 (기본값 10) |
--no-color | 색상 출력 비활성화 |
| 수준 | 의미 |
|---|
VULNERABLE | 버전이 권고된 CVE 범위와 일치 AND 전제 조건 충족 (예: HTTP/2 활성화) |
AT_RISK | 패치되지 않은 버전이지만 높은 심각도 전제 조건은 충족되지 않음, 다른 CVE는 여전히 적용됨 |
SAFE | 버전 ≥ 2.4.67 |
UNKNOWN | 배너가 숨겨져 있거나(ServerTokens Prod) 리버스 프록시/WAF에 의해 가려짐 — 로컬 감사 스크립트로 확인 |
NOT_APACHE | Apache가 아님 (nginx, IIS 등) |
ERROR | 연결 오류 |
| 수준 | 의미 |
|---|
VULNERABLE | 패치되지 않은 버전 + 높은 심각도 CVE 전제 조건 충족 (예: HTTP/2 활성화) |
AT_RISK | 패치되지 않은 버전 + 하나 이상의 CVE 전제 조건 충족 |
PATCH_NEEDED | 패치되지 않은 버전이지만 관련 모듈/프로토콜이 활성화되지 않음 — 그래도 패치 필요 |
SAFE | 버전 ≥ 2.4.67 |
UNKNOWN | 버전을 감지할 수 없음 |