Tuesday 22 November 2011

Javascript Obfuscation - Properties access

The way we access properties of an object in Javascript is pretty much straight forward with some tiny exceptions. What is interesting for obfuscation though is the way we use it and that's what we will see.

Common object properties access

The most common way to access property of an object is by using the dot notation. It's very simple, but for obfuscation it's not very convenient since we have to explicitly tell what property we want to access. However, there is a second way to access a property that is more convenient for obfuscation and it's with the bracket notation. Example :

var foo = {a : 1};
foo.a // dot notation
foo["a"] // bracket notation


The reason the second one is more convenient for obfuscation is that it takes a string and has we have seen before we can easily use obfuscation technique to produce the string we want. So the previous example can be rewritten has :

var foo = {a : 1};
foo[(!1+"")[1]]


Number properties access 

Numbers do have 2 extra ways to access their properties. Those 2 ways where made up because the dot notation is not adapted for numbers. For that reason we have the "dot-dot" notation and the "space-dot" notation to access properties of a number. They are usually unknown to most of the developer even from experienced Javascript developer. Example :

1..toFixed(2) === "1.00"
(1 .constructor+"")[11] === "m"

Sunday 20 November 2011

Javascript Obfuscation - The numbers

The numbers

In this section we will explore the different ways we can get number values. The way javascript handles number and operator have a good set of particular behavior that can be surprising and we will see those behavior in detail. Also numbers in javascript only exist in one flavor 64-bit float. Whether we are talking about 1 or 0.5, it's always a 64-bit float.

Number declaration

There are multiple way of declaring a number, most of them are simple, but it can always be interesting to use a variety of them to confuse the reader.

 Notation  Expression 
Decimal100
Octal0144
Hexadecimal0x64

Using parseInt

The "parseInt" function has two particularities that are very interesting for obfuscation. The first one is that if you don't pass a 2nd argument to the function, it won't default to base 10, but it will try to guess the base of your number.

parseInt("10") === 10
parseInt("010") === 8


The second particularity of the function is that you can pass anything as a first argument including object and function. When you pass it something that isn't a string as the first argument, it will internally cast it as a string. Here are few examples that are using this point :

parseInt([].sort, 16) === 15 // function ... with base 16
parseInt([][[]], 31) === 26231474015353 // undefined ... with base 31


Casting anything to number

It's also possible to obtain number with the "+" operator as an unary operator. The result of the operation will be 1 or 0, expect if what you are prefixing is a number or a string. In fact for anything that isn't a string or a number the result of the operation is based on whether what you are trying to cast is truthy of falsy. Here's a good summary of what you can do with it :

Expression Result
+[]0
+""0
+!![]1
+null0
+true1
+false0
+"10"10
+"010"10

Note: I left the last one to point out that the "+" operator will always try to cast a number with base 10.