Unpacking Packed Javascript with Rhino In Three Steps

Malware authors use various techniques for obfuscating their code. One I commonly see is using the packer compressor. Code will begin with “eval(function(p,a,c,k,e,d)”. 

Below is a block I came across yesterday from a scareware scam site:

eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!”.replace(/^/,String)){while(c–){d[e(c)]=k[c]||e(c)}k=[function(e){return d[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}(‘b 1F=h.q;b 2=h.22;b d=h.V;b 9=\’\’+13(h.q);b w=O(h.q,10);b T,3,s;a((3=2.f(“1R/”))!=-1){d=”K”;9=2.c(3+4)}i a((3=2.f(“K”))!=-1){d=”K”;9=2.c(3+6);a((3=2.f(“W”))!=-1)9=2.c(3+8)}i a((3=2.f(“24″))!=-1){d=”1P”;9=2.c(3+5)}i a((3=2.f(“X”))!=-1){d=”X”;9=2.c(3+7)}i a((3=2.f(“1t”))!=-1){d=”1t”;9=2.c(3+7);a((3=2.f(“W”))!=-1)9=2.c(3+8)}i a((3=2.f(“11″))!=-1){d=”11”;9=2.c(3+8)}i a((T=2.12(\’ \’)+1)<(3=2.12(\’/\’))){d=2.c(T,3);9=2.c(3+1);a(d.1G()==d.1E()){d=h.V}}a((s=9.f(“;”))!=-1)9=9.c(0,s);a((s=9.f(” “))!=-1)9=9.c(0,s);w=O(\’\’+9,10);a(1J(w)){9=\’\’+13(h.q);w=O(h.q,10)}1r(g(){B()},1K);b m=1D v();b 16=(m.1A()+1)+”/”+m.1B()+”/”+m.1C()+” @ “+m.1H()+”:”+m.1Y();b p=r(\’p\’),U=r(\’U\’),C=r(\’C\’),l=r(\’l\’);g 15(){18(“1L: “+p+” Q (“+U+”) x “+C+”\\n\\20 21 26 29 2a 28 S “+16+”.\\n\\P (“+l+”) (R 1) 2b F 25!”)}g 1Z(){15();b 14=D*4,A=1s.1O(\’#1M\’);Z(14,A)}g B(){18(\’\\n\\1n!!\\n\\n***************************************\\n\\1o \’+p+\’ Q: 1k z 1j, 1f 1g 1h z 1q, u 1i u 1p 1z 1y 1w 1x 1v Y!\\n\\1m 1l F 1u!\\n\\1c 17 1a 1d:\\n\\P \’+l+\’ (R 1)\\n\\n\\***************************************\\n\\n\’)

This code can be unpacked (deobfuscated for us) if the block is complete and will compile. 

The tool we will use is Rhino, from the Mozilla Developers Network. If you are running Fedora, it is included in the Fedora repositories and you can install it with the command “dnf install rhino” or “yum install rhino”. there will be some dependencies that need installed as well.

Once Rhino is installed, however you get it, you need to copy the block of packed code into a file. Then replace the word “eval” at the beginning with the word “print” and save it.

Now all you need to do is run the file through Rhino, with the command “rhino (name of your file). The unpacked content will be display to the screen. 

[analyst@testsvr05 ~]$ rhino 4

var nVer=navigator.appVersion;var nAgt=navigator.userAgent;var browserName=navigator.appName;var fullVersion=”+parseFloat(navigator.appVersion);var majorVersion=parseInt(navigator.appVersion,10);var nameOffset,verOffset,ix;if((verOffset=nAgt.indexOf(“OPR/”))!=-1){browserName=”Opera”;fullVersion=nAgt.substring(verOffset+4)}else if((verOffset=nAgt.indexOf(“Opera”))!=-1){browserName=”Opera”;fullVersion=nAgt.substring(verOffset+6);if((verOffset=nAgt.indexOf(“Version”))!=-1)fullVersion=nAgt.substring(verOffset+8)}else if((verOffset=nAgt.indexOf(“MSIE”))!=-1){browserName=”IE”;fullVersion=nAgt.substring(verOffset+5)}else if((verOffset=nAgt.indexOf(“Chrome”))!=-1){browserName=”Chrome”;fullVersion=nAgt.substring(verOffset+7)}else if((verOffset=nAgt.indexOf(“Safari”))!=-1){browserName=”Safari”;fullVersion=nAgt.substring(verOffset+7);if((verOffset=nAgt.indexOf(“Version”))!=-1)fullVersion=nAgt.substring(verOffset+8)}else if((verOffset=nAgt.indexOf(“Firefox”))!=-1){browserName=”Firefox”;fullVersion=nAgt.substring(verOffset+8)}else if((nameOffset=nAgt.lastIndexOf(‘ ‘)+1)<(verOffset=nAgt.lastIndexOf(‘/’))){browserName=nAgt.substring(nameOffset,verOffset);fullVersion=nAgt.substring(verOffset+1);if(browserName.toLowerCase()==browserName.toUpperCase()){browserName=navigator.appName}}if((ix=fullVersion.indexOf(“;”))!=-1)fullVersion=fullVersion.substring(0,ix);if((ix=fullVersion.indexOf(” “))!=-1)fullVersion=fullVersion.substring(0,ix);majorVersion=parseInt(”+fullVersion,10);if(isNaN(majorVersion)){fullVersion=”+parseFloat(navigator.appVersion);majorVersion=parseInt(navigator.appVersion,10)}setInterval(function(){exit_alert()},3000);var currentdate=new Date();var datetime=(currentdate.getMonth()+1)+”/”+currentdate.getDate()+”/”+currentdate.getFullYear()+” @ “+currentdate.getHours()+”:”+currentdate.getMinutes();var isp=getURLParameter(‘isp’),ip=getURLParameter(‘ip’),city=getURLParameter(‘city’),num=getURLParameter(‘num’);function entry_alert(){alert(“WARNING: “+isp+” customer (“+ip+”) from “+city+”\n\nSerious security vulnerabilities have been found on “+datetime+”.\n\nCall (“+num+”) (PRESS 1) for immediate assistance!”)}function pop(){entry_alert();var fiveMinutes=60*4,display=document.querySelector(‘#time’);startTimer(fiveMinutes,display)}function exit_alert(){alert(‘\n\nWAIT!!\n\n***************************************\n\nATTENTION ‘+isp+’ customer: Your personal photos, Facebook and other personal passwords, as well as credit card information could be at risk!\n\nThis requires immediate attention!\n\nContact Tech Support Immediately:\n\nCall ‘+num+’ (PRESS 1)\n\n\***************************************\n\n’)}function addEvent(obj,evt,fn){if(obj.addEventListener){obj.addEventListener(evt,fn,false)}else if(obj.attachEvent){obj.attachEvent(“on”+evt,fn)}}function startTimer(duration,display){var start=Date.now(),diff,minutes,seconds;function timer(){diff=duration-(((Date.now()-start)/1000)|0);minutes=(diff/60)|0;seconds=(diff%60)|0;minutes=minutes<10 1="" addevent="" amountalerts="amountalerts+1}}})});$(window).on(" and="" as="" at="" attention="" be="" beforeunload="" body="" card="" could="" credit="" customer:="" diff="" display.textcontent="minutes+" document="" e="e?e:window.event;var" exit_alert="" facebook="" from="e.relatedTarget||e.toElement;if(!from||from.nodeName==" function="" if="" immediate="" immediately:="" information="" isp="" load="" minutes:minutes="" mouseout="" n="" nattention="" ncall="" ncontact="" nthis="" num="" nwait="" other="" p="" passwords="" personal="" photos="" requires="" return="" risk="" seconds:seconds="" seconds="" start="Date.now()+1000}};timer();setInterval(timer,1000)}var" support="" tech="" var="" well="" your="">
If the file is large you can redirect output to another file or page it through less. 

For more information, see the excellent SANS Handler Diary article by Daniel Wesemann at http://handlers.sans.org/dwesemann/decode/ and look at the method #4, the Monkey Wrench Method. 
He uses Spider Monkey instead of Rhino here, but the functionality is exactly the same (as he notes in the article).

This is a Security Bloggers Network syndicated blog post authored by JeffSoh. Read the original post at: JeffSoh on NetSec