Home >Web Front-end >JS Tutorial >Exploring the Six Characters in JavaScript
JavaScript is a weird and interesting language, and we can write some crazy code that still works. It tries to help us convert things into specific types based on how we treat them.
If we add a string, JavaScript will assume we want text representation, so convert it to a string. If we add a positive or negative prefix symbol, JavaScript will assume that we want a numeric representation and convert the string to a number for us if possible. If we add a negation symbol, JavaScript will convert the string into a boolean value.
We can use the six symbols [,],(,),! and + in Javascript to write some magical codes. If you're not on your phone right now, you can open your browser's console and you can paste any code example into the console with the code value true.
Let’s start with the basics, some golden rules to remember:
! The characters following will be converted to a Boolean value
+ The characters following will be converted to a numeric value
[] The characters followed will be converted to a boolean value will be converted into a string
Look at the following example:
![] === false +[] === 0 []+[] === ""
Another thing you should know is that it is possible to retrieve specific letters from a string using square brackets, like this:
"hello"[0] === "h"
Also remember you can use Multiple numeric numbers are represented together by adding strings, and then converting the entire expression into a number:
+("1" + "1") === 11
Let’s continue to combine some things together to get the letter a
![] === false ![]+[] === "false" +!![] === 1 ------------------------ (![]+[])[+!![]] === "a" // same as "false"[1]
Apply inferences!
We can get similar letters a, e, f, l, r, s, t, u through true and false, but can we get letters from other places?
We can get undefined through some special formulas such as [][[]], and use the golden rules we mentioned above to get the other letters d, i and n.
`[][[]] + [] === "undefined"`
With all the letters we have acquired so far, we can spell fill, filter and find. Of course there are some other words that we can also spell, but the most important thing about these words is that they are all array methods. This means that they are part of the array object and can call the array instance directly, such as: [2,1].sort().
Now, another important thing to know about JavaScript is that the properties of an object can be accessed through dot notation or square brackets []. The above array methods are properties of the array object itself, and we can call these methods using square brackets instead of dot notation.
So [2,1]["sort"]() is equivalent to [2,1].sort().
Let’s go ahead and see what happens when we try to use an array method, we can use So far we have spelled but not called letters.
[]["fill"]
This will get function fill() { [native code] }, we can use this method header as a string again using our golden rule:
[]["fill"]+[] === "function fill() { [native code] }"
So now we get other characters: c,o, v,(,),{,[,],}.
With our new c and o, we can now form the word constructor. A constructor is a method, and all JS objects simply return their own constructor.
For the objects we have dealt with so far, we can get its constructor function represented as a string:
true["constructor"] + [] === "function Boolean() { [native code] }" 0["constructor"] + [] === "function Number() { [native code] }" ""["constructor"] + [] === "function String() { [native code] }" []["constructor"] + [] === "function Array() { [native code] }" ({})["constructor"] + [] === "function Object() { [native code] }"
With these formulas, we can add the following characters to our library:
Now we can construct a function "toString"` that we can use square brackets, which we can call like this:
(10)["toString"]() === "10"
Using our golden rule, we can already convert anything we want into a string, but the above equation How to use it?
Well, let me tell you, the toString method of Number type has a secret argument called radix ("radix"). It converts the value to a base before converting it to a string, like this:
(12)["toString"](10) === "12" // 十进制 (12)["toString"](2) === "1100" // 二进制 (12)["toString"](8) === "14" // 八进制 (12)["toString"](16) === "c" // 十六进制
But why is the base only written to 16? The maximum value is 36, including all characters 0-9 and a-z, so now we can get any alphanumeric characters we want:
(10)["toString"](36) === "a" (35)["toString"](36) === "z"
Great! But what about other symbols like punctuation and capital letters? Let’s explore further.
Depending on when your JS is executed, it may or may not access specific predefined objects or data. If you run this in a browser then you have access to some existing HTML wrapper methods.
For example, bold is a string method wrapped in a tag.
"test"["bold"]() === "<b>test</b>"
With this we get the two characters and /.
You may have heard of the escape method, which mainly converts a string into a URI-friendly format that can be interpreted by simple browsers. If we pass a space character, we get "%20".
Here is a tool that can convert each character automatically. Tool address: http://www.jsfuck.com/ Source code address: https://raw.githubusercontent.com/aemkei/jsfuck/master/jsfuck.js
Why are these characters useful?
It's not that eBay did some bad thing not too long ago that allowed sellers to put JS in pages using only these characters, but it is a fairly rare attack vector. Some people say obfuscate, but in fact, there are better ways to obfuscate.
Finally, I hope you will enjoy this exploration trip.
Resources:
https://en.wikipedia.org/wiki/JSFuck
https://esolangs.org/wiki/JSFuck
http://patriciopalladino.com/blog/2012/08/09/ non-alphanumeric-javascript.html
https://raw.githubusercontent.com/aemkei/jsfuck/master/jsfuck.js