SN 某javascript函数引发全站(含主站)dom反射XSS 超详细跟踪分析 + 修复方案
【注意:此文章为博主原创文章!转载需注意,请带原文链接,至少也要是txt格式!】
所有加密文章都是博主原创或精心收集或自行翻译国外的等较高质量的文章,每篇文章都会含有一些较为不错的知识点。但是请注意,加密文章如果你想查看,那么需要你用比较有质量的文章来和博主做交换,或者投稿。当然除了以上两种方式之外你也可以考虑付一些报酬来查看文章。这里的每篇文章博主都会亲自归纳知识点,都会让你不虚此行。
这是一个反射XSS从头到尾的开始逐步的分析文章,超级详细的分析了这个dom型反射XSS,如果你坚持详细的看完你会发现,结尾有个彩蛋。
首先打开https://talk8.xsstest.cn/robot/create.htm源码,然后注意登录和未登录的区别。
这里已经看到,如果没有登录,则 snTalk 数组中会有一个 noLogin:"true"
继续跟踪此函数。发现此函数会被多个功能所调用。
https://res.xsstest.cn/project/yunxin/js/chat_window.js?v=20180625 这里会多次调用
如下图:
此图已经说的很详细了。此页面加载的所有功能都会先判定是否登录,因为“未登录”这个网站,所以就必定会走进 ensureLogin 这个函数内。上图左侧已经画红圈。 这个是一个重点哦。(任何调用这个函数的地方都可能会触发此问题)
这里带进去了一个函数,及一个变量,变量已经在html中设置好了,如图:
我们找到ensureLogin这个函数。
https://sslres.jd.cn/project/passport/js/passport.min.js 函数在这个文件里面。
下面的分析基本都是基于此文件了。
如下图:
这里,会判断passport_config、config是否被初始化,因为上面已经说了,html页面中就已经初始化了。
所以这里会继续往下走。进入popupLoginContainer这个函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | function popupLoginContainer(a) { if (typeof a == "undefined") { if (typeof passport_config != "undefined") { a = passport_config } else { alert("You must define passport_config var."); return } } currentLocation = window.location.href; //……………………内容太多这里基本就全都省略了。直接看这里的最后一步即可 $("#modalContainer").html('<iframe id="iframeLogin" style="position: fixed ;" width="1" height="1" src="' + b + '" frameborder="0" scrolling="no" allowtransparency="yes"></iframe>'); if (typeof intervalVar != "undefined") { clearInterval(intervalVar) } intervalVar = window.setInterval(checkMsgFromLoginIframe, 200) //前面不用管,注意走到了这里。 } |
从上面的代码可以看到,最终走到了intervalVar = window.setInterval(checkMsgFromLoginIframe, 200)
window.setInterval 这个函数没必要说了。这里需要看一下,把checkMsgFromLoginIframe 带入到了window.setInterval。
继续跟踪checkMsgFromLoginIframe 这个函数。代码如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | function checkMsgFromLoginIframe() { var a = window.location.hash; //首先获取当前URL地址。 if (a.length > 1) { var b = a.split("#"); //把获取的URL地址通过#进行分组。 var c = b[1].split(":"); //这里把数组二 再次通过:冒号进行分割, switch (c[0]) { //这里开始判断属于第几个,然后就执行那个,这里明显是最后一个。 case "resize": resizeContainer(c[1]); break; case "close": closeContainer(); break; case "loginSuccess": loginSuccess(); break; case "loginRedirect": location.href = decodeURIComponent(c[1]); //最终跟踪到这里,就是这里引发的问题。😀 break; default: break } } } |
只有以诚相待,才会不虚此行。
-------------------------------------------------
最终访问:
https://talk8.xsstest.cn/robot/create.htm#loginRedirect:javascript%3Aalert%281%29
触发XSS
-------------------------------------------------
网站首页及其它页面XSS示例:
-------------下面是其他页面的XSS,直接合并成一张图片-------------
--------------------------------------------------------
至此,此问题跟踪分析完毕,也找出漏洞原因。下一步就是修复喽。
修复方案(过滤):
1 2 3 4 5 6 7 8 9 10 11 | //增加一个正则过滤的规则 var stripscript = function(s){ var pattern = new RegExp("(<|>|=|(|)|`|\\)") //这里我给的方案并不完善,应该更完善一些。 var rs = ""; for (var i = 0; i < s.length; i++) { rs = rs+s.substr(i, 1).replace(pattern, ''); } return rs; } //这里增加一下过滤,基本这样就达到了一个防御的状态,但是还要注意一下,要贴合业务,如果业务需要可能还需要其他过滤方法。 location.href = stripscript(decodeURIComponent(c[1])); |
彩蛋,你以为这篇文章详细的讲一个dom型的XSS就算完事了???
你以为这个故事到这里就结局了???
一定要优雅的玩转反射XSS。让危害最大化才是我们的终极目的。
其实这是下一个故事《反射XSS修改cookie 伪造登陆窗口实现登陆劫持》的开始。。。。。。
留言留言 留言测试