portswigger——HTTP request tunnelling(HTTP 请求隧道)_04
HTTP 请求隧道
到目前为止,我们介绍的许多请求走私攻击之所以成为可能,是因为前端和后端服务器之间的相同连接用于处理多个请求。HTTP 请求隧道提供了一种即使根本没有连接重用也很难构建高严重性漏洞的方法。
我们介绍的许多请求走私攻击之所以成为可能,是因为前端和后端之间的相同连接处理多个请求。尽管某些服务器会对任何请求重用连接,但其他服务器具有更严格的策略。
例如,某些服务器仅允许来自同一 IP 地址或同一客户端的请求重用连接。其他人根本不会重用连接,这限制了您可以通过经典请求走私实现的目标,因为您没有明显的方式来影响其他用户的流量。
虽然你不能毒害套接字来干扰其他用户的请求,但你仍然可以发送一个请求,从后端引发两个响应。这可能使您能够完全隐藏前端的请求及其匹配响应。
您可以使用此技术绕过前端安全措施,否则可能会阻止您发送某些请求。事实上,即使是一些专门用于防止请求走私攻击的机制也无法阻止请求隧道。
以这种方式将请求通过隧道传输到后端提供了一种更有限的请求走私形式,但它仍然可能导致高严重性漏洞利用在正确的人手中。
使用 HTTP/2 请求隧道
HTTP/1 和 HTTP/2 都可以使用请求隧道,但在仅 HTTP/1 环境中检测要困难得多。由于持久 () 连接在 HTTP/1 中的工作方式,即使您确实收到两个响应,这并不一定确认请求已成功走私。keep-alive
另一方面,在HTTP / 2中,每个“流”应该只包含一个请求和响应。如果您收到一个 HTTP/2 响应,正文中似乎有一个 HTTP/1 响应,则可以确信您已成功通过隧道传输第二个请求。
通过 HTTP/2 请求隧道泄漏内部标头
当请求隧道是您的唯一选择时,您将无法使用我们在[早期实验室中]介绍的技术泄漏内部标头,但 HTTP/2 降级启用了替代解决方案。
您可能会诱使前端将内部标头附加到将成为后端的主体参数中。假设我们发送了一个如下所示的请求:
在这种情况下,前端和后端都同意只有一个请求。有趣的是,他们可能会在标题结束的位置上产生分歧。
前端将我们注入的所有内容视为标头的一部分,因此在尾随字符串之后添加任何新标头,即X-Internal-Header: secretContent-Length: 3
。
另一方面,后端看到序列并认为 \r\n\r\n
这是标头的结尾。comment=
字符串以及内部标头被视为正文的一部分。结果是一个以内部标头comment
作为其值的参数。
POST /comment HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 200
comment=X-Internal-Header: secretContent-Length: 3
x=1
盲请求隧道
某些前端服务器会读入它们从后端接收的所有数据。这意味着,如果您成功通过隧道传输请求,它们可能会将两个响应转发到客户端,而对隧道请求的响应嵌套在主响应的正文中。
其他前端服务器仅读取响应标头中指定的字节数,因此仅将第一个响应转发到客户端。这会导致盲请求隧道漏洞,因为您将无法看到对隧道请求的响应。Content-Length
使用 HEAD 的非盲请求隧道
盲请求隧道可能很难利用,但有时可以使用请求使这些漏洞非盲漏洞。HEAD
对HEAD
请求的响应通常包含一个content-length
标头,即使它们没有自己的正文。这通常是指请求返回给同一终结点的资源长度。某些前端服务器无法说明这一点,并尝试读取标头中指定的字节数。如果成功地通过执行此操作的前端服务器通过隧道传输请求,则此行为可能会导致它过度读取来自后端的响应。因此,您收到的响应可能包含从响应开始到GET
隧道请求的字节数。
Request
Response
由于您有效地将一个响应的标头与另一个响应的主体混合在一起,因此成功使用此技术是一种平衡行为。content-length
如果您向其发送请求的终端节点返回的资源短于您尝试读取的隧道响应,则在您看到任何有趣的内容之前,它可能会被截断,如上例所示。另一方面,如果返回的字节长于对隧道请求的响应,则可能会遇到超时,因为前端服务器会等待来自后端的其他字节到达。HEAD
content-length
幸运的是,通过一些试验和错误,您通常可以使用以下解决方案之一来克服这些问题:
- 将
HEAD
请求指向其他终结点,该终结点根据需要返回更长或更短的资源。 - 如果资源太短,请在主请求中使用反射输入来注入任意填充字符。即使你实际上不会看到你的输入被反映,返回的输入仍然会相应地增加。
HEAD``content-length
- 如果资源太长,请使用隧道请求中的反射输入来注入任意字符,以便隧道响应的长度与预期内容的长度匹配或超过预期的长度。
实验室:通过 HTTP/2 请求隧道绕过访问控制
此实验室容易受到请求走私的攻击,因为前端服务器会降级 HTTP/2 请求,并且无法充分清理传入的标头名称。要解决实验室问题,请以用户身份访问管理面板并删除用户。/admin administrator carlos
前端服务器不会重用与后端的连接,因此不易受到经典请求走私攻击。但是,它仍然容易受到请求隧道的攻击。
将请求发送到打嗝中继器。展开检查器的“请求属性”部分,并确保协议设置为 HTTP/2。GET /
使用检查器,将任意标头附加到请求的末尾,并尝试以名称走私标头,如下所示:Host
name
foo: bar\r\n
Host: abc
value
xyz
请注意,错误响应指示服务器处理注入的主机,从而通过标头名称确认实验室容易受到 CRLF 注入的攻击。
在浏览器中,请注意实验室的搜索功能在响应中反映了搜索查询。将最新的请求发送到 Burp Repeater 并将其升级为 HTTP/2 请求。GET /?search=YOUR-SEARCH-QUERY
在“打嗝转发器”中,右键单击请求并选择“更改请求方法”POST
。发送请求,请注意,当您在请求正文中发送参数时,搜索功能仍然有效。search
添加任意标头并使用其名称字段注入大标头和其他参数,如下所示:Content-Length search
名字
foo: bar
Content-Length: 500
search=x
价值
xyz
在请求的主体中(在消息编辑器面板中),将任意字符附加到原始search 参数,直到请求比走私的Content-Length标头长。
发送请求并观察响应现在是否反映了前端服务器追加到请求的标头:
X-SSL-VERIFIED: 0
X-SSL-CLIENT-CN: null
X-FRONTEND-KEY: 4853848450063373
请注意,这些标头似乎是用于[客户端身份验证]的标头。
请求方法更改为并编辑您的恶意标头,以便它窃取对管理面板的请求。包括三个客户端身份验证标头,确保按如下所示更新其值:HEAD
foo: bar\r\n
\r\n
GET /admin HTTP/1.1\r\n
X-SSL-VERIFIED: 1\r\n
X-SSL-CLIENT-CN: administrator\r\n
X-FRONTEND-KEY: YOUR-UNIQUE-KEY\r\n
\r\n
将请求方法更改为并编辑您的恶意标头,以便它窃取对管理面板的请求。包括三个客户端身份验证标头,确保按如下所示更新其值:HEAD
发送请求并观察到您收到错误响应,指出收到的字节不足。这是因为请求的资源比您尝试读取的隧道响应长。Content-Length
“仅收到预期3247字节数据中的3076字节”
更改伪标头,使其指向返回较短资源的终结点。在这种情况下,您可以使用 .:path``/login
在响应中,找到用于删除 () 的 URL,然后相应地更新隧道请求中的路径并重新发送。尽管你可能会遇到错误响应,但已删除并解决实验室问题。carlos``/admin/delete?username=carlos``carlos
foo: bar
GET /admin/delete?username=carlos HTTP/1.1
X-SSL-VERIFIED: 1
X-SSL-CLIENT-CN: administrator
X-FRONTEND-KEY: 3540402970749952
成功删除
通过 HTTP/2 请求隧道的 Web 缓存中毒
尽管请求隧道通常比经典请求走私更受限制,但有时仍可以构建高严重性攻击。例如,您可以结合我们到目前为止研究的请求隧道技术,以获得一种功能更强大的 [Web 缓存中毒]形式。
使用非盲请求隧道,您可以有效地将一个响应的标头与另一个响应的正文混合和匹配。如果正文中的响应反映了未编码的用户输入,则可以在浏览器通常不会执行代码的上下文中将此行为用于[反射的 XSS]。
例如,以下响应包含未编码的、攻击者可控制的输入
HTTP/1.1 200 OK
Content-Type: application/json
{ "name" : "test<script>alert(1)</script>" }
[etc.]
就其本身而言,这是相对无害的。这意味着浏览器将简单地将此有效负载解释为 JSON。但是考虑一下,如果将请求通过隧道传输到后端会发生什么。此响应将出现在不同响应的正文中,有效地继承其content-type
标头,包括 .Content-Type
由于缓存发生在前端,因此缓存也可能被欺骗以将这些混合响应提供给其他用户。
实验室:通过 HTTP/2 请求隧道的 Web 缓存中毒
此实验室容易受到请求走私的影响,因为前端服务器会降级 HTTP/2 请求,并且不会始终审查传入标头。
为了解决实验室问题,请以这样的方式毒害缓存,即当受害者访问主页时,他们的浏览器会执行。受害用户将每 15 秒访问一次主页。
alert(1)
前端服务器不会重用与后端的连接,因此不易受到经典请求走私攻击。但是,它仍然容易受到[请求隧道的攻击]。
向打嗝中继器发送请求。展开检查器的“请求属性”部分,并确保协议设置为 HTTP/2。GET /
使用检查器,尝试在伪标头中走私任意标头,确保为降级请求保留有效的请求行,如下所示::path
name
:path
value
/?cachebuster=1 HTTP/1.1
Foo: bar
观察您仍然收到:path
正常响应,确认您能够通过 .
将请求方法更改为HEAD
并使用伪标头对另一个任意终结点的请求进行隧道传输,如下所示::path
名字
:path
价值
/?cachebuster=2 HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
GET /post?postId=1 HTTP/1.1
Foo: bar
请注意,我们通过在拆分之前包含一个标头来确保主请求有效。我们还留下了一个任意尾随标头来捕获后缀,该后缀将在重写期间由前端附加到请求行中。Host``HTTP/1.1
发送请求并观察您是否能够查看隧道响应。如果不能,请尝试使用其他 .postId
从伪标头中删除除路径和缓存查询参数之外的所有内容,然后重新发送请求。观察您已成功使用隧道响应毒害缓存。:path
现在,您需要找到一个反映基于 HTML的[XSS]有效负载的小工具,而无需对其进行编码或转义。发送的响应,并观察到这会触发重定向到 。GET /resources``/resources/
名字
:path
价值
/?cachebuster=3 HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
GET /resources?<script>alert(1)</script> HTTP/1.1
Foo: bar
观察请求超时。这是因为主响应中的标头比隧道请求的嵌套响应长。Content-Length
从代理历史记录中,检查对正常请求的Content-Lengt
响应并记下其值。返回到 Burp 中继器中的恶意请求,并在结束标记后添加足够的任意字符来填充反射的有效负载,以便隧道响应的长度将超过您刚才注意到的长度8705
。 GET /
发送请求并确认您的有效负载已成功反映在隧道响应中。如果仍然遇到超时,则可能没有添加足够的填充
当缓存仍然中毒时,使用相同的缓存破坏查询参数访问主页并确认触发。alert()
在检查器中,从请求中删除缓存阻止程序,然后重新发送,直到缓存中毒。每隔 5 秒左右重新发送一次请求,以保持缓存中毒,直到受害者访问主页并解决实验室问题。
使主页缓存中毒
HEAD请求
名字
:path
价值
/ HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
GET /resources?<script>alert(1)</script>填充 HTTP/1.1
Foo: bar
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
2019-09-23 mysql报错型注入
2019-09-23 phar反序列化漏洞