====== SymbolicJS: notes on JavaScript obfuscation ====== Inspired by JSFuck, but here's the rules: * 7-bit printable ASCII (32 to 126) * No alphanumerics (''[a-zA-Z0-9]''), no spaces, only ''``'' quotes ===== Build some strings with keywords ===== Use either ''`${}`'' or ''(+[])'' to obtain useful keywords: ^keyword^code^ |''[object Object]''|''{}''| |''true'' |''!``''| |''false''|''![]''| |''NaN''|''-`!`''| |''undefined''|''[]%%[[]]%%''| |''-Infinity''|''~[]/[]''| ===== Index the strings with numerals ===== ^number^code^ |-4|''~-~-~!``''| |-3|''~-~!``''| |-2|''~!``''| |-1|''~``''| |-0|''-``''| |0|''+``''| |1|''+!``''| |2|''-~!``''| |3|''-~-~!``''| |4|''-~-~-~!``''| ===== Build a basic alphabet ===== We can use variables, but only those whose name contains `$` and `_` so we'll use some sort of morse code-based encoding, with `$`=>`.` and `_`=>`-`, and a prefix to differentiate lowercase and uppercase: ^ ^code^ |a|''%%$$_=`${![]}`[+!``]%%''| |b|''%%$_$$$=`${{}}`[-~!``]%%''| |c|''%%$_$_$=`${{}}`[-~-~-~-~!``]%%''| |d|''%%$_$$=`${[][[]]}`[-~!``]%%''| |e|''%%$$=`${!``}`[-~-~!``]%%''| |f|''%%$$$_$=`${![]}`[-``]%%''| |i|''%%$$$=`${[][[]]}`[-~-~-~-~!``]%%''| |j|''%%$$___=`${{}}`[-~-~!``]%%''| |l|''%%$$_$$=`${![]}`[-~!``]%%''| |n|''%%$_$=`${[][[]]}`[+!``]%%''| |o|''%%$___=`${{}}`[+!``]%%''| |r|''%%$$_$=`${!``}`[+!``]%%''| |s|''%%$$$$=`${![]}`[-~-~!``]%%''| |t|''%%$_=`${!``}`[-``]%%''| |u|''%%$$$_=`${!``}`[-~!``]%%''| |y|''%%$_$__=`${-~[]/[]}`[-~-~-~-~-~-~!``]%%''| |I|''%%_$$=`${~[]/[]}`[+!``]%%''| |N|''%%__$=``${-`!`}`[-``]%%''| |O|''%%____=`${{}}`[-~-~-~-~-~-~-~!``]%%''| |space|''%%____$=`${{}}`[-~-~-~-~-~-~!``]%%''| Actually, we can just use the ''[a,b]="ab"'' notation to make it way shorter. Note that using ''+[]'' or ''+``'' is now shorter due to the lack of need of parentheses. [,$___,$_$$$,$$___,$$,$_$_,$_,____$,____]={}+[], // o,b,j,e,c,t,space,O [$$$_$,$$_,$$_$$,$$$$]=![]+[], // f,a,l,s [,$$_$]=!``+[], // r [__$]=-`!`+[], // N [,_$$,$_$,,$$$,,,,$_$__]=~[]/[]+[], // I,n,i,y [$$$_,,$_$$]=[][[]]+[] // u,d Of course, a few of those are not needed, can be removed if you don't need them, and those identifiers can always be shorter. We need at least enough to spell ''constructor'' and ''return btoa''. Here's the minimum: [,$___,$_$$$,,$$,$_$_$,$_,____$]={}+[], // o,b,e,c,t,space [,$$_,,$$$$]=![]+[], // a,s [,$$_$]=!``+[], // r [$$$_,$_$]=[][[]]+[], // u,n Note that we need the ''l'' for ''console.log'', and I'll put it back here, but it's shorter to move the ''i'' to the ''btoa'' call later in this document. ===== Execute arbitrary code ===== Now we have enough letters to execute arbitrary code: $=(_=>_)["constructor"] // returns Function $=(_=>_)[$_$_$+$___+$_$+$$$$+$_+$$_$+$$$_+$_$_$+$_+$___+$$_$] ===== Build more letters ===== We can then use `btoa` to get a lot of the letters we're missing, most notably ''h'' and ''i'' to spell ''return this'', and the ''g'' from ''log''. [K,i,g,h]=Function("return btoa")()`*(!` // returns 'Kigh' [,$$$,$__$,$$$$$]=$((_=$$_$+$$+$_+$$$_+$$_$+$_$+____$)+$_$$$+$_+$___+$$_)()`*(!` It's useful to save ''"return "'' for later here. You might want to use another variable name, though. ===== Build the global object ===== _=Function("return this")() _=$(_+$_+$$$$$+$$$+$$$$)() ===== Access global variables and run some code ===== _["console"]["log"]("hello") _[$_$_$+$___+$_$+$$$$+$___+$$_$$+$$][$$_$$+$___+$__$]($$$$$+$$+$$_$$+$$_$$+$___) ===== console.log example ===== [,$___,$_$$$,,$$,$_$_$,$_,____$]={}+[], // o b e c t space [,$$_,$$_$$,$$$$]=![]+[], // a l s [,$$_$]=!``+[], // r [$$$_,$_$]=[][[]]+[], // u n $=(_=>_)[$_$_$+$___+$_$+$$$$+$_+$$_$+$$$_+$_$_$+$_+$___+$$_$], // $=Function [,$$$,$__$,$$$$$]=$($$_$+$$+$_+$$$_+$$_$+$_$+____$+$_$$$+$_+$___+$$_)()`*(!` // i g h $($$_$+$$+$_+$$$_+$$_$+$_$+____$+$_+$$$$$+$$$+$$$$)() // $("return this")() [$_$_$+$___+$_$+$$$$+$___+$$_$$+$$][$$_$$+$___+$__$]($$$$$+$$+$$_$$+$$_$$+$___) // console.log("hello") [,$___,$_$$$,,$$,$_$_$,$_,____$]={}+[],[,$$_,$$_$$,$$$$]=![]+[],[,$$_$]=!``+[],[$$$_,$_$]=[][[]]+[],$=(_=>_)[$_$_$+$___+$_$+$$$$+$_+$$_$+$$$_+$_$_$+$_+$___+$$_$],[,$$$,$__$,$$$$$]=$($$_$+$$+$_+$$$_+$$_$+$_$+____$+$_$$$+$_+$___+$$_)()`*(!`,$($$_$+$$+$_+$$$_+$$_$+$_$+____$+$_+$$$$$+$$$+$$$$)()[$_$_$+$___+$_$+$$$$+$___+$$_$$+$$][$$_$$+$___+$__$]($$$$$+$$+$$_$$+$$_$$+$___)