前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用css绕过同源策略跨域窃取数据

用css绕过同源策略跨域窃取数据

作者头像
安恒网络空间安全讲武堂
发布2018-02-06 11:56:59
1.1K0
发布2018-02-06 11:56:59
举报
文章被收录于专栏:安恒网络空间安全讲武堂

用css绕过同源策略跨域窃取数据

序言

如果你和我一样无聊,你可能遇到过这种潜在的攻击 -》https://www.w3.org/TR/CSP2/#security-css-parsing

如果浏览器使用了一种宽松的css解析方法来渲染,攻击者可能通过插入非同源且非法的脚本来窃取用户的数据

宽松的解析

和遇到语法错误就会停止运行的JavaScript相比,css解析规则会在遇到语法错误的情况下忽略那些不合语法的部分

如何实现

2009年的时候, Chris Evans发现了一种跨域窃取的方法。他的思路是,找一个可以反射get参数的页面,将自己的payload注入在页面里然后把它引入到一个自己可控服务器上的页面里。简单的解释如下图

简单的来说,就是攻击者注入了2处payload,第一处是

代码语言:javascript
复制
{}#f{font-family:'

第二处是

代码语言:javascript
复制
';}

这两者把数据包围起来,划删除线的地方我们可以忽略掉,然后中间的user对象的这些数据就编程了一个font-family属性的值,即单引号内的,所 以这也将成为一个前置条件,那就是要窃取的数据中不能同时出现单双引号。现在,我们可以通过getComputedStyle方法来获取font- family的值了,而这个值将包含user对象中的数据 :)。 我们可以看到,我们注入的数据其实没有很明显的恶意特征(比如脚本标记”<“,”>”),所以通常来说它们并不会被escape。最后我们就 可以通过这样的方式完成跨域窃取敏感信息,数据甚至可能包含csrf所需的token,或者更敏感的个人信息。

攻击的一些前提约束

  • 要窃取的数据必须在payload1和payload2之间。
  • 要窃取的数据不能同时存在单引号和双引号,否则会破坏解析的结构。(数据最后要被解析为css一个属性的值)
  • 要窃取的数据不能包含换行符(css值不支持多行)

这些条件在现代的编码风格下是很难遇到,尤其是不允许出现换行。

如何解决

IE和Firefox禁止了一个不正确的MIME类型(text/css)的跨域加载。另方面,基于webkit的浏览器为了兼容性原因使用strict模式来加载跨域的css文件,这些webkit浏览器采用的方法其实也是csp2官方所建议的。

所有的浏览器应该具有一种更严格的css解析规则来防御错误MIME tyle导致的跨域问题。

模型之外的思考

这个防御 建议看起来是一种完美的平衡:它解决了能够在不破坏已经使用了错误类型的MIME type网站的前提下更好的处理和防御这种跨域攻击的问题。它可以不破坏那些已经使用了错误类型的css的网站,但这也不代表这规则不能被打破。你可以假 设:黑客基本不太可能用合法的css去感染一个文档。我想说的是:我们可以确确实实的去一件事情——让一个页面使用字符集就可以合法的,正常的渲染。

熟悉字符集

css官方文档定义了一个css所需的字符集的优先级

  • BOM
  • content-type头 (比如content-type:text/html)
  • 环境编码(link的字符集属性)

如果一个页面没有明确的BOM或者content-type,那最后就会选择环境的编码值作为最后的编码选择,然而,环境编码是我们可控的。 其 中BOM这个可以不谈,因为很少用到。尽管出于各种原因,我们能看到很多网站并没指定content-type头的字符集,但是content-type 头来设置字符集其实有那么点点暴力,现代的框架都会对其设置默认值。举个例子,facebook就是一个不设置content-type字符集的网站,但 是它用meta charset来指定字符集。

没什么用的css语法

我们来看最有意思的部分:强行合法化css。在这之前我们先得了解基本的语法。

一个css就是个样式表。它必须以“@ ”规则开头 或者是选择器开头。我们就只看下规则集

一个规则本质上就是又“选择器”+“代码块”组成的。选择器有很多种,但是大部分都是有一个标识符的。根据这篇说明,标识符只能包含a-zA-Z0-9和ISO 10646字符集U+00A0,又或者是更高,还有就是“-”和“_”。很明显,css标识符支持大范围的unicode字符集(U+00A0 ~ U+10FFFF),但是引号之类都会被视为非法字符。

如何引入UTF-16?

不像别的字符集,UTF-16通常由2个字节以上组成一个字符,甚至是ascii。

我们来看这个案例:我能告诉浏览器这个页面应该用UTF-16去渲染,然后,突然的整个文档就编程了一个合法标识符!因为整个转变过程中ascii字符 被”吃掉”了,包括换行和引号。当我们添加一个通配符让以后的规则都可以匹配这个元素。搞定了选择器后,解析器继续往下走。

到这一步,我们需要去找一个可以注入我们代码的地方并且创建一个代码块来执行我们的payload。我们需要一个可以写任意字符串的属性,这样才能导入我们要窃取的数据。”font-family”是最佳的选择。

好,我们来看现在我们分析到哪一步了

1

Identifier(junk), * { font-family: Identifier(secret data)

恩,就是这样。哦!等等。。。闭合的“}”在哪?事实上,我们可以忽略掉它,因为这样依然是合法的。根据这篇文档,当一个文件被加载到末尾(EOF)后,代码块将自动的闭合。为了达到目的,我还需要一个注入点来执行。

不能嗅探?

你会怀疑:X-Content-Type-Options 不是用来防止嗅探的么?不幸的是,webkit在引入一个css的时候并不执行这个策略。换句话说就是,即使在头部设置了X-Content-Type-Options: nosniff也不能阻止这种跨域攻击。

限制

总结一下,这种攻击只有在以下情况才能成功。

  • 网站没有设置Content-Type 字符集
  • 注入的反射点没有过滤或者转义null字符

POC

“PoC || GTFO” – whoever

下面的poc将会演示如何从别人的phpinfo文件中截取cookie。phpinfo是常见的信息泄露,它包含http请求中的参数和一些服务端信 息。一般来说它不会受到xss攻击,用这个攻击方式的话,我们可以绕过http only来获取cookie,当然前提就是没设置字符集没过滤null。

PoC (Chrome 43, Safari 8 or iOS 8): http://innerht.ml/csstheft/phpinfo.html

修复

最后webkit 拒绝了设置错误的MIME type的跨域加载

以上请求将提示禁止跨域加载。

虽然现代大部分浏览器修复了这个问题,但是一些个别浏览器依然是存在这个问题的。

更多

https://www.mbsd.jp/Whitepaper/xssi.pdf

https://tools.ietf.org/html/draft-west-first-party-cookies-01#section-1.1

https://www.w3.org/TR/epr/

来源

https://code.google.com/p/chromium/issues/detail?id=419383

http://www.phpied.com/css-railroad-diagrams/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-10-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 恒星EDU 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 序言
  • 模型之外的思考
  • POC
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档