本文翻译自:http://www.mbsd.jp/blog/20160921.html ,有改动
**原作者:プロフェッショナルサービス事業部 寺田 健**
**译者:Holic (知道创宇404安全实验室)**
部分内容翻译自[MBSD](http://www.mbsd.jp/blog/20160921.html),有改动。
## 0x00 漏洞概述
#### 漏洞简介
URL重定向漏洞有时会造成与上下文变量有关的漏洞,其导致的XSS便是常见的例子之一。本文所描述的[漏洞](https://support.apple.com/HT206900)在一年前提交至苹果官方,对应[CVE-2016-4585](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-4585),下面介绍这个漏洞的相关细节。
#### 漏洞利用点
1. 操纵请求中的Host头
2. Origin Confusion XSS
此外还可以盗取敏感信息和展开钓鱼攻击。
#### 受影响的组件
[Safari < v9.1.2](https://support.apple.com/HT206900)、[iOS < v9.3.3](https://support.apple.com/HT206902)、[tvOS <v9.2.2](https://support.apple.com/HT206905)
## 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头可以影响类似于以下的部分的代码:
```javascript
<script src="http://(HOST)/js/jquery.js">
<link href="http://(HOST)/css/style.css" rel="stylesheet" type="text/css">
```

当server中有类似代码的时候会触发漏洞。
在[Github](https://github.com/search?utf8=%E2%9C%93&q=%3Cscript+src%3D+%24_SERVER%5B%22HTTP_HOST%22%5D&type=Code&ref=searchresults)上能找到很多类似的代码,我在本地也进行了一系列验证。

我们看下```<script src=```标签这儿,假如Host头中的“example.com”修改为“example.com:abc":
```javascript
<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 ](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.30) 是禁止 Location header 中使用相对 但是 [RFC7231](https://tools.ietf.org/html/rfc7231#section-7.1.2)允许这么做 )。
如果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 参考
* http://paper.seebug.org/51/
* http://www.mbsd.jp/blog/20160921.html
* https://support.apple.com/HT206900
暂无评论