Sunday 30 October 2011

Javascript Obfuscation - Getting "window"

In this section, I will show how to get the "window" global variable in an obfuscated way. This section is strongly related to how context works in javascript. If you have no clue what context are in javascript I suggest you take a look at what it is before reading this.

The most common method in javascript obfuscation to access "window" in an obfuscated way is to leak it. In standard mode (non "strict mode"), the global object (window) can leak in some cases. Here's a quick example to show how you can leak it :

function test() {
    return this;
}

a = test();


The variable "a" will now contain "window". This is a simple example, but it's not that great for obfuscation. What is better to use for obfuscation are native method that can leak the "window". One of the native method that is the simplest and most reliable to leak the global object from is "Array.prototype.concat".

Example :

a = [].concat; // We create a reference to Array.prototype.concat
b= a()[0]; // b now contains "window"


If you want to obfuscate this further you can always use the trick learned in the previous blog post and transform it into this :

[_=[][(1+{})[6]+(1+{})[2]+([][0]+"")[1]+(1+{})[6]+(!1+"")[1]+(!0+"")[0]],__=_()[0]]

Now "__" contains the "window" global object.

Javascript Obfuscation - Rewriting block of code

This section is about how to rewrite block of code in an obfuscated way. One of the obvious thing to do to chain your operation is to remove all the extra spacing, but this technique won't get you far since simple tool like jsbeautifier will unobfuscate your code very easily. What will we see is divided in 2 sections, the first one is about block of code that don't use any loop or condition, and the second one is about rewriting code that uses condition.

Simple block of code

Using array declaration

Array declaring are a nice and compact way to rewrite a block of code especially if we are re-using result from previous operation.

Example :

foo = 1;
bar = foo + 2;


Can be rewritten as :

[bar = [foo = 1][0] + 2];


This example is trivial, but there is one interesting thing to note. Most unobfuscator won't be able to rewrite the code in a nice way. If you use this pattern with larger amount of code, it will be a pain for people to understand the code even if they use tools.

Note : You can use the same principle with object declaration, but the syntax is less light and easier to follow.

Comma and parentheses

Using comma in parentheses is an other way to obfuscate code that is very similar to the previous one. It's something that most people don't know about and it's something that can leave most people perplex about the result.

Example :

({a:1},{a:2}).a


What is the result of this expression ? 1, 2 or an error ?

The actual answer is 2, because when you separate multiple operation with a comma in parentheses, the result of the parentheses is the result of the last operation. Once you know it it's simple, but for people that aren't aware of it, it can be puzzling.

Lisp style

This one last trick is interesting just for the look. It's mainly about syntax that use an abusive amount of parentheses.

Example :

(function z(){ return(z); })((foo = (1)))((bar = ((foo) + (2))))((alert((bar))))


If you are using a lot of a specific set of character in general, your code will be harder to read. Parentheses here are just an example, but it could also apply to "{" and "}".

Rewriting conditional block of code

In javascript it's possible to replace block of code that uses if/else statement using the conditional operator (ternary operator), logic operator (&&, ||), parentheses and comma.

Let's first take a look at what we can do with logic operator, parentheses and comma. This technique primarily uses the fact that logic operator are evaluated in a lazy way and that some block of code will only be executed in the cases we want.

Example :

if (test == 2) {
    bob = 1;
    foo = bob + 2;
}


Can be rewritten as :

(test == 2 && (bob = 1, foo = bob + 2))


With this technique we can also transform else statement with a little bit of logic.

Example :

if (test == 2) {
    bob = 1;
    foo = bob + 2;
} else {
    bob = 2;
}


Can be rewritten as :

((test == 2 && (bob = 1, foo = bob + 2, true)) || (bob = 2))


Note : The "true" is added there to make sure the first part of the expression always evaluate to true if test equals 2. This is a good trick to make sure the code will do the exact same thing even if we swap the "bob = 1, foo = bob + 2" part for something else. "true" can also be replaced with "1" or any expression that is truthy.

There is also the conditional operator (often called the ternary operator) that is useful to achieve the same thing. For the 2 previous examples using the conditional operator it would look like this :

(test == 2) ? (bob = 1, foo = bob + 2) : void(0)


and

(test == 2) ? (bob = 1, foo = bob + 2) : (bob = 2)

Friday 21 October 2011

Javascript Obfuscation - Introduction

Introduction

This is the beginning of a series of blog post about Javascript obfuscation. Obfuscation in Javascript is a very interesting topic, because Javascript has a lot of special syntax and special behavior that can be abuse to produce totally unreadable code. Truly obfuscated code can be so dark that even tools like JS Beautifier won't help you to have a clue about what's going on. The only thing about Javascript obfuscation that is missing is places to find knowledge about it and this is why I am starting a series of blog post about it.

Everything in this series should be working in a modern browser (IE7 is not a modern browser) unless it's noted otherwise. If you see any mistake, you can leave me a comment or send me a message and I will correct it.

Parts