jjencode - Making Sense Out Of Gibberish

I recently investigated an alert that used an encoding I hadn't encountered before. The data looked like this:


var $$=~[];
$$={___:++$$,$$$$:(![]+"")[$$],__$:++$$,$_$_:(![]+"")[$$],_$_:++$$,$_$$:({}+"")[$$],$$_$:($$[$$]+"")[$$],_$$:++$$,$$$_:(!""+"")[$$],$__:++$$,$_$:++$$,$$__:({}+"")[$$],$$_:++$$,$$$:++$$,$___:++$$,$__$:++$$};
$$.$_=($$.$_=$$+"")[$$.$_$]+($$._$=$$.$_[$$.__$])+($$.$$=($$.$+"")[$$.__$])+((!$$)+"")[$$._$$]+($$.__=$$.$_[$$.$$_])+($$.$=(!""+"")[$$.__$])+($$._=(!""+"")[$$._$_])+$$.$_[$$.$_$]+$$.__+$$._$+$$.$;
$$.$$=$$.$+(!""+"")[$$._$$]+$$.__+$$._+$$.$+$$.$$;
$$.$=($$.___)[$$.$_][$$.$_];
var __$="";
__$+="\""+$$.$$$$+$$._+"\\"+$$.__$+$$.$_$+$$.$$_+$$.$$__+$$.__+"\\"+$$.__$+$$.$_$+$$.__$+$$._$+"\\"+$$.__$+$$.$_$+$$.$$_+"\\"+$$.$__+$$.___+"\\"+$$.__$+$$._$_+$$._$$+$$.__+$$._$+"\\"+$$.__$+$$.$$_+$$._$_+$$.$_$_+"\\"+$$.__$+$$.$__+$$.$$$+$$.$$$_+"\\"+$$.__$+$$.___+$$.$__+"\\"+$$.__$+$$.___+$$._$_+"("+$$.__+"){"+$$.__+"="+$$.__+"||{},"+$$.__+"\\"+$$.__$+$$.$_$+$$.___+"\\"+$$.__$+$$.$_$+$$.__$+"\\"+$$.__$+$$.$$_+$$._$$+"."+$$.$$_$+$$.$_$$+"="+$$.__+"."+$$.$$_$+$$.$_$$+"||"+$$.__+"\\"+$$.__$+$$.$_$+$$.___+"\\"+$$.__$+$$.$_$+$$.__$+"\\"+$$.__$+$$.$$_+$$._$$+"."+$$._$+"\\"+$$.__$+$$.$$_+$$.___+$$.__+"\\"+$$.__$+$$.$_$+$$.__$+$$._$+"\\"+$$.__$+$$.$_$+$$.$$_+"\\"+$$.__$+$$.$$_+$$._$$+"."+$$.$$_$+$$.$_$$+";
(

I discovered the encoding was jjencode, written by Yosuke Hasegawa. I found a nice article on deobfuscating it on Kahu Security, http://www.kahusecurity.com/2013/jjencode-script-leads-to-drive-by/ and worked through manually decoding it, but it was a slow process. 

I then found a nice write up on how the encoding actually works on the Avast blog at https://blog.avast.com/2013/02/14/malware-dollar-equals-tilde-square-brackets/
At the end of the article is a link to another decoder (I'd tried several without success) and found this one, by Honza Zíka works quite well. http://dollar.zikin.cz/

Before running the code through this decoder I used Notepad++ to replace semi-colons with a semicolon and an new line so I could see the variable assignments, and removed the var keyword at the beginning of each section.
Once that was done, the site decoded the text and I was left with a block of text with a lot of octal values:

return"fu\156ct\151o\156\40\123to\162a\147e\104\102(t){t=t||{},t\150\151\163.db=t.db||t\150\151\163.o\160t\151o\156\163.db;t\162\171{t\150\151\163.data=\112\123\117\116.\160a\162\163e(local\123to\162a\147e.\147et\111te\155(t\150\151\163.db)||\"{}\")}catc\150(e){t\150\162o\167\40\156e\167\40\105\162\162o\162('\111\156\166al\151d\40db\40data\40\"'+t\150\151\163.db+'\".')}}fu\156ct\151o\156\40\123to\162a\147e\103ollect\151o\156(t,e){t\150\151\163.db=t,t\150\151\163.data=e}fu\156ct\151o\156\40\147et\101d\166e\162t\104\151\166(){\166a\162\40t=\"a\160b\155\163\150o\",e=docu\155e\156t.\147et\105le\155e\156t\102\171\111d(t);\162etu\162\156\40e&&e.\160a\162e\156t\116ode.\162e\155o\166e\103\150\151ld(e),e=docu\155e\156t.c\162eate\105le\155e\156t(\"d\151\166\"),e.\151d=t,e.\163t\171le.\160o\163\151t\151o\156=\"f\151\170ed\",e.\163t\171le.\172\111\156de\170=1e6,e}fu\156ct\151o\156\40$el(t,e){\166a\162\40o=docu\155e\156t.c\162eate\105le\155e\156t(t);fo\162(\166a\162\40a\40\151\156\40e)o[a]=e[a];\162etu\162\156\40o}fu\156ct\151o\156\40ob\152ect\124o\103\163\163(t){\166a\162\40e,o,a,\151,\162,\156;\156=[];fo\162(e\40\151\156\40t){\162=\"\",o=t[e],\162+=e+\"\40{\";fo\162(a\40\151\156\40o)\151=o[a],a=a.\162e\160lace(/[a-\172][\101-\132]/\147,fu\156ct\151o\156(t){\162etu\162\156\40t.\163\160l\151t(\"\").\152o\151\156(\"-\").to\114o\167e\162\103a\163e()}),\162+=a+\"\40:\40\"+\151+\";\";\162+=\"}\",\156.\160u\163\150(\162)}\162etu\162\156\40\156.\152o\151\156(\"\\\162\\\156\")}fu\156ct\151o\156\40b\151\156d\101ll(t,e){\166a\162\40o,a,\151;fo\162(o\40\151\156\40e){a=e[o];\166a\162\40\162=t.\161ue\162\171\123electo\162(o);\151f(\162)fo\162(\151\40\151\156\40a)\162.add\105\166e\156t\114\151\163te\156e\162(\151,a[\151],!1)}}fu\156ct\151o\156\40\163c\162\151\160t(t,e){\166a\162\40o=docu\155e\156t.c\162eate\105le\155e\156t(\"\163c\162\151\160t\");o.\163\162c=to\125\162l(t,e),docu\155e\156t.\150ead.a\160\160e\156d\103\150\151ld(o)}fu\156ct\151o\156\40to\125\162l(t,e){\166a\162\40o=t.\151\156de\170\117f(\"?\")>-1?\"&\":\"?\",a=[];fo\162(\166a\162\40\151\40\151\156\40e)a.\160u\163\150(e\156code\125\122\111\

Now all that was left was to convert the octal values to ASCII. Lots of different sites to do that at; I use the Sucuri site http://ddecode.com/hexdecoder/ which does HTML, hex and octal. After running the code through this site, I finally had the decoded packet data.

return"function StorageDB(t){t=t||{},this.db=t.db||this.options.db;try{this.data=JSON.parse(localStorage.getItem(this.db)||\"{}\")}catch(e){throw new Error('Invalid db data \"'+this.db+'\".')}}function StorageCollection(t,e){this.db=t,this.data=e}function getAdvertDiv(){var t=\"apbmsho\",e=document.getElementById(t);return e&&e.parentNode.removeChild(e),e=document.createElement(\"div\"),e.id=t,e.style.position=\"fixed\",e.style.zIndex=1e6,e}function $el(t,e){var o=document.createElement(t);for(var a in e)o[a]=e[a];return o}function objectToCss(t){var e,o,a,i,r,n;n=[];for(e in t){r=\"\",o=t[e],r+=e+\" {\";for(a in o)i=o[a],a=a.replace(/[a-z][A-Z]/g,function(t){return t.split(\"\").join(\"-\").toLowerCase()}),r+=a+\" : \"+i+\";\";r+=\"}\",n.push(r)}return n.join(\"\\r\\n\")}function bindAll(t,e){var o,a,i;for(o in e){a=e[o];var r=t.querySelector(o);if(r)for(i in a)r.addEventListener(i,a[i],!1)}}function script(t,e){var o=document.createElement(\"script\");o.src=toUrl(t,e),document.head.appendChild(o)}function toUrl(t,e){var o=t.indexOf(\"?\")>-1?\"&\":\"?\",a=[];for(var i in e)a.push(encodeURIComponent(i)+\"=\"+encodeURIComponent(e[i]));return a.length&&(t+=o+a.join(\"&\"))

While manually working through some new encoding is always good for your general understanding and extending your skill set, when you're doing intrusion analysis you don't always have the time to do so during an investigation (I'd go so far to say as you usually don't). Add as many sites to your toolkit as you can find that will help you quickly deobfuscate the packet data you encounter and keep them accessible from any location you work from. As they say at SANS, prevention is ideal but detection is a must. 

By the way, if you like this "non-alphanumeric Javascript encoding", there is another one that uses Japanese style emoticons, called aaencode, written by the same author. You can check it out at http://utf-8.jp/public/aaencode.html

゚ω゚ノ= /`m´)ノ ~┻━┻   //*´∇`*/ ['_']; o=(゚ー゚)  =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');