Step 6: Javascript Obfuscation
I’m starting this fairly quickly (an hour or so) after finishing the knowledge check portion of ‘Getting Started’. Honestly the knowledge check was extremely easy. I did spend hours reading through nmap stuff and enumerating everything.
I understand you normally would but at that point, I was just ready to complete and move on… and so I did!
Anyway…
NOTE: I will likely not do ‘write-ups’ for boxes but focus on Obsidian notes to add to my repository on GitHub. For learning academy modules, I’ll put exercises and (SPOILER ALERT) screenshots.
Introduction
Code obfuscation is all about picking out bits of ‘hidden’ code. Starting off with HTML and locating JavaScript within it.
CSS code is either defined internally within <style> elements or defined externally with a ‘.css’ file and referenced within the HTML code.
Internally defined:
Externally defined (note the ‘href=”style.css”):
The same applies to JavaScript.
Task:
Painfully easy… CTRL+U and scroll down a little bit.
Obfuscation
Code obfuscation is the process of making it more difficult for humans to read whilst allowing it to still be successfully executed, albeit potentially at the cost of speed/efficiency.
This can be done by turning the letters and symbols into dictionaries which are then referenced individually as shown below:
Directly from HTB Academy:
Codes written in many languages are published and executed without being compiled in
interpreted
languages, such asPython
,PHP
, andJavaScript
. WhilePython
andPHP
usually reside on the server-side and hence are hidden from end-users,JavaScript
is usually used within browsers at theclient-side
, and the code is sent to the user and executed in cleartext. This is why obfuscation is very often used withJavaScript
.
Your interpreted languages are hidden server-side so we don’t see them (usually). Your JavaScript is usually client-side so obfuscation is used here.
(Discovered the quote feature as you can see…)
There are many reasons why developers may consider obfuscating their code. One common reason is to hide the original code and its functions to prevent it from being reused or copied without the developer’s permission, making it more difficult to reverse engineer the code’s original functionality. Another reason is to provide a security layer when dealing with authentication or encryption to prevent attacks on vulnerabilities that may be found within the code.
It must be noted that doing authentication or encryption on the client-side is not recommended, as code is more prone to attacks this way.
The most common usage of obfuscation, however, is for malicious actions. It is common for attackers and malicious actors to obfuscate their malicious scripts to prevent Intrusion Detection and Prevention systems from detecting their scripts. In the next section, we will learn how to obfuscate a simple JavaScript code and attempt running it before and after obfuscation to note any differences.
A common way of reducing readability of code is minification. This is just the process of having code in one long line. This allows minification to make it look effectively the same as it is all on the same line before and after.
Here is a JavaScript minifier tool in action:
Here is BeautifyTools for obfuscating JavaScript, shown below:
This is a type of obfuscation called packing, taking the words and symbols and referencing them as dictionaries using the {p, a, c, k, e, d} function.
The disadvantage to this is you still see main functions written in cleartext.
Now for more advanced obfuscation techniques using this.
The lesson talks about converting to base64 which OBVIOUSLY will make it impossible to read at least easily for humans, and a hell of a lot longer.
Deobfuscation
JSNice is just one option.
Another way of unpacking
such code is to find the return
value at the end and use console.log
to print it instead of executing it.
Task:
Easy… just open the source code (CTRL+U) and open the ‘secret.js’ and paste it into JSNice:
Personal note: It’s currently 21:00 on a Monday night and because of my obsessive tendencies and terrible sinuses the last couple of days I’m horrifically sleep deprived so going to really try to settle on a relatively early night. This seems a good place to stop for now. Tomorrow I’ll look through the examples, a lab on HTTP Requests and Decoding followed by the longer Skills Assessment…
Deobfuscation Examples
Alright folks, we’re back…
Here’s our deobfuscated code from earlier… time to break it down. Our ‘secret.js’ file only contains one function, ‘generateSerial()’.
HTTP Requests
Starts by defining the variable ‘xhr’, creating a new object ‘XMLHttpRequest’. This is a JS function that handles HTTP requests.
Our second variable is a generic url leading to a ‘/serial.php’ directory along the same origin domain as it wasn’t specified.
The main function of ‘secret.js’ is purely at this moment to send an empty POST request to ‘/serial.php’.
cURL… Hello Darkness My Old Friend
Nothing new here… just a friendly reminder.
POST request
Add -X flag :
Task:
Send a POST request using cURL to the ‘/serial.php’.:
Decoding
Our previous task seemed to give us a block of encoded text. Let’s review three of the commonly most used types of encoding.
Base64
Used to reduce the use of special characters.
Easily spotted due to its use of alpha-numeric characters only and it’s use of = for padding and has to be in multiples of 4. If your code is 3 characters long, an ‘=’ is added for padding purposes.
A lazy screenshot…
Hex
Remember the ASCII table? It’s back babies!
Spotting hex is easy too, it only has a-f and 0–9.
Lazy screenshot incoming…
Caesar/Rot13
The Caesar cipher is common, but old. It shifts each letter by a fixed amount. The most common version is Rot13 which shifts each letter 13 times.
Or use a tool.
If you are unsure of what encoding method was used try Cipher Identifier.
Task:
As you may be able to see:
Send the cURL with POST to get the base64 string. Decode that with a little “| base64 -d”
As you may be able to see when I went to send the POST request using cURL the first time I forgot the ‘-d’ flag… whoops and there’s our task.
Skills Assessment… uh oh
This seems like a whopper. We’ll figure this out as we go format wise…
Step 1:
Easy enough. Open ‘er up on FireFox (probably some terminal way to do it but whatevs), CTRL + U for source code and use your eyes:
Step 2:
Open the ‘api.min.js’ file. Copy the code and use the old terminal. The ‘node -v’ was just there to check node was installed in PwnBox. Too lazy to get the VM running.. sue me.
Step 3:
Copy the code that has been minified (put into a single line) and paste it in to Unminify and put it into JSNice to deal with the dictionary shenanigans:
Probably missed a step that would auto print it, but was easy enough to stick it together manually:
Step 4:
Okay so the code mentions /keys.php and POST so I’m thinking POST request to target ip:port/keys.php…
Oh look an alpha-numeric string (a-f and 0–9) which is Step 4 answer and Step 5 (echo “string” | xxd -p -r) decodes it for us
So you get the hex (alpha-numeric) key and send a POST request but I forgot the “key=…” part. All good now.
TA DAAAAA
Congratulations me!
A significant path completed. Overall, I really liked this module. Made me feel like a 21st century spy. Two days (a lot more for me with all the side-stuff, but here we are!) completed.
I’m looking and it looks like I should probably do Windows Fundamentals next.. meh. Can’t say I’m excited about it, but I’m not an expert on the ins and outs of Windows. It’s important as most corporate workplaces you’ll ever work in are Windows based and you’re probably going to end up hacking/defending Windows based workstations the most.
Also it leads to Active Directory… a notoriously large attack surface area. Okay, maybe I am a little more enthused now! It’s 22:10 here, I’m feeling good about today and gonna watch an episode of One Piece, have a little ice cream and get my beauty rest.