From 296d5eb1434840107d5a0a5e79abeaa779e63e77 Mon Sep 17 00:00:00 2001 From: Translator Date: Wed, 20 Aug 2025 16:34:06 +0000 Subject: [PATCH] Translated ['src/pentesting-web/http-request-smuggling/README.md', 'src/ --- .../http-request-smuggling/README.md | 230 +++++++++++++----- .../browser-http-request-smuggling.md | 18 +- 2 files changed, 192 insertions(+), 56 deletions(-) diff --git a/src/pentesting-web/http-request-smuggling/README.md b/src/pentesting-web/http-request-smuggling/README.md index cbd951ec0..a7b90e51d 100644 --- a/src/pentesting-web/http-request-smuggling/README.md +++ b/src/pentesting-web/http-request-smuggling/README.md @@ -15,7 +15,7 @@ **Content-Length** -> Content-Length 实体头指示发送给接收者的实体主体的大小(以字节为单位)。 +> Content-Length 实体头指示发送给接收者的实体主体的字节大小。 **Transfer-Encoding: chunked** @@ -24,7 +24,7 @@ ### 现实 -**前端**(负载均衡/反向代理)**处理** _**content-length**_ 或 _**transfer-encoding**_ 头,而**后端**服务器**处理另一个**,导致两个系统之间发生**不同步**。\ +**前端**(负载均衡/反向代理)**处理** _**content-length**_ 或 _**transfer-encoding**_ 头,而**后端**服务器**处理另一个**,导致两个系统之间的**不同步**。\ 这可能非常关键,因为**攻击者将能够向反向代理发送一个请求**,该请求将被**后端**服务器**视为两个不同的请求**。这种技术的**危险**在于**后端**服务器**将解释**注入的**第二个请求**,仿佛它**来自下一个客户端**,而该客户端的**真实请求**将是**注入请求**的一部分。 ### 特点 @@ -33,31 +33,31 @@ - **Content-Length**:此头使用**十进制数字**指示请求**主体**的**字节数**。主体预计在最后一个字符结束,**请求末尾不需要换行**。 - **Transfer-Encoding:** 此头在**主体**中使用**十六进制数字**指示**下一个块**的**字节数**。**块**必须以**换行**结束,但此换行**不计入**长度指示器。此传输方法必须以**大小为0的块后跟2个换行**结束:`0` -- **Connection**:根据我的经验,建议在请求走私的第一个请求中使用**`Connection: keep-alive`**。 +- **Connection**:根据我的经验,建议在请求欺骗的第一个请求中使用**`Connection: keep-alive`**。 ## 基本示例 > [!TIP] > 在尝试使用Burp Suite进行利用时,**禁用 `Update Content-Length` 和 `Normalize HTTP/1 line endings`**,因为某些工具滥用换行符、回车和格式错误的内容长度。 -HTTP请求走私攻击是通过发送模棱两可的请求来构造的,这些请求利用前端和后端服务器在解释`Content-Length`(CL)和`Transfer-Encoding`(TE)头时的差异。这些攻击可以以不同形式表现,主要为**CL.TE**、**TE.CL**和**TE.TE**。每种类型代表前端和后端服务器如何优先处理这些头的独特组合。漏洞源于服务器以不同方式处理相同请求,导致意外和潜在的恶意结果。 +HTTP请求欺骗攻击是通过发送模棱两可的请求来构造的,这些请求利用前端和后端服务器在解释`Content-Length`(CL)和`Transfer-Encoding`(TE)头时的差异。这些攻击可以以不同形式表现,主要为**CL.TE**、**TE.CL**和**TE.TE**。每种类型代表前端和后端服务器如何优先处理这些头的独特组合。漏洞源于服务器以不同方式处理相同请求,导致意外和潜在的恶意结果。 ### 漏洞类型的基本示例 ![https://twitter.com/SpiderSec/status/1200413390339887104?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104&ref_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104](../../images/EKi5edAUUAAIPIK.jpg) -> [!NOTE] -> 在前面的表中,您应该添加TE.0技术,类似于CL.0技术,但使用Transfer Encoding。 +> [!TIP] +> 在之前的表格中,您应该添加TE.0技术,类似于CL.0技术,但使用Transfer Encoding。 #### CL.TE 漏洞(前端使用Content-Length,后端使用Transfer-Encoding) -- **前端 (CL):** 根据`Content-Length`头处理请求。 -- **后端 (TE):** 根据`Transfer-Encoding`头处理请求。 +- **前端 (CL)**:根据`Content-Length`头处理请求。 +- **后端 (TE)**:根据`Transfer-Encoding`头处理请求。 - **攻击场景:** - 攻击者发送一个请求,其中`Content-Length`头的值与实际内容长度不匹配。 - 前端服务器根据`Content-Length`值将整个请求转发给后端。 -- 后端服务器由于`Transfer-Encoding: chunked`头将请求视为分块处理,解释剩余数据为一个单独的后续请求。 +- 后端服务器由于`Transfer-Encoding: chunked`头将请求处理为分块,解释剩余数据为一个单独的后续请求。 - **示例:** ``` @@ -75,13 +75,13 @@ Foo: x #### TE.CL 漏洞(前端使用Transfer-Encoding,后端使用Content-Length) -- **前端 (TE):** 根据`Transfer-Encoding`头处理请求。 -- **后端 (CL):** 根据`Content-Length`头处理请求。 +- **前端 (TE)**:根据`Transfer-Encoding`头处理请求。 +- **后端 (CL)**:根据`Content-Length`头处理请求。 - **攻击场景:** - 攻击者发送一个分块请求,其中块大小(`7b`)和实际内容长度(`Content-Length: 4`)不一致。 -- 前端服务器遵循`Transfer-Encoding`,将整个请求转发给后端。 -- 后端服务器尊重`Content-Length`,仅处理请求的初始部分(`7b`字节),将其余部分视为意外的后续请求的一部分。 +- 前端服务器尊重`Transfer-Encoding`,将整个请求转发给后端。 +- 后端服务器尊重`Content-Length`,仅处理请求的初始部分(`7b`字节),将其余部分视为意外的后续请求。 - **示例:** ``` @@ -102,14 +102,14 @@ x= ``` -#### TE.TE 漏洞(两者都使用Transfer-Encoding,带混淆) +#### TE.TE 漏洞(两者都使用Transfer-Encoding,并进行模糊处理) -- **服务器:** 两者都支持`Transfer-Encoding`,但一个可以通过混淆被欺骗以忽略它。 +- **服务器**:两者都支持`Transfer-Encoding`,但可以通过模糊处理欺骗其中一个忽略它。 - **攻击场景:** -- 攻击者发送一个带有混淆`Transfer-Encoding`头的请求。 -- 根据哪个服务器(前端或后端)未能识别混淆,可能会利用CL.TE或TE.CL漏洞。 -- 请求中未处理的部分,作为其中一个服务器所见,成为后续请求的一部分,导致走私。 +- 攻击者发送一个带有模糊`Transfer-Encoding`头的请求。 +- 根据哪个服务器(前端或后端)未能识别模糊处理,可能会利用CL.TE或TE.CL漏洞。 +- 请求中未处理的部分在其中一个服务器看来成为后续请求的一部分,导致欺骗。 - **示例:** ``` @@ -132,7 +132,7 @@ Transfer-Encoding #### **CL.CL 场景(前端和后端都使用Content-Length)** - 两个服务器仅根据`Content-Length`头处理请求。 -- 这种情况通常不会导致走私,因为两个服务器在解释请求长度时是一致的。 +- 此场景通常不会导致欺骗,因为两个服务器在解释请求长度时是一致的。 - **示例:** ``` @@ -147,7 +147,7 @@ Normal Request #### **CL.0 场景** - 指的是`Content-Length`头存在且值不为零,表示请求主体有内容。后端忽略`Content-Length`头(被视为0),但前端解析它。 -- 这在理解和构造走私攻击中至关重要,因为它影响服务器确定请求结束的方式。 +- 这在理解和构造欺骗攻击中至关重要,因为它影响服务器确定请求结束的方式。 - **示例:** ``` @@ -162,7 +162,7 @@ Non-Empty Body #### TE.0 场景 - 类似于前一个场景,但使用TE。 -- 技术[在此报告](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/) +- 技术[在此报告](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)。 - **示例**: ``` OPTIONS / HTTP/1.1 @@ -183,9 +183,9 @@ EMPTY_LINE_HERE ``` #### 破坏网络服务器 -此技术在某些场景中也很有用,在这些场景中,可以**在读取初始HTTP数据时破坏网络服务器**,但**不关闭连接**。这样,HTTP请求的**主体**将被视为**下一个HTTP请求**。 +此技术在可以**在读取初始HTTP数据时破坏网络服务器**但**不关闭连接**的场景中也很有用。这样,HTTP请求的**主体**将被视为**下一个HTTP请求**。 -例如,如[**这篇文章**](https://mizu.re/post/twisty-python)中所述,在Werkzeug中,可以发送一些**Unicode**字符,这会导致服务器**崩溃**。然而,如果HTTP连接是使用**`Connection: keep-alive`**头创建的,请求的主体将不会被读取,连接仍将保持打开状态,因此请求的**主体**将被视为**下一个HTTP请求**。 +例如,如[**这篇文章**](https://mizu.re/post/twisty-python)中所述,在Werkzeug中可以发送一些**Unicode**字符,这会导致服务器**崩溃**。然而,如果HTTP连接是使用**`Connection: keep-alive`**头创建的,请求的主体将不会被读取,连接仍将保持打开状态,因此请求的**主体**将被视为**下一个HTTP请求**。 #### 通过逐跳头强制 @@ -201,7 +201,7 @@ Connection: Content-Length ## 查找 HTTP 请求走私 -识别 HTTP 请求走私漏洞通常可以通过时间技术实现,这依赖于观察服务器响应被操纵请求所需的时间。这些技术对于检测 CL.TE 和 TE.CL 漏洞特别有用。除了这些方法,还有其他策略和工具可以用来查找此类漏洞: +识别 HTTP 请求走私漏洞通常可以通过时间技术实现,这依赖于观察服务器对被操控请求的响应时间。这些技术特别适用于检测 CL.TE 和 TE.CL 漏洞。除了这些方法,还有其他策略和工具可以用来发现此类漏洞: ### 使用时间技术查找 CL.TE 漏洞 @@ -261,11 +261,11 @@ X - **Content-Length 变异测试:** - 发送具有不同 `Content-Length` 值的请求,这些值与实际内容长度不一致,并观察服务器如何处理此类不匹配。 - **Transfer-Encoding 变异测试:** -- 发送具有模糊或格式错误的 `Transfer-Encoding` 头的请求,并监控前端和后端服务器对这种操控的不同响应。 +- 发送带有模糊或格式错误的 `Transfer-Encoding` 头的请求,并监控前端和后端服务器对这种操控的不同响应。 ### HTTP 请求走私漏洞测试 -在确认时间技术有效性后,验证客户端请求是否可以被操控至关重要。一种简单的方法是尝试毒化您的请求,例如,使对 `/` 的请求返回 404 响应。之前在 [Basic Examples](#basic-examples) 中讨论的 `CL.TE` 和 `TE.CL` 示例演示了如何毒化客户端请求以引发 404 响应,尽管客户端旨在访问不同的资源。 +在确认时间技术的有效性后,验证客户端请求是否可以被操控至关重要。一个简单的方法是尝试毒化你的请求,例如,使对 `/` 的请求返回 404 响应。之前在 [基本示例](#basic-examples) 中讨论的 `CL.TE` 和 `TE.CL` 示例演示了如何毒化客户端请求以引发 404 响应,尽管客户端旨在访问不同的资源。 **关键考虑事项** @@ -275,9 +275,123 @@ X - **一致的 URL 和参数:** 力求对两个请求使用相同的 URL 和参数名称。现代应用程序通常根据 URL 和参数将请求路由到特定的后端服务器。匹配这些可以增加两个请求由同一服务器处理的可能性,这是成功攻击的前提。 - **时间和竞争条件:** “正常”请求旨在检测“攻击”请求的干扰,与其他并发应用请求竞争。因此,在“攻击”请求后立即发送“正常”请求。繁忙的应用程序可能需要多次尝试以确认漏洞。 - **负载均衡挑战:** 作为负载均衡器的前端服务器可能会将请求分配到不同的后端系统。如果“攻击”和“正常”请求最终落在不同的系统上,攻击将不会成功。这个负载均衡方面可能需要多次尝试以确认漏洞。 -- **意外用户影响:** 如果您的攻击无意中影响了另一个用户的请求(不是您发送的“正常”请求),这表明您的攻击影响了另一个应用用户。持续测试可能会干扰其他用户,因此需要谨慎处理。 +- **意外用户影响:** 如果你的攻击无意中影响了另一个用户的请求(不是你发送的“正常”请求),这表明你的攻击影响了另一个应用用户。持续测试可能会干扰其他用户,因此需要谨慎处理。 + +## 区分 HTTP/1.1 管道化伪影与真正的请求走私 + +连接重用(keep-alive)和管道化可以轻易在发送多个请求的测试工具中产生“走私”的错觉。学会将无害的客户端伪影与真实的服务器端不同步分开。 + +### 为什么管道化会产生经典的假阳性 + +HTTP/1.1 重用单个 TCP/TLS 连接,并在同一流上连接请求和响应。在管道化中,客户端连续发送多个请求,并依赖于按顺序的响应。一个常见的假阳性是将格式错误的 CL.0 风格有效负载在单个连接上发送两次: +``` +POST / HTTP/1.1 +Host: hackxor.net +Content_Length: 47 + +GET /robots.txt HTTP/1.1 +X: Y +``` +响应可能看起来像: +``` +HTTP/1.1 200 OK +Content-Type: text/html + +``` + +``` +HTTP/1.1 200 OK +Content-Type: text/plain + +User-agent: * +Disallow: /settings +``` +如果服务器忽略了格式错误的 `Content_Length`,则没有 FE↔BE 的不同步。在重用中,您的客户端实际上发送了这个字节流,服务器将其解析为两个独立的请求: +``` +POST / HTTP/1.1 +Host: hackxor.net +Content_Length: 47 + +GET /robots.txt HTTP/1.1 +X: YPOST / HTTP/1.1 +Host: hackxor.net +Content_Length: 47 + +GET /robots.txt HTTP/1.1 +X: Y +``` +影响:无。您只是使客户端与服务器框架不同步。 + +> [!TIP] +> 依赖于重用/流水线的 Burp 模块:Turbo Intruder 使用 `requestsPerConnection>1`,Intruder 使用 "HTTP/1 连接重用",Repeater "按顺序发送组(单个连接)" 或 "启用连接重用"。 + +### Litmus 测试:流水线还是实际不同步? + +1. 禁用重用并重新测试 +- 在 Burp Intruder/Repeater 中,关闭 HTTP/1 重用并避免 "按顺序发送组"。 +- 在 Turbo Intruder 中,设置 `requestsPerConnection=1` 和 `pipeline=False`。 +- 如果行为消失,可能是客户端流水线,除非您正在处理连接锁定/有状态目标或客户端不同步。 +2. HTTP/2 嵌套响应检查 +- 发送一个 HTTP/2 请求。如果响应体包含完整的嵌套 HTTP/1 响应,您已证明后端解析/不同步错误,而不是纯客户端伪影。 +3. 针对连接锁定前端的部分请求探测 +- 一些前端仅在客户端重用其连接时才重用上游后端连接。使用部分请求检测与客户端重用相似的前端行为。 +- 请参见 PortSwigger "Browser‑Powered Desync Attacks" 以获取连接锁定技术。 +4. 状态探测 +- 查找同一 TCP 连接上的首次请求与后续请求的差异(首次请求路由/验证)。 +- Burp "HTTP Request Smuggler" 包含一个连接状态探测器,可以自动化此操作。 +5. 可视化网络 +- 使用 Burp "HTTP Hacker" 扩展直接检查连接和消息框架,同时实验重用和部分请求。 + +### 连接锁定请求走私(需要重用) + +一些前端仅在客户端重用其连接时才重用上游连接。真实的走私存在,但取决于客户端重用。要区分并证明影响: +- 证明服务器端错误 +- 使用 HTTP/2 嵌套响应检查,或 +- 使用部分请求显示前端仅在客户端重用时重用上游。 +- 即使直接跨用户套接字滥用被阻止,也要显示真实影响: +- 缓存中毒:通过不同步毒化共享缓存,使响应影响其他用户。 +- 内部头部泄露:反射前端注入的头部(例如,auth/trust 头部)并转向认证绕过。 +- 绕过前端控制:走私受限路径/方法通过前端。 +- 主机头滥用:结合主机路由怪癖转向内部虚拟主机。 +- 操作员工作流 +- 使用受控重用重现(Turbo Intruder `requestsPerConnection=2`,或 Burp Repeater 标签组 → "按顺序发送组(单个连接)")。 +- 然后链到缓存/头部泄露/控制绕过原语并演示跨用户或授权影响。 + +> 另请参见连接状态攻击,这些攻击密切相关但不属于技术走私: +> +>{{#ref}} +>../http-connection-request-smuggling.md +>{{#endref}} + +### 客户端不同步约束 + +如果您针对浏览器驱动/客户端不同步,则恶意请求必须可以通过浏览器跨源发送。头部混淆技巧无效。专注于可通过导航/获取到达的原语,然后转向缓存中毒、头部泄露或前端控制绕过,其中下游组件反射或缓存响应。 + +有关背景和端到端工作流: + +{{#ref}} +-browser-http-request-smuggling.md +{{#endref}} + +### 帮助决策的工具 + +- HTTP Hacker(Burp BApp Store):暴露低级 HTTP 行为和套接字连接。 +- "走私还是流水线?" Burp Repeater 自定义操作:https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda +- Turbo Intruder:通过 `requestsPerConnection` 精确控制连接重用。 +- Burp HTTP Request Smuggler:包括一个连接状态探测器,以发现首次请求路由/验证。 + +> [!NOTE] +> 除非您能证明服务器端不同步并附加具体影响(中毒缓存伪影、泄露内部头部以启用特权绕过、绕过前端控制等),否则将仅重用效果视为非问题。 ## 滥用 HTTP 请求走私 + +### 通过 HTTP 请求走私规避前端安全 + +有时,前端代理会实施安全措施,审查传入请求。然而,通过利用 HTTP 请求走私,这些措施可以被规避,从而允许未经授权访问受限端点。例如,访问 `/admin` 可能在外部被禁止,前端代理积极阻止此类尝试。然而,该代理可能未能检查走私 HTTP 请求中的嵌入请求,从而留下绕过这些限制的漏洞。 + +考虑以下示例,说明如何使用 HTTP 请求走私绕过前端安全控制,特别针对通常由前端代理保护的 `/admin` 路径: + +**CL.TE 示例** ``` POST / HTTP/1.1 Host: [redacted].web-security-academy.net @@ -312,11 +426,11 @@ a=x 0 ``` -相反,在TE.CL攻击中,初始的`POST`请求使用`Transfer-Encoding: chunked`,而后续的嵌入请求则基于`Content-Length`头进行处理。与CL.TE攻击类似,前端代理忽视了被隐藏的`GET /admin`请求,意外地授予了对受限`/admin`路径的访问。 +相反,在TE.CL攻击中,初始的`POST`请求使用`Transfer-Encoding: chunked`,而后续嵌入的请求则基于`Content-Length`头进行处理。与CL.TE攻击类似,前端代理忽视了被隐藏的`GET /admin`请求,意外地授予了对受限`/admin`路径的访问。 ### 揭示前端请求重写 -应用程序通常使用**前端服务器**来修改传入请求,然后将其传递给后端服务器。典型的修改涉及添加头部,例如`X-Forwarded-For: `,以将客户端的IP转发给后端。理解这些修改可能至关重要,因为它可能揭示**绕过保护**或**发现隐藏的信息或端点**的方法。 +应用程序通常使用**前端服务器**来修改传入请求,然后将其传递给后端服务器。典型的修改涉及添加头信息,例如`X-Forwarded-For: `,以将客户端的IP转发给后端。理解这些修改可能至关重要,因为它可能揭示**绕过保护**或**发现隐藏的信息或端点**的方法。 要调查代理如何更改请求,找到一个后端在响应中回显的POST参数。然后,构造一个请求,使用这个参数作为最后一个,类似于以下内容: ``` @@ -337,7 +451,7 @@ search= ``` 在这个结构中,后续请求组件被附加在 `search=` 之后,这是在响应中反映的参数。这个反射将暴露后续请求的头部。 -重要的是要将嵌套请求的 `Content-Length` 头与实际内容长度对齐。建议从一个小值开始并逐渐增加,因为过低的值会截断反射的数据,而过高的值可能会导致请求出错。 +重要的是要使嵌套请求的 `Content-Length` 头与实际内容长度对齐。建议从一个小值开始并逐渐增加,因为过低的值会截断反射的数据,而过高的值可能会导致请求出错。 这种技术在 TE.CL 漏洞的上下文中也适用,但请求应以 `search=\r\n0` 结束。无论换行符如何,值将附加到搜索参数中。 @@ -345,9 +459,9 @@ search= ### 捕获其他用户的请求 -通过在 POST 操作期间将特定请求附加为参数的值,可以捕获下一个用户的请求。以下是如何实现这一点的: +通过在 POST 操作期间将特定请求附加为参数的值,可以捕获下一个用户的请求。以下是如何实现这一点的: -通过将以下请求附加为参数的值,您可以存储后续客户端的请求: +通过将以下请求附加为参数的值,可以存储后续客户端的请求: ``` POST / HTTP/1.1 Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net @@ -367,20 +481,20 @@ Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=asdfghjklo&email=email%40email.com&comment= ``` -在这种情况下,**comment 参数**旨在存储公开可访问页面上帖子评论部分的内容。因此,后续请求的内容将作为评论出现。 +在这种情况下,**comment 参数**旨在存储在公开可访问页面的帖子评论部分中的内容。因此,后续请求的内容将作为评论出现。 然而,这种技术有其局限性。通常,它仅捕获 smuggled 请求中使用的参数分隔符之前的数据。对于 URL 编码的表单提交,这个分隔符是 `&` 字符。这意味着从受害者用户请求中捕获的内容将在第一个 `&` 处停止,这可能甚至是查询字符串的一部分。 -此外,值得注意的是,这种方法在 TE.CL 漏洞中也是可行的。在这种情况下,请求应以 `search=\r\n0` 结束。无论换行符如何,值将附加到搜索参数。 +此外,值得注意的是,这种方法在 TE.CL 漏洞中也是可行的。在这种情况下,请求应以 `search=\r\n0` 结束。无论换行符如何,值将附加到搜索参数中。 ### 使用 HTTP 请求走私来利用反射型 XSS HTTP 请求走私可以被用来利用易受 **反射型 XSS** 攻击的网页,提供显著的优势: - **不需要**与目标用户互动。 -- 允许在 **通常无法达到** 的请求部分利用 XSS,例如 HTTP 请求头。 +- 允许在 **通常无法获取** 的请求部分中利用 XSS,例如 HTTP 请求头。 -在网站通过 User-Agent 头部易受反射型 XSS 攻击的情况下,以下有效载荷演示了如何利用此漏洞: +在网站通过 User-Agent 头易受反射型 XSS 攻击的情况下,以下有效载荷演示了如何利用此漏洞: ``` POST / HTTP/1.1 Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net @@ -401,11 +515,11 @@ Content-Type: application/x-www-form-urlencoded A= ``` -这个有效载荷的结构旨在利用漏洞,通过以下方式: +此有效载荷的结构旨在利用该漏洞,具体步骤如下: -1. 发起一个看似典型的 `POST` 请求,带有 `Transfer-Encoding: chunked` 头部以指示开始走私。 +1. 发起一个看似典型的 `POST` 请求,带有 `Transfer-Encoding: chunked` 头以指示走私的开始。 2. 随后跟随一个 `0`,标记块消息体的结束。 -3. 然后,引入一个走私的 `GET` 请求,其中 `User-Agent` 头部注入了一个脚本,``,当服务器处理这个后续请求时触发 XSS。 +3. 然后,引入一个走私的 `GET` 请求,其中 `User-Agent` 头被注入一个脚本 ``,当服务器处理此后续请求时触发 XSS。 通过走私操控 `User-Agent`,该有效载荷绕过了正常请求约束,从而以非标准但有效的方式利用了反射型 XSS 漏洞。 @@ -414,13 +528,13 @@ A= > [!CAUTION] > 如果用户内容在响应中以 **`Content-type`** 反射,例如 **`text/plain`**,将阻止 XSS 的执行。如果服务器支持 **HTTP/0.9,可能可以绕过这一点**! -版本 HTTP/0.9 是在 1.0 之前,仅使用 **GET** 动词,并且 **不** 响应 **头部**,只有主体。 +HTTP/0.9 版本早于 1.0,仅使用 **GET** 动词,并且 **不** 响应 **头部**,只有主体。 -在 [**这篇文章**](https://mizu.re/post/twisty-python) 中,这被滥用通过请求走私和一个 **会回复用户输入的易受攻击端点** 来走私一个 HTTP/0.9 请求。响应中反射的参数包含一个 **伪造的 HTTP/1.1 响应(带有头部和主体)**,因此响应将包含有效的可执行 JS 代码,`Content-Type` 为 `text/html`。 +在 [**这篇文章**](https://mizu.re/post/twisty-python) 中,利用了请求走私和一个 **会回复用户输入的易受攻击端点** 来走私一个 HTTP/0.9 请求。响应中反射的参数包含一个 **伪造的 HTTP/1.1 响应(带有头部和主体)**,因此响应将包含有效的可执行 JS 代码,`Content-Type` 为 `text/html`。 ### 利用 HTTP 请求走私进行站内重定向 -应用程序通常通过使用重定向 URL 中的 `Host` 头部的主机名从一个 URL 重定向到另一个 URL。这在像 Apache 和 IIS 这样的 web 服务器中很常见。例如,请求一个没有尾部斜杠的文件夹会导致重定向以包含斜杠: +应用程序通常通过使用重定向 URL 中的 `Host` 头的主机名从一个 URL 重定向到另一个 URL。这在像 Apache 和 IIS 这样的 Web 服务器中很常见。例如,请求一个没有尾部斜杠的文件夹会导致重定向以包含斜杠: ``` GET /home HTTP/1.1 Host: normal-website.com @@ -430,7 +544,7 @@ Host: normal-website.com HTTP/1.1 301 Moved Permanently Location: https://normal-website.com/home/ ``` -尽管看似无害,但这种行为可以通过 HTTP request smuggling 被操控,以将用户重定向到外部网站。例如: +尽管看似无害,但这种行为可以通过HTTP请求走私进行操控,以将用户重定向到外部网站。例如: ``` POST / HTTP/1.1 Host: vulnerable-website.com @@ -456,17 +570,17 @@ Host: vulnerable-website.com HTTP/1.1 301 Moved Permanently Location: https://attacker-website.com/home/ ``` -在这个场景中,用户对 JavaScript 文件的请求被劫持。攻击者可以通过响应恶意 JavaScript 来潜在地危害用户。 +在这种情况下,用户对 JavaScript 文件的请求被劫持。攻击者可以通过响应恶意 JavaScript 来潜在地危害用户。 ### 通过 HTTP 请求走私利用 Web 缓存中毒 如果 **前端基础设施的任何组件缓存内容**,通常是为了提高性能,则可以执行 Web 缓存中毒。通过操纵服务器的响应,可以 **毒化缓存**。 -之前,我们观察到如何改变服务器响应以返回 404 错误(参见 [Basic Examples](#basic-examples))。同样,可以欺骗服务器以响应对 `/static/include.js` 的请求而提供 `/index.html` 内容。因此,`/static/include.js` 的内容在缓存中被替换为 `/index.html` 的内容,使得 `/static/include.js` 对用户不可访问,可能导致服务拒绝(DoS)。 +之前,我们观察到如何改变服务器响应以返回 404 错误(参见 [Basic Examples](#basic-examples))。同样,可以欺骗服务器以响应对 `/static/include.js` 的请求而提供 `/index.html` 内容。因此,缓存中的 `/static/include.js` 内容被替换为 `/index.html` 的内容,使得用户无法访问 `/static/include.js`,这可能导致服务拒绝(DoS)。 如果发现 **开放重定向漏洞** 或者存在 **指向开放重定向的站内重定向**,这种技术变得特别强大。这些漏洞可以被利用来将 `/static/include.js` 的缓存内容替换为攻击者控制的脚本,从而实质上使所有请求更新的 `/static/include.js` 的客户端面临广泛的跨站脚本(XSS)攻击。 -下面是利用 **缓存中毒结合站内重定向到开放重定向** 的示例。目标是改变 `/static/include.js` 的缓存内容,以提供由攻击者控制的 JavaScript 代码: +下面是利用 **缓存中毒结合站内重定向到开放重定向** 的示例。目标是更改 `/static/include.js` 的缓存内容,以提供由攻击者控制的 JavaScript 代码: ``` POST / HTTP/1.1 Host: vulnerable.net @@ -484,7 +598,7 @@ Content-Length: 10 x=1 ``` -注意嵌入的请求针对 `/post/next?postId=3`。该请求将被重定向到 `/post?postId=4`,利用 **Host header value** 来确定域名。通过更改 **Host header**,攻击者可以将请求重定向到他们的域名 (**on-site redirect to open redirect**)。 +注意嵌入的请求目标是 `/post/next?postId=3`。该请求将被重定向到 `/post?postId=4`,利用 **Host header value** 来确定域名。通过更改 **Host header**,攻击者可以将请求重定向到他们的域名 (**on-site redirect to open redirect**)。 在成功的 **socket poisoning** 之后,应发起对 `/static/include.js` 的 **GET request**。该请求将受到先前 **on-site redirect to open redirect** 请求的污染,并获取由攻击者控制的脚本内容。 @@ -497,7 +611,7 @@ x=1 > - 在 **web cache poisoning** 中,攻击者使应用程序在缓存中存储一些恶意内容,并且这些内容从缓存中提供给其他应用程序用户。 > - 在 **web cache deception** 中,攻击者使应用程序在缓存中存储属于另一个用户的一些敏感内容,然后攻击者从缓存中检索这些内容。 -攻击者构造一个偷渡请求,以获取敏感的用户特定内容。考虑以下示例: +攻击者构造一个走私请求,以获取敏感的用户特定内容。考虑以下示例: ```markdown `POST / HTTP/1.1`\ `Host: vulnerable-website.com`\ @@ -508,7 +622,7 @@ x=1 `GET /private/messages HTTP/1.1`\ `Foo: X` ``` -如果这个走私请求污染了用于静态内容的缓存条目(例如,`/someimage.png`),那么受害者在`/private/messages`中的敏感数据可能会被缓存到静态内容的缓存条目下。因此,攻击者可能会检索到这些缓存的敏感数据。 +如果这个被走私的请求污染了用于静态内容的缓存条目(例如,`/someimage.png`),那么受害者在`/private/messages`中的敏感数据可能会被缓存到静态内容的缓存条目下。因此,攻击者可能会检索到这些缓存的敏感数据。 ### 通过 HTTP 请求走私滥用 TRACE @@ -518,7 +632,7 @@ TRACE / HTTP/1.1 Host: example.com XSS: ``` -请发送您的内容,我将为您翻译。 +请发送您的请求。 ``` HTTP/1.1 200 OK Content-Type: message/http @@ -529,13 +643,13 @@ Host: vulnerable.com XSS: X-Forwarded-For: xxx.xxx.xxx.xxx ``` -一个滥用这种行为的例子是**首先伪装一个HEAD请求**。该请求将仅以GET请求的**头部**进行响应(其中包括**`Content-Type`**)。然后立即伪装**一个TRACE请求**,该请求将**反射发送的数据**。\ -由于HEAD响应将包含一个`Content-Length`头,**TRACE请求的响应将被视为HEAD响应的主体,因此在响应中反射任意数据**。\ -该响应将被发送到连接上的下一个请求,因此这可以**用于缓存的JS文件,例如注入任意JS代码**。 +一个滥用这种行为的例子是**首先伪装一个HEAD请求**。该请求将仅以GET请求的**头部**进行响应(**`Content-Type`**在其中)。然后立即伪装**一个TRACE请求**,该请求将**反射发送的数据**。\ +由于HEAD响应将包含一个`Content-Length`头部,**TRACE请求的响应将被视为HEAD响应的主体,因此在响应中反射任意数据**。\ +该响应将被发送到连接上的下一个请求,因此这可以**用于缓存的JS文件中,例如注入任意JS代码**。 ### 通过HTTP响应拆分滥用TRACE -继续关注[**这篇文章**](https://portswigger.net/research/trace-desync-attack)建议另一种滥用TRACE方法的方式。如评论所述,伪装一个HEAD请求和一个TRACE请求可以**控制HEAD请求响应中的一些反射数据**。HEAD请求主体的长度基本上在Content-Length头中指示,并由TRACE请求的响应形成。 +继续关注[**这篇文章**](https://portswigger.net/research/trace-desync-attack)建议另一种滥用TRACE方法的方式。如评论所述,伪装一个HEAD请求和一个TRACE请求可以**控制HEAD请求响应中的一些反射数据**。HEAD请求主体的长度基本上在Content-Length头部中指示,并由TRACE请求的响应形成。 因此,新的想法是,知道这个Content-Length和TRACE响应中给出的数据,可以使TRACE响应在Content-Length的最后一个字节之后包含一个有效的HTTP响应,从而允许攻击者完全控制下一个响应的请求(这可以用于执行缓存中毒)。 @@ -690,12 +804,14 @@ table.add(req) ``` ## 工具 +- HTTP Hacker (Burp BApp Store) – 可视化连接/框架和低级 HTTP 行为 +- https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda Burp Repeater 自定义操作 "Smuggling or pipelining?" - [https://github.com/anshumanpattnaik/http-request-smuggling](https://github.com/anshumanpattnaik/http-request-smuggling) - [https://github.com/PortSwigger/http-request-smuggler](https://github.com/PortSwigger/http-request-smuggler) - [https://github.com/gwen001/pentest-tools/blob/master/smuggler.py](https://github.com/gwen001/pentest-tools/blob/master/smuggler.py) - [https://github.com/defparam/smuggler](https://github.com/defparam/smuggler) - [https://github.com/Moopinger/smugglefuzz](https://github.com/Moopinger/smugglefuzz) -- [https://github.com/bahruzjabiyev/t-reqs-http-fuzzer](https://github.com/bahruzjabiyev/t-reqs-http-fuzzer): 该工具是一个基于语法的HTTP Fuzzer,有助于发现奇怪的请求走私差异。 +- [https://github.com/bahruzjabiyev/t-reqs-http-fuzzer](https://github.com/bahruzjabiyev/t-reqs-http-fuzzer): 该工具是基于语法的 HTTP Fuzzer,有助于发现奇怪的请求走私差异。 ## 参考 @@ -708,6 +824,10 @@ table.add(req) - [https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/](https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/) - [https://portswigger.net/research/trace-desync-attack](https://portswigger.net/research/trace-desync-attack) - [https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/) +- 注意虚假阳性:如何区分 HTTP 管道和请求走私 – [https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling](https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling) +- [https://http1mustdie.com/](https://http1mustdie.com/) +- 浏览器驱动的去同步攻击 – [https://portswigger.net/research/browser-powered-desync-attacks](https://portswigger.net/research/browser-powered-desync-attacks) +- PortSwigger Academy – 客户端去同步 – [https://portswigger.net/web-security/request-smuggling/browser/client-side-desync](https://portswigger.net/web-security/request-smuggling/browser/client-side-desync) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/pentesting-web/http-request-smuggling/browser-http-request-smuggling.md b/src/pentesting-web/http-request-smuggling/browser-http-request-smuggling.md index c76e21b9e..dddcdbce7 100644 --- a/src/pentesting-web/http-request-smuggling/browser-http-request-smuggling.md +++ b/src/pentesting-web/http-request-smuggling/browser-http-request-smuggling.md @@ -2,6 +2,22 @@ {{#include ../../banners/hacktricks-training.md}} -**查看帖子 [https://portswigger.net/research/browser-powered-desync-attacks](https://portswigger.net/research/browser-powered-desync-attacks)** +浏览器驱动的不同步(即客户端请求走私)利用受害者的浏览器在共享连接上排队一个格式错误的请求,以便后续请求被下游组件解析为不同步。与经典的前端↔后端走私不同,有效负载受到浏览器合法发送跨域请求的限制。 + +关键约束和提示 +- 仅使用浏览器可以通过导航、fetch 或表单提交发出的头部和语法。头部混淆(LWS 技巧、重复 TE、无效 CL)通常不会发送。 +- 目标端点和中介,反映输入或缓存响应。有效影响包括缓存中毒、泄露前端注入的头部,或绕过前端路径/方法控制。 +- 重用很重要:调整构造的请求,使其与高价值受害者请求共享相同的 HTTP/1.1 或 H2 连接。连接锁定/有状态行为会放大影响。 +- 优先选择不需要自定义头部的原语:路径混淆、查询字符串注入,以及通过表单编码的 POST 进行主体塑形。 +- 通过重新测试而不重用,或使用 HTTP/2 嵌套响应检查,验证真正的服务器端不同步与单纯的管道化伪影。 + +有关端到端技术和 PoC,请参见: +- PortSwigger Research – 浏览器驱动的不同步攻击: https://portswigger.net/research/browser-powered-desync-attacks +- PortSwigger Academy – 客户端不同步: https://portswigger.net/web-security/request-smuggling/browser/client-side-desync + +## 参考 +- [https://portswigger.net/research/browser-powered-desync-attacks](https://portswigger.net/research/browser-powered-desync-attacks) +- [https://portswigger.net/web-security/request-smuggling/browser/client-side-desync](https://portswigger.net/web-security/request-smuggling/browser/client-side-desync) +- 区分管道化与走私(关于重用误报的背景):https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling {{#include ../../banners/hacktricks-training.md}}