This info was extracted from HTB Academy

Source code

HTML

As we can see, the website saysย Secret Serial Generator, without having any input fields or showing any clear functionality. So, our next step is to peak at its source code. We can do that by pressingย [CTRL + U], which should open the source view of the website:

As we can see, we can view theย HTMLย source code of the website.

CSS

CSSย code is either definedย internallyย within the sameย HTMLย file betweenย <style>ย elements, or definedย externallyย in a separateย .cssย file and referenced within theย HTMLย code.

In this case, we see that theย CSSย is internally defined, as seen in the code snippet below:

    <style>
        *,
        html {
            margin: 0;
            padding: 0;
            border: 0;
        }
        ...SNIP...
        h1 {
            font-size: 144px;
        }
        p {
            font-size: 64px;
        }
    </style>

If a pageย CSSย style is externally defined, the externalย .cssย file is referred to with theย <link>ย tag within the HTML head, as follows:

<head>
    <link rel="stylesheet" href="style.css">
</head>

JavaScript

The same concept applies toย JavaScript. It can be internally written betweenย <script>ย elements or written into a separateย .jsย file and referenced within theย HTMLย code.

We can see in ourย HTMLย source that theย .jsย file is referenced externally:

<script src="secret.js"></script>

We can check out the script by clicking onย secret.js, which should take us directly into the script. When we visit it, we see that the code is very complicated and cannot be comprehended:

