HTTP请求走私攻击的变异形式:H2.CL与H2.TE详解
字数 2935 2025-12-06 03:01:44
HTTP请求走私攻击的变异形式:H2.CL与H2.TE详解
描述:HTTP请求走私攻击是一种利用HTTP/1.1中的请求体长度解析差异(在前后端服务器之间)的攻击技术。随着HTTP/2的普及,攻击面扩展到了HTTP/2与后端HTTP/1.1服务器的转换边界。H2.CL和H2.TE是HTTP请求走私在HTTP/2上下文中的两种关键变异形式,它们利用了HTTP/2前端与HTTP/1.1后端在内容长度(Content-Length, CL) 和分块传输编码(Transfer-Encoding, TE) 头部处理上的不一致性,从而走私恶意请求,可能造成缓存投毒、会话劫持、绕过安全控制等危害。
解题过程(原理与步骤详解):
第一步:理解攻击场景与核心矛盾
- 架构背景:现代Web架构中,用户通过HTTP/2协议连接到前端服务器(如反向代理、负载均衡器),前端服务器将请求“转换”或“代理”到后端的HTTP/1.1服务器(如应用服务器)。这个转换过程是关键。
- 核心矛盾:HTTP/2协议不再使用
Content-Length和Transfer-Encoding这类头部来界定消息体边界,而是使用内置的帧(Frames)结构,特别是DATA帧。当前端服务器将HTTP/2请求“降级”转换为HTTP/1.1请求转发给后端时,它必须为HTTP/1.1请求生成合适的Content-Length或Transfer-Encoding头部。攻击就发生在这个“生成”逻辑的缺陷上。
第二步:掌握HTTP/2请求走私的基本原理
攻击者发送一个精心构造的HTTP/2请求。这个请求的头部和载荷,经过前端服务器的转换后,会使得后端HTTP/1.1服务器错误地解析出两个HTTP请求。第一个是攻击者意图中的“包装请求”,第二个是“走私”的、隐藏的恶意请求。这个恶意请求可能会被后端服务器处理,并影响到后续其他用户的请求。
第三步:深入H2.CL攻击
- 利用点:利用前端服务器在转换时,错误地同时信任HTTP/2请求中的
content-length伪头部(:authority, :path, :method等是伪头部,但content-length是实体头部,在HTTP/2中仍可能存在)和HTTP/2数据帧实际长度,或者错误地计算了长度。 - 攻击载荷构造示例:
- 攻击者发送一个HTTP/2请求,其中包含一个
content-length: 50的头部,但其DATA帧的实际载荷长度为大于50的X字节。 - 有缺陷的前端转换逻辑:前端在生成HTTP/1.1请求时,直接使用了头部中的
content-length: 50,而忽略了实际数据长度。 - 后端解析:后端HTTP/1.1服务器收到一个以
Content-Length: 50开头的请求。它读取50字节作为第一个请求的正文,然后认为这个请求结束。而剩下的X-50字节,后端服务器会将其解析为下一个请求的开始(即走私的请求)。
- 攻击者发送一个HTTP/2请求,其中包含一个
- 简单比喻:你告诉快递员(前端)箱子(请求)上写着“重50公斤”(CL头),但实际上你塞了80公斤的货(DATA帧)。快递员没称重就直接贴了50公斤标签转给仓库(后端)。仓库工人搬走前50公斤货认为任务完成,剩下的30公斤货就留在了传送带上,被当成了下一个不知情的客户的货物。
第四步:深入H2.TE攻击
- 利用点:利用前端服务器在转换时,错误地传递或处理了
Transfer-Encoding: chunked头部。HTTP/2规范明确禁止使用TE: chunked,但允许TE: trailers等值。有缺陷的前端可能会错误地将攻击者提供的TE头部转换为HTTP/1.1的Transfer-Encoding: chunked。 - 攻击载荷构造示例:
- 攻击者发送一个HTTP/2请求,其中包含
transfer-encoding: chunked头部,并且请求体是按照HTTP/1.1分块编码格式构造的(例如5\r\nSMUGG\r\n0\r\n\r\n)。 - 有缺陷的前端转换逻辑:前端在生成HTTP/1.1请求时,直接将这个
transfer-encoding头部和原始载荷转发给了后端。 - 后端解析:后端HTTP/1.1服务器看到
Transfer-Encoding: chunked,于是使用分块编码规则解析请求体。它解析完5\r\nSMUGG\r\n0\r\n\r\n后,认为第一个请求结束。但关键在于,攻击者可以在第一个“分块”的结尾(0\r\n\r\n)之后,追加额外的数据。这些额外数据会被后端当作另一个独立的HTTP请求来解析。
- 攻击者发送一个HTTP/2请求,其中包含
- 简单比喻:你给快递员一份说明书(TE头)说“按清单上的块送货”,并给了第一份清单和货物(第一个块)。快递员原封不动把说明书和货物转给仓库。仓库按清单处理完第一块后,以为你的货送完了。但你其实在箱子底部还藏了另一张清单和另一批货(走私数据),仓库工人会继续处理这批“隐藏的货”。
第五步:攻击的完整链条与影响
- 探测:攻击者首先需要探测目标系统是否存在此类解析歧义。通常通过发送具有歧义的CL/TE头部组合,并观察响应的时间差、错误或对后续请求的影响来判断。
- 利用:确认漏洞存在后,构造一个“携带”恶意请求的攻击请求。第一个请求通常是正常的,用于通过前端检查;第二个“走私”的请求可以是指向其他用户路径的请求(造成会话劫持)、注入恶意内容的请求(造成缓存投毒或存储型XSS)或绕过身份验证的请求。
- 影响:
- 缓存投毒:将恶意响应缓存到CDN或代理,影响其他用户。
- 权限绕过:走私一个直接访问内部API或管理功能的请求。
- 反射型XSS/SSRF:走私的请求可以触发后端服务器向其他系统发起请求或返回恶意脚本。
第六步:防御措施
- 前端服务器(代理/负载均衡器):
- 禁用下游HTTP/1.1连接的重用(每个后端连接只处理一个请求),但这会严重影响性能。
- 严格规范化HTTP/2到HTTP/1.1的转换逻辑:绝对不要将客户端请求中的
content-length或transfer-encoding头部直接传递给后端。应该根据HTTP/2数据帧的实际长度,为转换后的HTTP/1.1请求计算并设置一个正确且唯一的Content-Length头,并且绝不使用Transfer-Encoding: chunked。 - 使用同版本协议:尽可能保持前后端都使用HTTP/2。
- 后端服务器:
- 对接收到的HTTP/1.1请求进行严格验证,拒绝任何存在
Content-Length和Transfer-Encoding头部歧义的请求(根据RFC规范,两者共存时Transfer-Encoding优先,但Content-Length应被忽略)。
- 对接收到的HTTP/1.1请求进行严格验证,拒绝任何存在
- 通用建议:
- 保持所有代理服务器、负载均衡器、Web服务器和应用框架的最新版本,及时修补相关漏洞。
- 使用Web应用防火墙(WAF)规则检测异常的请求序列或走私攻击特征。