Tuesday 27 September 2011

Javascript Obfuscation - The booleans

The booleans

In this section we will explore the different ways we can get boolean values. It might seems at the first look that there isn't much to say about the subject and I hope you will be surprised by the end of the post.

There is 2 common ways to get boolean values in an obfuscated way. The first one we will see is by using the "equality" operators and the second one is by using the "not" operator. It's also good to note that the "or" and "and" operator aren't used much in obfuscation to get boolean, simply because it doesn't always give boolean as an output (I will write up about this in an other blog post, this one).

The equality operator

Javascript has two operators to test for the "equality" of 2 variables. The first one "==" is more a similarity operator and the second one "===" is a strict equality operator. The first one is particularly interesting because it gives results that can be unexpected in various cases. Here are few example of this :

(null == undefined) => true
(false == "false") => false
(false == "0") => true
(NaN == NaN) => false
(2 == [[[2]]]) => true
([2] == [[[2]]]) => false

You can also see this Stack Overflow answer for more examples.

For the "===" operator there is less to say, because it's a strict operator. The only thing that gives a result that can be unexpected is the following :

(NaN === NaN) => false

NaN is a special value in Javascript. The way this value is defined, if you do an operation with this value the result will be NaN. This is why when you test if something equals NaN it will always be false.

The not operator

The not operator "!" in Javascript is commonly used to force something to be cast to a boolean value. But what is less known and that you can use in obfuscation is the result of this cast on value that aren't at the first look made to be cast to boolean. Here are few examples :

Expression Result
!0 true
!3 false
![] false
!({}) false
!"" true
!"0" false
!NaN true

Monday 26 September 2011

Javascript Obfuscation - The strings

The strings

Strings can be obtained in a couple of unusual way. Most of those way of obtaining string in unusual ways relies on abusing type conversion. Abusing type conversion to produce obfuscated code is in itself  a very interesting thing that we will also explore in other parts.

To get started, I will show up the basic step that are commonly used to produce an obfuscated string.

Step 1 - Available string

There is a good number of thing that will produce a string in javascript. Here's a good list to get started :

(1/0)+"" === "Infinity"
1+{} === "1[object Object]"
("a"/2)+"" === "NaN"
false+"" === "false"
true+"" === "true"
[].concat+"" === "function concat() { [native code] }"
[][[]]+"" === "undefined"

Note that all of these are forcing type conversion of values to string in various of ways. The most common one is by adding an empty string (+""). The one that is used in the 2nd example is using the fact that when you add an object and a number it will force both of them to become a string before they get added.

Step 2 - Getting letters

Now that we have a couple of string available, the next thing to do is to get letter by using the fact that strings are array-like structure. If we combine that with step 1, we can get this :

"undefined"[0] === "u"
([][[]]+"")[0] === "u"

You can get most of the letter you need with the string given in the step 1, but there are letter that you simply can't get using that method. For those letter there are other ways to get them in an obfuscated way. Here are a few ways that you can use :

Name Notation
Unobfuscated "{"
Unicode "\u007b"
Octal ASCII "\173"
Hexadecimal ASCII "\x7b"

Step 3 - Composing string

Now that we can get individual letter, we can combine them to make our own string. Here are few examples :

(!1+"")[2]+(1+{})[2]+(!1+"")[2] === "lol"
(1+{})[4]+(!1+"")[3] === "js"

Extra

In addition to this blog post, here's a reference for how to get most letter you will need in an obfuscated way.

Letter Obfuscated letter
a(!1+"")[1]
b(1+{})[3]
c(1+{})[6]
d([][[]]+"")[2]
e([][[]]+"")[3]
f([][[]]+"")[4]
i([][[]]+"")[5]
j(1+{})[4]
l(!1+"")[2]
m*(1..constructor+"")[11]
n([][[]]+"")[1]
o(1+{})[2]
r(!0+"")[1]
s(!1+"")[3]
t(!0+"")[0]
u([][[]]+"")[0]
v*([].sort+"")[23]
y(1/0+"")[7]

* It's not guaranteed by the specification to return this value.

Sunday 25 September 2011

Javascript Obfuscation - The variables

The variables

