用css绕过同源策略跨域窃取数据
用css绕过同源策略跨域窃取数据
序言
如果你和我一样无聊,你可能遇到过这种潜在的攻击 -》https://www.w3.org/TR/CSP2/#security-css-parsing
如果浏览器使用了一种宽松的css解析方法来渲染,攻击者可能通过插入非同源且非法的脚本来窃取用户的数据
宽松的解析
和遇到语法错误就会停止运行的JavaScript相比,css解析规则会在遇到语法错误的情况下忽略那些不合语法的部分
如何实现
2009年的时候, Chris Evans发现了一种跨域窃取的方法。他的思路是,找一个可以反射get参数的页面,将自己的payload注入在页面里然后把它引入到一个自己可控服务器上的页面里。简单的解释如下图
简单的来说,就是攻击者注入了2处payload,第一处是
{}#f{font-family:'
第二处是
';}
这两者把数据包围起来,划删除线的地方我们可以忽略掉,然后中间的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/
- Python基础03 序列
- Python基础02 基本数据类型
- 用命令重启IIS 常重启IIS的朋友看过来
- Python基础01 Hello World!
- 剑指OFFER之从上往下打印二叉树(九度OJ1523)
- 给你的博客加上“Fork me on Github”彩带
- Android Studio添加PNG图片报错原因
- 剑指OFFER之包含min函数的栈(九度OJ1522)
- 使用VS2010开发Qt程序的一点经验
- 用Qt写软件系列五:一个安全防护软件的制作(3)
- 剑指OFFER之顺时针打印矩阵(九度OJ1391)
- 用Qt写软件系列五:一个安全防护软件的制作(2)
- 2018年值得关注的200场机器学习会议
- Linux开机启动(bootstrap)
- HTML 教程
- HTML 简介
- html div 标签介绍
- html span 标签介绍
- html a 超链接标签
- HTML Br换行标签介绍
- HTML P段落标签介绍
- HTML br与p标签区别
- Html H 标题标签
- html px em pt长度单位
- HTML form 标签
- HTML radio 单选框
- HTML B 加粗标签
- HTML strong加粗粗体标签
- HTML em 强调标签
- HTML i 斜体标签
- HTML u下划线标签
- HTML s 删除线标签
- Html img 图片标签
- Html上标注sup与下标注sub标签
- HTML nobr 禁止换行标签
- HTML hr 水平线标签
- HTML label 标签
- HTML input 标签
- HTML textarea 标签
- HTML select下拉列表标签
- HTML checkbox 多选框
- HTML font color 标签
- HTML iframe 框架标签
- HTML Table 表格
- HTML dl dt dd 标签
- HTML ol li有序列表标签
- HTML ul li 无序列表标签
- HTML 注释
- CSS 教程
- CSS 简介
- CSS 语法
- CSS Id 和 Class选择器
- CSS 样式的创建
- CSS background 背景介绍
- CSS 文本样式
- CSS font 字体
- CSS A 链接
- CSS ul ol列表样式
- CSS TABLE 样式
- CSS 框模型
- CSS border 边框
- CSS Outlines 轮廓
- CSS 外边距 Margin
- CSS Padding 内边距
- CSS 分组和嵌套选择器
- CSS 尺寸 (Dimension)
- CSS Display 属性
- CSS Position 定位
- CSS Float 浮动
- CSS 水平对齐(Horizontal Align)
- CSS 组合选择符
- CSS 伪类
- CSS 伪元素
- CSS 导航栏
- CSS 下拉菜单
- CSS 图片廊
- CSS 图像透明/不透明
- CSS sprite 图像拼合技术
- CSS 媒体类型
- CSS 属性选择器
- CSS 实例