[译]Safari URL重定向漏洞(CVE-2016-4585)利用分析
本文翻译自:http://www.mbsd.jp/blog/20160921.html ,有改动
原作者:プロフェッショナルサービス事業部 寺田 健
译者:Holic (知道创宇404安全实验室)
0x00 漏洞概述
漏洞简介
URL重定向漏洞有时会造成与上下文变量有关的漏洞,其导致的XSS便是常见的例子之一。本文所描述的漏洞在一年前提交至苹果官方,对应CVE-2016-4585,下面介绍这个漏洞的相关细节。
漏洞利用点
- 操纵请求中的Host头
- Origin Confusion XSS 此外还可以盗取敏感信息和展开钓鱼攻击。
受影响的组件
Safari < v9.1.2、iOS < v9.3.3、tvOS <v9.2.2
0x01 漏洞详情
1.操纵Host头
在服务端返回302或者307状态码的情况下,我们可以构造如下请求:
Location: http://example.com:abc<'">()foo/
注意上面URL的端口号不是数字。Safari在处理的时候会访问example.com:80 ,并将请求头转换成下面这样:
Host: example.com:abc'%3C%26%22%3E()foo
Host头的端口是无效的,这意味着可以操纵浏览器的Host头访问任何位置。
漏洞利用有两点限制:
- 这些字符有一部分是编码过的;
- 只有":" 后面的内容可以修改
下面来探索一些攻击利用的技巧
闭合单引号导致的XSS
上面看到一些字符是受限的,比如"'"和"&"。 一些XSS攻击在Safari下是受限的:
Safari的XSS过滤机制对Host头反射型同样生效。当然下面的这种情况是可以触发XSS的。
可操纵hostname的XSS
Host头可以影响类似于以下的部分的代码:
<script src="http://(HOST)/js/jquery.js"> <link href="http://(HOST)/css/style.css" rel="stylesheet" type="text/css">
当server中有类似代码的时候会触发漏洞。
在Github上能找到很多类似的代码,我在本地也进行了一系列验证。
我们看下<script src=
标签这儿,假如Host头中的“example.com”修改为“example.com:abc":
<script src="http://example.com:abc/js/jquery.js">
这种情况下,Safari并不会加载此畸形的URL(URL不合法),而攻击者是想要在Safari加载他自己服务器上面的JS。
经过一系列实验,想出以下思路:
攻击者服务器上的响应:
此时对目标服务器上的请求:
在接收到Location之后,Safari连接至example.jp:80,发送的Host头如下
Host: example.jp:evil
开始部分的a@
被当做了基础认证信息。
目标服务器返回的内容:
(原图)
后面包括@
的部分被再次去掉了。由此可见,JS从攻击者的host获取,成功执行了XSS攻击。
攻击实例(加载了外部网站的js):
信息窃取
上面所说的技巧同样可以用来窃取信息。假设一些web服务会重定向的URL包含了一些私密信息:
Location: http://(HOST)/foo?token=fj0t9wj958...
在这种情况下,攻击者还是可以通过@
大法操纵Host头。
这种情景其实非常普遍,因为Location header是服务端对Host头的反馈最常见的地方。这可能因为不是web app的开发者这么写的,而是使用了相同的web平台,把相对URL处理成绝对路径的时候是基于Host头的。比如Java 的 HttpServletResponse#sendRedirect()方法。
顺便说下协议背景,路径绝对化的格式按照 HTTP/1.1 标准,RFC2616 是禁止 Location header 中使用相对 但是 RFC7231允许这么做 )。
如果header的值受到hostname的影响,除了Location header,HTML的URI属性像<form action=
和 <a href=
同样可以造成信息窃取漏洞。
2.域混淆XSS
根据原文作者的例子,他在使用:非数字
的方法测试目标链接的时候,像http://www.mbsd.jp:xyz/
在加载外部资源的时候会出现以下情况。
明显采用相对路径的URL资源没有正确加载。 我们可以在浏览器console下面可以进行验证:
此页面的域是损坏的,这便是为什么采用相对路径加载资源会失败了。cookie也因此无法获取。同源策略在一定程度上抑制了攻击者的行为,不过如果能够好好利用的话这个故事就会变得截然不同。
想到的最好的利用方法便是iframe了,我们可以找个在header中"X-Frame-Options"限制宽松的站进行测试。
原作者的示例如下:
我们发现经过一系列混淆,浏览器会加载以iframe的父页面为baseURL的资源,导致了加载错误。
同样我也在线上验证了这种情况:
同理,相对路径加载资源导致这种情况。
造成的影响
加载的JS是在加载损坏内容的情况下进行的,因此不能通过XHR的方式获取同站点的cookie。但是依然可以对自身的document内容进行操作,这意味着攻击者可以修改页面内容。使用Cookie验证的页面也是可以进行攻击利用的,因为请求中带有cookie。
漏洞要点
- Safari 在处理无效端口时使用默认端口(80,443)
- 畸形Host头比如
Host: hostname:xyz
可以发送至 Apache, WebLogic 和 Nginx等服务器,Tomcat 和 IIS 不会接收。 - 可以使用GET 和 POST的HTTP请求方法,使用302或者307进行跳转
- 在iframe中,base URL继承自父页面,奇怪的是至今
<base href=
被完全忽略了 - JS是在blank域下执行的,与iframe父页面分离,除了cookie,DOM对象皆可访问
- CSP (或者 X-Frame-Options) 可能会防止此XSS攻击
0x02 修复建议
升级Safari至 2016 年 7 月 18日以后的版本
官方修复:加强验证,不合法URL会显示错误
0x03 参考
- https://www.seebug.org/vuldb/ssvid-92437
- http://www.mbsd.jp/blog/20160921.html
- https://support.apple.com/HT206900
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- k8s安装自动证书签发cert-manager letsencrypt
- Android仿Keep运动休息倒计时圆形控件
- android通过led实现手电筒功能
- Android 7.0 手电筒控制实现
- 【STM32H7】第13章 RL-TCPnet V7.X之创建多个TCP客户端
- Android倒计时的开始与停止 剩余时分秒的展示
- 由LFI引起的Zimbra邮件管理系统0day
- Android手电筒兼容各个手机与版本
- 【STM32F429】第13章 RL-TCPnet V7.X之创建多个TCP客户端
- RecyclerView仿应用列表实现网格布局
- Android实现带进度条的WebView
- Android实现记住密码功能
- 【- Flutter Web篇 -】 FlutterUnit web版闪亮登场
- Android简单实现弹幕效果
- 实现 Base64 的编码解码