Deobfuscating BreakingPoint's JS Challenge
Now that the BreakingPoint Systems contest is over and since several of you wanted to know how I did it, here’s an overview. First off, when I approached this, I just wanted to solve the puzzle as quickly as I could. If I couldn’t figure it out fast then I would go back to the beginning and read through and decode each line of code. But thankfully, I was able to solve it the quick way…
Let’s take a look at a cleaned up version of BreakingPoint’s obfuscated Javascript:
The script starts off by checking your user-agent string. Depending on your browser, it will return a value/key which is used to try to decrypt the chunk of decimal, hex, and octal values at the bottom of the script.
What was initially tricky was figuring out what these “toString” values were. Here’s one of the first statements I encountered. If you run this on your browser, you’ll see what this means:
alert(720094129..toString(1<<5));
This converts to "length". So this if-then statement:
(uUHIjMJVFJET.indexOf(523090424..toString(1 << 5) + "x") != -'c' [720094129..toString(4 << 3) + ""])
Can be translated to:
(uUHIjMJVFJET.length != -'c' [length])
Half-way through the script, there's a function that decodes the string of values at the bottom. You can see the function in the screenshot above. You will also see there's another "toString" statement with a value of 490837 (center of screenshot). When you alert on this, you'll see that this converts to "eval".
So at this point, I had a good idea of what I wanted to try. I could have used different browsers or used a user-agent spoofer but instead I thought I would just brute-force this by stripping off everything and passing the return values for each browser until I got the right key. And to deal with that obfuscated "eval" statement, I initially tried replacing it with "alert" but since that didn't work, I just base-converted "alert" to a decimal value of 11189117 and stuck that there. Here's what the script looked like after my modifications:
I tried the IE browser’s return statement but that didn’t work. Next I tried the Firefox’s return statement and bingo!
I noticed “body.appendChild” in the script so I added some body tags to the document. I also saw “.write” at the end so I took a closer look at that statement and noticed a “<" in the line above. Knowing that this is likely used in an HTML tag, I just changed it to "< " (less-than plus a space).
Then I executed the script and watched what it did.
The script spewed a bunch of strange looking HTML tags over and over until IE cried “uncle”. I noticed that the tags at the beginning had “audio” in it. Scrolling down, it then changed to “a” then to “base” and then repeated itself many times. I searched for this pattern in Google and eventually found a little known Firefox exploit. This part took longer than the actual deobfuscation. So there you have it! It was fun and quite a nice challenge they put together!
How did you deobfuscate it?