CVE-2019-9514: HTTP/2 Reset Flood 拒绝服务漏洞分析
0x00 漏洞背景与详情
- CVE 编号:CVE-2019-9514
- 漏洞名称:HTTP/2 Reset Flood (HTTP/2 重置洪水攻击)
- 影响协议:HTTP/2 (RFC 7540)
- 危险等级:高危 (CVSS 7.5)
- 影响范围:几乎所有主流 HTTP/2 服务端实现,包括 Nginx (1.10.0+), Apache (2.4.17+), Go
net/http, Node.js 等。
该漏洞是 2019 年由 Netflix 和 Google 联合披露的 HTTP/2 系列拒绝服务(DoS)漏洞之一。它利用了 HTTP/2 协议的流取消机制,通过持续发送复位帧(RST_STREAM)绕过服务端的并发限制,导致服务端资源耗尽崩溃。
(注:该漏洞是后来 2023 年 CVE-2023-44487 Rapid Reset 的“前辈”,两者的核心思想非常相似,但在帧序列的处理上存在微小差别)。
0x01 漏洞原理分析
HTTP/2 协议引入了多路复用(Multiplexing),允许在单个 TCP 连接上并发处理多个请求(流)。为了防止资源耗尽,服务端会设置 SETTINGS_MAX_CONCURRENT_STREAMS 参数(通常为 100)来限制活动中的流数量。
核心逻辑缺陷:
- 发起请求:攻击者发送一个
HEADERS帧(发起一个新请求)。 - 立即重置:紧接着发送一个
RST_STREAM帧。 - 计数器绕过:根据协议规范,
RST_STREAM会立即使流进入“关闭”状态,从而立刻释放服务端的并发流配额。 - 资源损耗:虽然并发计数器被重置了,但服务端在处理
HEADERS帧(如 HPACK 头部解压、路由逻辑触发、安全检查等)时已经消耗了不可逆的 CPU 和内存。 - 洪水效应:攻击者通过不断循环“请求-重置”,可以在不触发并发流限制的情况下,在单个连接上向服务端灌入海量请求,最终导致 OOM 或 CPU 满载。
0x02 POC (Proof of Concept) 与利用逻辑
攻击者通常使用 Go 或 C++ 编写高性能脚本直接操作 HTTP/2 帧。以下是核心攻击逻辑的 Go 伪代码:
0x03 高级利用姿势
在实战中,攻击者通过演化手法可以规避早期的防御:
- 并发控制绕过 (Concurrency Bypass):
利用“快速重置”特性,使服务端始终认为当前活跃连接数为 0,从而完美绕过所有基于
MAX_CONCURRENT_STREAMS的防御。 - HPACK 压力增强 (HPACK Bombing):
在
HEADERS帧中构造极其复杂的动态表指令。即使流被重置,服务端在解压和维护 HPACK 状态时的内存开销也无法撤回,极大地加速了内存溢出(OOM)的发生。 - 混合协议攻击:
将 Reset Flood 与 Ping Flood (CVE-2019-9512) 或 Settings Flood (CVE-2019-9515) 混合使用。在发送大量的
HEADERS和RST_STREAM的同时插入PING帧,迫使服务端进行复杂的确认计算,形成多维度的资源挤兑。 - WAF 绕过姿势:
- 延迟重置:不立即重置,而是等待服务端开始读取 Body 或触发后端业务(如数据库查询)后再重置,增加后端资源损耗。
- 帧交织:在
HEADERS和RST序列中随机插入无效的DATA或WINDOW_UPDATE帧,干扰 WAF 的流序列检测算法。
0x04 应急排查与日志痕迹分析
1. 资源监控指标
- CPU 异常:Web 服务进程(如 nginx worker)CPU 占用率飙升至 100%,但服务器带宽入口流量(BPS)并不显著,呈现典型的“低带宽、高请求”特征。
2. 流量抓包分析 (PCAP)
- 使用 Wireshark 过滤
http2。 - 特征:观察到大量的
HEADERS帧和RST_STREAM帧以 1:1 的比例交替出现,且两个帧的时间戳间隔极短(微秒级)。
3. 日志排查
- Access Log:普通访问日志可能完全没有记录(因为请求被过早重置,未触发日志生成逻辑),或者出现大量状态码为 499 (Nginx: Client Closed Request) 的记录。
- Error/Debug Log:如果开启了 HTTP/2 级别的调试日志,会看到密集的
stream <ID> was reset或client canceled stream报错信息。
0x05 修复与缓解建议
- 核心补丁更新:
- Nginx:升级至
1.16.1+或1.17.3+。新版本引入了对每连接重置频率的平滑限制机制。 - Apache:升级至
2.4.41+。 - 各开发语言底层的 HTTP/2 库均需升级至最新补丁。
- Nginx:升级至
- 配置加固:
- 限制单连接总请求数:在 Nginx 中设置
http2_max_requests(默认 1000),强制频繁重置的连接在达到上限后断开,增加攻击者重建 TCP 连接的开销。
- 限制单连接总请求数:在 Nginx 中设置
- 基础设施保护: 使用具备 HTTP/2 深度检测能力的 DDoS 清洗服务,拦截异常帧序列。