eval(function (p, a, c, k, e, d) { e = function (c) { '...SNIP... |true|function'.split('|'), 0, {}))

The reason behind this isย code obfuscation. What is it? How is it done? Where is it used?

Code Obfuscation

Obfuscation is a technique used to make a script more difficult to read by humans but allows it to function the same from a technical point of view, though performance may be slower. This is usually achieved automatically by using an obfuscation tool, which takes code as an input, and attempts to re-write the code in a way that is much more difficult to read, depending on its design.

For example, code obfuscators often turn the code into a dictionary of all of the words and symbols used within the code and then attempt to rebuild the original code during execution by referring to each word and symbol from the dictionary. The following is an example of a simple JavaScript code being obfuscated:

Codes written in many languages are published and executed without being compiled inย interpretedย languages, such asย Python,ย PHP, andย JavaScript. Whileย Pythonย andย PHPย usually reside on the server-side and hence are hidden from end-users,ย JavaScriptย is usually used within browsers at theย client-side, and the code is sent to the user and executed in cleartext. This is why obfuscation is very often used withย JavaScript.

Use Cases

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.

Basic Obfuscation

Running JavaScript code

Let us take the following line of code as an example and attempt to obfuscate it:

console.log('HTB JavaScript Deobfuscation Module');

First, let us test running this code in cleartext, to see it work in action. We can go toย JSConsole, paste the code and hit enter, and see its output:

We see that this line of code printsย HTB JavaScript Deobfuscation Module, which is done using theย console.log()ย function.

Minifying JavaScript code

A common way of reducing the readability of a snippet of JavaScript code while keeping it fully functional is JavaScript minification.ย Code minificationย means having the entire code in a single (often very long) line.ย Code minificationย is more useful for longer code, as if our code only consisted of a single line, it would not look much different when minified.

Many tools can help us minify JavaScript code, likeย javascript-minifier. We simply copy our code, and clickย Minify, and we get the minified output on the right:

Once again, we can copy the minified code toย JSConsole, and run it, and we see that it runs as expected. Usually, minified JavaScript code is saved with the extensionย .min.js.

Note

Code minification is not exclusive to JavaScript, and can be applied to many other languages, as can be seen onย javascript-minifier.

Packing JavaScript code

Now, let us obfuscate our line of code to make it more obscure and difficult to read. First, we will tryย BeautifyToolsย to obfuscate our code:

eval(function(p,a,c,k,e,d){e=function(c){return c};if(!''.replace(/^/,String)){while(c--){d[c]=k[c]||c}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('5.4(\'3 2 1 0\');',6,6,'Module|Deobfuscation|JavaScript|HTB|log|console'.split('|'),0,{}))

We see that our code became much more obfuscated and difficult to read. We can copy this code intoย https://jsconsole.com, to verify that it still does its main function:

Note

The above type of obfuscation is known as โ€œpackingโ€, which is usually recognizable from the six function arguments used in the initial function โ€œfunction(p,a,c,k,e,d)โ€œ.

Aย packerย obfuscation tool usually attempts to convert all words and symbols of the code into a list or a dictionary and then refer to them using theย (p,a,c,k,e,d)ย function to re-build the original code during execution. Theย (p,a,c,k,e,d)ย can be different from one packer to another. However, it usually contains a certain order in which the words and symbols of the original code were packed to know how to order them during execution.

While a packer does a great job reducing the codeโ€™s readability, we can still see its main strings written in cleartext, which may reveal some of its functionality. This is why we may want to look for better ways to obfuscate our code.

Advanced Obfuscation

Obfuscator

Letโ€™s visitย https://obfuscator.io. Before we clickย obfuscate, we will changeย String Array Encodingย toย Base64, as seen below:

Now, we can paste our code and clickย obfuscate:

We get the following code:

var _0x1ec6=['Bg9N','sfrciePHDMfty3jPChqGrgvVyMz1C2nHDgLVBIbnB2r1Bgu='];(function(_0x13249d,_0x1ec6e5){var _0x14f83b=function(_0x3f720f){while(--_0x3f720f){_0x13249d['push'](_0x13249d['shift']());}};_0x14f83b(++_0x1ec6e5);}(_0x1ec6,0xb4));var _0x14f8=function(_0x13249d,_0x1ec6e5){_0x13249d=_0x13249d-0x0;var _0x14f83b=_0x1ec6[_0x13249d];if(_0x14f8['eOTqeL']===undefined){var _0x3f720f=function(_0x32fbfd){var _0x523045='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=',_0x4f8a49=String(_0x32fbfd)['replace'](/=+$/,'');var _0x1171d4='';for(var _0x44920a=0x0,_0x2a30c5,_0x443b2f,_0xcdf142=0x0;_0x443b2f=_0x4f8a49['charAt'](_0xcdf142++);~_0x443b2f&&(_0x2a30c5=_0x44920a%0x4?_0x2a30c5*0x40+_0x443b2f:_0x443b2f,_0x44920a++%0x4)?_0x1171d4+=String['fromCharCode'](0xff&_0x2a30c5>>(-0x2*_0x44920a&0x6)):0x0){_0x443b2f=_0x523045['indexOf'](_0x443b2f);}return _0x1171d4;};_0x14f8['oZlYBE']=function(_0x8f2071){var _0x49af5e=_0x3f720f(_0x8f2071);var _0x52e65f=[];for(var _0x1ed1cf=0x0,_0x79942e=_0x49af5e['length'];_0x1ed1cf<_0x79942e;_0x1ed1cf++){_0x52e65f+='%'+('00'+_0x49af5e['charCodeAt'](_0x1ed1cf)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x52e65f);},_0x14f8['qHtbNC']={},_0x14f8['eOTqeL']=!![];}var _0x20247c=_0x14f8['qHtbNC'][_0x13249d];return _0x20247c===undefined?(_0x14f83b=_0x14f8['oZlYBE'](_0x14f83b),_0x14f8['qHtbNC'][_0x13249d]=_0x14f83b):_0x14f83b=_0x20247c,_0x14f83b;};console[_0x14f8('0x0')](_0x14f8('0x1'));

This code is obviously more obfuscated, and we canโ€™t see any remnants of our original code. We can now try running it inย https://jsconsole.comย to verify that it still performs its original function.

More Obfuscation

Now we should have a clear idea of how code obfuscation works. There are still many variations of code obfuscation tools, each of which obfuscates the code differently. Take the following JavaScript code, for example:

[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(!
...SNIP...
[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]](!+[]+!+[]+[+[]])))()

This is JSFuck haha, check Esoteric languages ๐Ÿ’ข

We can try obfuscating code using the same tool inย JSF, and then rerunning it. We will notice that the code may take some time to run, which shows how code obfuscation could affect the performance, as previously mentioned.

There are many other JavaScript obfuscators, likeย JJ Encodeย orย AA Encode. However, such obfuscators usually make code execution/compilation very slow, so it is not recommended to be used unless for an obvious reason, like bypassing web filters or restrictions.

Check Esoteric languages ๐Ÿ’ข

Deobfuscation

Beautify

We see that the current code we have is all written in a single line. This is known asย Minified JavaScriptย code. In order to properly format the code, we need toย Beautifyย our code. The most basic method for doing so is through ourย Browser Dev Tools.

For example, if we were using Firefox, we can open the browser debugger with CTRL+SHIFT+Z, and then click on our scriptย secret.js. This will show the script in its original formatting, but we can click on the โ€˜{ }โ€™ button at the bottom, which willย Pretty Printย the script into its proper JavaScript formatting:

Furthermore, we can utilize many online tools or code editor plugins, likeย Prettierย orย Beautifier. Let us copy theย secret.jsย script:

eval(function (p, a, c, k, e, d) { e = function (c) { return c.toString(36) }; if (!''.replace(/^/, String)) { while (c--) { d[c.toString(a)] = k[c] || c.toString(a) } k = [function (e) { return d[e] }]; e = function () { return '\\w+' }; c = 1 }; while (c--) { if (k[c]) { p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]) } } return p }('g 4(){0 5="6{7!}";0 1=8 a();0 2="/9.c";1.d("e",2,f);1.b(3)}', 17, 17, 'var|xhr|url|null|generateSerial|flag|HTB|flag|new|serial|XMLHttpRequest|send|php|open|POST|true|function'.split('|'), 0, {}))

We can see that both websites do a good job in formatting the code:

However, the code is still not very easy to read. This is because the code we are dealing with was not only minified but obfuscated as well. So, simply formatting or beautifying the code will not be enough. For that, we will require tools to deobfuscate the code.

Deobfuscate

We can find many good online tools to deobfuscate JavaScript code and turn it into something we can understand. One good tool isย UnPacker. Letโ€™s try copying our above-obfuscated code and run it in UnPacker by clicking theย UnPackย button.

We can see that this tool does a much better job in deobfuscating the JavaScript code and gave us an output we can understand:

function generateSerial() {
  ...SNIP...
  var xhr = new XMLHttpRequest;
  var url = "/serial.php";
  xhr.open("POST", url, true);
  xhr.send(null);
};

As previously mentioned, the above-used method of obfuscation isย packing. 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.

HTTP Requests

We will use cURL

POST Requests

curl -s http://SERVER_IP:PORT/ -X POST

Tip

We add the โ€œ-sโ€ flag to reduce cluttering the response with unnecessary data

  • To send data, we can use the โ€œ-d "param1=sample"โ€ flag and include our data for each parameter, as follows:
curl -s http://SERVER_IP:PORT/ -X POST -d "param1=sample"

Decoding

You should check my note Translation and Shifting (Format encodindg) ๐Ÿฅญ