One of the thing about variables in Javascript that is not so known is that their name can contains a very width range of character. Lets take a peak look at what the Ecmascript specification allow :

  • Your variable name can start with $, _ or a Unicode Letter (Lu, Ll, Lt, Lm, Lo, Nl).
  • For the rest of the name of the variable you can use $, _, Unicode Letter or Unicode Number (Nd).
There's ton of stuff that is considered as a valid variable name and what's really interesting for obfuscation is that there are a lot of letter that are very similar and there are also letter for which most people will only see a square when they will view the source. The only thing you need to be careful about is encoding. If you're using UTF-8 and your Javascript file is not recognize as a UTF-8 file on the client side, that will break your script. The same thing applies to all encoding of course.

If you don't feel in a comfort zone when using Unicode extensively, there are other thing you can abuse. One of the other thing you can abuse is the way some character are displayed. The best example of this is the character underscore. In most text editor, it's very hard to know how much of them there is when you place them one after the other. Are _____ and ______ the same variable name ?


External Links

Thursday 8 September 2011

LiveTool, P2P experiment in Javascript

I have been working in the last month in a project called LiveTool which was an experiment of how it would be possible to use P2P communication in a Javascript application. The project in itself can be found on GitHub : https://github.com/HoLyVieR/LiveTool

In brief, the project was a graphic editor that could be used by multiple people at the same time and people could see all the modification that where done as soon as they are made.

What where the obstacle ?


One of the main obstacle in starting this project was that RTMFP is not a well known technology and the documentation is very limited. In fact nearly everything you will found about it is made by Adobe. Also, the way RTMFP works in Actionscript is not very intuitive. Also when I wanted to start this project, I couldn't find any Javascript library that would allow me to use RTMFP without doing any Actionscript. This is the main reason I builded the RTMFP-JS library.

What about support for people that don't have Flash ?


This is a point I wanted to experiment with the project. Using P2P communication is very interesting, but it isn't widely supported so you still have to think about integrating fallback for those that don't support it. Technically speaking it isn't hard to implements, but if you don't integrate it from the start, it can be very hard to do. The fallback that I implemented for LiveTool is very simple, if you don't support RTMFP or if you want to send data to someone that doesn't support RTMFP, the server is used as a repeater.

Will LiveTool have more updates ?


For now, I'm leaving the LiveTool project as it is now, since I got to the point where I did the experiment that I wanted to do with it.

What about ... ?


If you have question about the project, you can leave a comment and I will try to respond to you or do a blog post about it.

Wednesday 7 September 2011

P2P and Javascript

I have been experimenting  P2P connection with Javascript (in the browser) over the past few months, it's been quite interesting and it has revealed to me that it could have a lot of potential.

How do I do P2P communication in Javascript ?


You probably won't hear about P2P communication and Javascript a lot, because there isn't any native API that will allow you to have direct connection with other client. But it is supported through a common 3rd party plugin : Flash. Inside Flash you can use a protocol called RTMFP which allows P2P connection. If you want to read up about it you can have more information on adobe website.

But you said with Javascript, not Actionscript !


The nice thing about Flash, is that you can communicate with Javascript through ExternalInterface. With this we can use Flash technology but with Javascript and we don't have to create a Flash application to use RTMFP. If you don't really care about the Actionscript / ExternalInterface part, you can use some already made library which will take care of it. I builded up my own which is available on Github : https://github.com/HoLyVieR/RTMFP-JS-Bridge

Why should I use P2P communication ?


P2P communication is mainly aimed for application that require that multiple client speak to each other. One of the basic example of that kind of application would be a chat. All the information that are sent between the client won't have to pass through the server. It reduces traffic and load on your server since you are now sending and receiving less data while doing the same thing.

Why shouldn't I use P2P communication ?


There are 2 principle obstacle to P2P communication. Network infrastructure and Flash support. If you are inside a corporate or school network, there's a strong chance nobody will be able to connect to you because of the way the network you are in is made. As for the Flash support, it isn't supported on some mobile platform and even tough there is a larger proportion of the Internet user that have it, some don't have it for various of reasons ( OS support, they don't have admin rights on their machine, etc. ).

What about security ?


The RTMFP protocol informations are quite vague or hidden, so it's hard to say how secure the protocol is, but from what Adobe has written so far it seems that the information that is exchanged between the client is encrypted.

The only certitude that you can have is that the information that a client will receive will be from untrusted source (an other client, not the server), so you have to implement the same information checking that your server would have, but on the client.