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.
Great, Thanks !
ReplyDelete