
Get any a-Z char using only []()+{}/. in JavaScript (for XSS obfuscation) - ronnier
http://sla.ckers.org/forum/read.php?24,33349,33405
======
tsally
Similarly, tabs and spaces can be used as a primitive form of binary. A simple
decoder function will allow you to generate entire Javascript programs using
only whitespace.

Javascript obfuscation can get really nasty. For those interested in pursuing
the issue further, I recommend checking out Caffeine Monkey [1], an automated
tool for analyzing and classifying Javascript. The paper [2] gives a good
overview of Javascript obfuscation techniques and the implementation of the
tool.

One notable thing about Caffeine Monkey is that it attempts to do behavioral
analysis instead of signature-based analysis, thereby reducing the
effectiveness of obfuscation.

[1]
[http://www.secureworks.com/research/tools/caffeinemonkey.htm...](http://www.secureworks.com/research/tools/caffeinemonkey.html)

[2] [https://www.blackhat.com/presentations/bh-
usa-07/Feinstein_a...](https://www.blackhat.com/presentations/bh-
usa-07/Feinstein_and_Peck/Whitepaper/bh-usa-07-feinstein_and_peck-WP.pdf)

~~~
patrickas
This reminds me of Acme::Bleach for Perl :)

[http://search.cpan.org/~dconway/Acme-
Bleach-1.12/lib/Acme/Bl...](http://search.cpan.org/~dconway/Acme-
Bleach-1.12/lib/Acme/Bleach.pm)

------
lzell
I'm missing the basics for this one. Why does ++[[]][+[]] == 1?

~~~
jeresig
To start, you need to know that JavaScript has type coercion. Numbers can
become strings, strings can become numbers, and arrays can become strings.

Thus, for example: [] in a string context becomes "". "" in a number context
becomes 0. Thus if we were to do: "" - 1 we'd get the number -1. Additionally
if we were to do [] - 1 we'd get -1. ++ is also able to coerce a string into a
number.

If ++ is able to turn a string into a number then you're probably wondering
why they just don't do ++[] and be done with it (to get 1, that is). The
problem is that ++ is attempting to assign that resulting value back somewhere
and since [] doesn't exist anywhere yet (it's temporary) it throws an error
instead.

We could do something like this:

    
    
        var a = [];
        ++a; // 1
    

But we can't actually assign the result to a variable because we can't use
alphanumeric characters. So what's another way in which we can assign the
results to a variable? We can stick it into an array.

    
    
        var a = [ [] ];
        ++a[ 0 ]; // 1
    

This also works:

    
    
        ++[ [] ][ 0 ];
    

Now, we can't use 0 because it's alphanumeric so we swap 0 for +[] (+ turns
the string "" into the number 0, [] turns into the string ""). Thus we get the
final result:

    
    
        ++[ [] ][ +[] ]

~~~
kangax
The explanation of why ++[] throws error is actually incorrect. This has
nothing to do with "existence" of [] (I'm not even sure what existence could
mean here). Rather, it's the way ++ operator works.

++ requires its operand to evaluate to a _reference_, not a _value_. If
operand evaluates to a value, a ReferenceError is thrown (well, actually it is
internal PutValue method that throws error, but that's irrelevant here). Now,
if we were to pass reference to ++ operator, it would "work" as expected.
E.g.:

++({ x: 1 }).x;

In this case, `({ x: 1 }).x` is a reference, it evaluates to 1, and is then
increased by 1 to produce 2 as a resulting value.

When you said "this also works" with `++[ [] ][ 0 ]` example, what happened is
that `[ [] ][ 0 ]` evaluated to a reference too, and returned a value of array
(inner one). The fact that something like ++[[]][0] "works" should already
hint at the fact that "existence" of an object is a bogus reasoning ;)

So what we really need to understand here (besides type coercion) is the
notion of references. Literals, for example, always evaluate to values: 1,
"foo", true, ({ x: 1 }), and [] are all values. Expressions involving property
accessors, on the other hand — foo.bar, [1][0], ({ x: 1 }).x — are all
references.

Understanding this distinction can also help explain other aspects of
Javascript, such as, say, simple assignments, where left hand operand is
constrained by the same rules as ++ operator; it should always evaluate to a
reference:

1 = 1; // ReferenceError, LHS operand is not a reference

null = 1; // ReferenceError, LHS operand is not a reference

// but

({ x: 1 }).x = 1; // works as expected, LHS operand is a reference

x = 1; // works as expected, LHS operand is a reference

FWIW, it is the same internal PutValue method that's invoked by `=` operator,
and is why assignment to non-reference values result in an error.

~~~
jeresig
"This has nothing to do with 'existence' of [] (I'm not even sure what
existence could mean here)."

Ah sorry, I was referring to the fact that the array was already created and
within another object that we were referencing. But yeah, thanks for your
more-in-depth explanation!

