Going Above The Obfuscator
5 min read

Going Above The Obfuscator

Supreme's anti-bot "ticket.js"

Supreme utilizes the JScrambler obfuscator to protect their anti-bot code. JScrambler offers "enterprise" JavaScript code protection through a plethora of code transformations ranging from simple identifier mangling to self defending code.

Tools like beautifier.io are able to provide formatted versions of the code but the obfuscations remain.

One of the obfuscation techniques heavily utilized by Supreme is the use of evals. Javascript's eval function is a way to evaluate code given as a string.

How eval works

Most of the anti-bot logic are hidden in these eval calls. Searching "eval" in the ticket file yields 25 results.

Eval calls in Supreme's ticket

Knowing that the argument passed into eval has to be a string one may try and log what's getting passed into the function. Lucky for us, it's pretty easy to setup an environment to test this out in. Using just the ticket.js file and a simple HTML page to load it is enough to get us started.

Supreme's ticket formatted by beautifier.io and loaded in a simple HTML page

And going to the file in our browser shows us that the file is executed!

Stuck in a debugger loop while loading the page

But we're immediately thrown into a debugger loop. This is one of JScrambler's features. We're able to disable debugger breakpoints and bypass this with one caveat: we won't be able to use the debugger. This is fine for now as we plan on using console.log

Deactivate breakpoints to exit the loop

Placing a console.log call right before an eval should show us what code is getting executed. So let's try it.

Trying to log the argument to eval
Incorrect code and broken script after executing it with changes

Hmm, this doesn't look right. The string printed is not valid JavaScript code and it also prevents the script from further executing. This is because JScrambler uses techniques like hashing and integrity checks to prevent you from easily modifying certain functions.

At this point you can choose to go the deobfuscator route and use AST traversal + transformation as described in Part 1 but we'll be going a different route.

Ascending

All JavaScript code in the browser is ran by an engine. In Firefox's case they use the SpiderMonkey engine. Chrome uses the V8 engine. Lucky for us these projects are open source and we're able to build and run our own custom versions. The beauty of open source.

Firefox provides detailed guides on building Firefox on your machine. Go check it out!.

The docs also tell us which folders we care about most when looking through the huge codebase.

Folder structure of Firefox's codebase

In our case we care about js/src as it encapsulates the JS engine known as SpiderMonkey.

Searching for "Eval" in this folder should give us some results. In fact, there will be thousands of results but it's important you learn how to find what sticks out to you and dive in.

Searching for Eval in the Firefox codebase

Eval.cpp looks interesting so I'd probably start here! Scrolling down the file we find helpful comments on various functions. This is how we'll find exactly what function we want to intercept.

EvalKernel function that handles calls to JS eval

This one looks like what we need. We can test it out by logging what gets passed into the function. Let's see how logging is handled in this codebase by searching it up in your favorite search engine.

Oh look, a snippet!

Logging in Firefox

After reading the docs about logging in Firefox it seems simple enough. Throwing those lines into our EvalKernel function should give us what we want so let's try it.

Our modified EvalKernel to log argument to eval

Building...

Building changes to Firefox

Running..

Running our custom Firefox

Immediately we are met with logs from our Eval function. It appears Firefox evaluates some code of its own on launch. Pretty interesting.

The first eval call by Firefox

Heading to Supreme's site is looking a lot more exciting now.

An eval made by ticket.js
The debugger loop inside the eval

Tada!!

The code from the eval functions are here in cleartext! Formatting this in a tool like beautifier.io should give you an idea on how the internals of Ticket work.

What's next?

From here you can modify or intercept various JavaScript functions / operators. For example, you're able to intercept XOR operations and track their input/output (hint hint, AES).

Logging XOR operations
How to log those XOR operations

The End

Don't be afraid to dive into the internals of a browser. There's tons of documentation that exists and allows you to reverse-engineer scripts from the deepest level possible. AST & Debugging will get you far but this can get you the furthest.

Feel free to message me on Twitter if you have questions!