------
raganwald
At the risk of summoning Captain Obvious...

Is this for sneaking code past XSS filters? Or for making XSS attacks more
difficult? Can someone explain the utility?

~~~
notauser
A lot of people do input validation by disallowing 'bad' characters.

The idea is to stop people buying JavaScript in comments, as that would be
bad. Just strip enough characters that you can't do functions and everything
will be...

...oops. Hope you remembered to filter out + and [] as well! Never mind, now
all your visitors are automatically posting/up-voting spam comments or
something similar. Better luck next time.

~~~
raganwald
Captain Obvious here again. Doesn't all this go away if you use Javascript to
inject untrusted text directly into the DOM rather than rendering it as HTML
which is then interpreted by the browser?

And if so, it seems to me that there's a fairly obvious way to build that
directly into templating engines and meta-languages like HAML.

~~~
mncaudill
That would work, but with the downside of lowering the accessibility of your
site. Not everyone has JavaScript enabled, and so dynamic insertion of text
wouldn't be accommodating to them.

~~~
zackattack
How many people don't have JavaScript enabled these days? I guess you have to
consider your audience. <http://www.w3schools.com/browsers/browsers_stats.asp>
has some clues.

~~~
mncaudill
That's true for people that don't need alternate browsers. It's like, "why
build wheelchair ramps outside of businesses when 99.99% of people are able to
walk up steps?"

<http://www.section508.gov/>

------
ronnier
Here's a page to convert JavaScript into this small character set:
<http://discogscounter.getfreehosting.co.uk/js-noalnum.php>

(From <http://twitter.com/jeresig/status/9680176440> &
<http://twitter.com/jeresig/status/9680335152>)

------
eel
Wow - how does this work? Does anyone know or have a link to a place that
might explain this?

~~~
there
it is basically various ways of making javascript return things like "NaN",
"undefined", or "false", and then using a numbered index to return a
particular character of that word after it is converted to a string.

so "NaN"[1] would be "a". "false"[0] would be "f".

since they are trying to do it without numbers, they can create them using
things like "++[[]][+[]]" which returns a 1. by adding up different numbers
you can get the digits you need.

~~~
est
Making strings out of nothing is hard, but how did they managed to execute
that string out of nothing?

~~~
tptacek
By deriving an eval-equivalent and indexing [] (read the comments).

~~~
est
Yes, I know how to make "eval", but how could it convert "eval" to eval() ?

Edit: by using []["sort"]["call"]()["eval"]

~~~
lisper
Yes, but why does _that_ work? I don't get:

+[]

or

[]['sort']

or

[]['eval']

for that matter, why does []['sort']['call'] work but []['call'] doesn't.

All of these look like they should be syntax errors to me. What am I missing?

~~~
aston
Here's the breakdown:

    
    
      []["sort"]["call"]()["eval"]
    

is the same in javascript as

    
    
      ([].sort.call()).eval
    

The part in parentheses calls Array.sort with an undefined _this_ object,
defaulting it to _window_. Array.sort returns _this_ after it's done. Global
functions like _eval_ are stored on _window_ , so you end up with
_window.eval_.

~~~
lisper
Ah. Thanks!

------
Jach
Wow, that's insane. Also, comparing hello worlds:

Brainfuck:

    
    
      ++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
    

JavaScript:

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

~~~
epochwolf
I'd like to file a bug report on your hello world. (Using webkit nightly on
OSX 10.6.2)

[http://i159.photobucket.com/albums/t146/epochcoyote/8950ccb4...](http://i159.photobucket.com/albums/t146/epochcoyote/8950ccb4.png)

~~~
epochwolf
But it works properly in Firefox.

[http://i159.photobucket.com/albums/t146/epochcoyote/8528ac1e...](http://i159.photobucket.com/albums/t146/epochcoyote/8528ac1e.png)

------
est
sla.ckers.org has the most epic thread of XSS vectors of all time

<http://sla.ckers.org/forum/read.php?2,15812>

You can find the the most bizarre javascript out there.

~~~
there
i think most of that has been summarized at <http://ha.ckers.org/xss.html>

------
vladocar
Hello World example - CopyPaste this in your address bar:
javascript:alert:(([][(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]()[(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]])([][(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]()[([][(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]()+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(![]+[])[+!+[]]](+[]+(!![]+[])[+[]])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(+[![]]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+!+[]]]+([][(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]()+[])[+!+[]+[!+[]+!+[]+!+[]]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([][[]]+[])[!+[]+!+[]]+[][(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]()[(![]+[])[+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]()+[])[!+[]+!+[]]]((+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]]+[+[]])+[])[+[]]+(![]+[])[+[]])[+[]]))

~~~
jfarmer
Hello norld!

~~~
vladocar
Hello norld! in Safari, Hello World! in Firefox

