DEV Community

Cover image for How To Get a HackTheBox Invite Code! (Outdated)
L0WK3Y | I.A.A.N
L0WK3Y | I.A.A.N

Posted on • Updated on

How To Get a HackTheBox Invite Code! (Outdated)



How To Get a HackTheBox Invite Code.

So you want to practice penetration testing, you're looking around on your favorite search engine for a few pen-testing labs. Low and behold, you come across the holy grail that is hackthebox, you're interested in joining, so you click the "Join Now" button at the top right of the webpage. Expecting to be met with the basic username and password sign up, you're greeted with this...

Challenge Accepted.

To start things off let's look at the signup/invite page in its entirety.

As you can see there's a "Click Here" button for help, there's a good chance you've already clicked the said button and are wondering what to do afterward. Head over to Developer Tools by pressing F12 or CTRL+Shift+I and head to the Console tab. You will then be greeted by a nifty looking banner, here you will see another hint "This page loads an interesting javascript file. See if you can find it :)"

Getting Closer...

With another clue to guide us in the right direction, we can now head over to the Sources tab to view the source code for the webpage. In the Sources tab head over to the Page sidebar, there you will find the folders css, images, js. Inside the js folder, you'll find a file that should catch your eye and it's titled inviteapi.min.js. I wonder what could be in this file... Once inside the file, you'll see a long single line of code, you'll want to Pretty-Print to make the code a bit more readable.

Once Pretty-Print is enabled, the code should look like this...


//This javascript code looks strange...is it obfuscated???

eval(function(p, a, c, k, e, r) {
e = function(c) {
return c.toString(a)
}
;
if (!''.replace(/^/, String)) {
while (c--)
r[e(c)] = k[c] || e(c);
k = [function(e) {
return r[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
}('0 3(){$.4({5:"6",7:"8",9:\'/b/c/d/e/f\',g:0(a){1.2(a)},h:0(a){1.2(a)}})}', 18, 18, 'function|console|log|makeInviteCode|ajax|type|POST|dataType|json|url||api|invite|how|to|generate|success|error'.split('|'), 0, {}))

Now that we have a better idea of what we're looking at, we can observe the code a little better. At first glance, the code seems a bit complex, but we can still extract a few keywords like:

  • "makeInviteCode"
  • "generate"
  • "success"

  • Although, if you have some experience in programming, there should be a few keywords that also stand out to you, such as:

  • "ajax"
  • "POST"
  • "json"
  • "url"
  • "api"

  • If these 5 keywords look familiar to you, then you probably can guess what is coming next 😉,(POST Request) BUT before we get to that there's still one more clue that we missed if you got too caught up scratching your brain, trying to figure out what on Earth you're looking at. Then you probably looked over the most important clue in all of the code...

    Obfuscation

    Taking a look back at the code, in the very first line some text is commented out reading, "This javascript code looks strange...is it obfuscated???" "hmmm... obfuscated??? What does that mean? 🤔 you are probably thinking to yourself, well let's take a trip to Dictionary.com.

    In programming, obfuscation is used to "to confuse, bewilder, or stupefy." those who try to read the code. With that said now, you're probably thinking "how do we deobfuscate the code then?" For deobfuscation we will be using an online tool called de4js by lelinhtinh, the tool is super easy to use, all you have to do is copy and paste the JavaScript code into the textbox and click Auto Decode, and BOOM! You have the original JavaScript code.


    function makeInviteCode() {
    $.ajax({
    type: "POST",
    dataType: "json",
    url: '/api/invite/how/to/generate',
    success: function (a) {
    console.log(a)
    },
    error: function (a) {
    console.log(a)
    }
    })
    }

    Now that we can see the original code, we can see that the "makeInviteCode" is actually a function that creates the API key, and this is where those 5 programming keywords we mentioned early now come into play.

    POST Requests

    Within the function we see that ajax is being used, "Ajax is a set of web development techniques using many web technologies on the client side to create asynchronous web applications. With Ajax, web applications can send and retrieve data from a server asynchronously without interfering with the display and behaviour of the existing page. We can see in the function that, the type of data that Ajax is sending to the server is a POST and it is being sent to the url: '/api/invite/how/to/generate'. Now that we have an idea of what Ajax is doing in the function, let's talk a little about what a POST request is and how to make a POST request to the server. In computing, POST is a request method supported by HTTP used by the World Wide Web. By design, the POST request method requests that a web server accepts the data enclosed in the body of the request message, most likely for storing it.[1] It is often used when uploading a file or when submitting a completed web form. To make a POST request to the HTB server, we will be using this amazingly easy to use tool called reqbin. Simply type the main website URL "hackthebox.eu" into the text field and then take the URL from the makeInviteCode function and append them this should be your final URL for the POST request: hackthebox.eu/api/invite/how/to/generate Now you're all set to send the POST request!

    Once you've sent the POST request you should receive a status code of 200(OK) meaning that the request was sent successfully, and should also receive data inside of curly brackets. This data is called JSON or JavaScript Object Notation it's essentially a data type primarily used to store and transmit data. If you look back to the makeInviteCode function you can see that the person who wrote the code is telling Ajax the data type to expect when making the POST request is JSON. The JSON data that you received should look something like this.


    {
    "success": 1,
    "data": {
    "data": "SW4gb3JkZXIgdG8gZ2VuZXJhdGUgdGhlIGludml0ZSBjb2RlLCBtYWtlIGEgUE9TVCByZXF1ZXN0IHRvIC9hcGkvaW52aXRlL2dlbmVyYXRl",
    "enctype": "BASE64"
    },
    "hint": "Data is encrypted \u2026 We should probably check the encryption type in order to decrypt it\u2026",
    "0": 200
    }

    Now we are in the home stretch, and time to solve the second to last hint to get our invite code."Data is encrypted. We should probably check the encryption type in order to decrypt it.".

    Base64

    Picking up from where we left off, upon inspecting the JSON data we can see an attribute called "enctype": "BASE64". Base64 is the most popular binary-to-text algorithm used to convert data as plain text in order to prevent data corruption during transmission between different storage mediums. In addition, it is often used to embed binary data into text documents such as HTML, CSS, JavaScript, or XML. (XML has been replaced by JSON). To decrypt the data we will need to use a base64 decoder, we could use the many base64 decoders online. Instead, I decided to make my own in python just for the fun of it 😁.


    import base64
    import subprocess
    from sys import platform

    def osCheck():
    if platform == "win32":

        while True:
            try:
                subprocess.call(['cls'],shell=True) 
                modeSelect = input('Select a conversion mode: \n1: Encode\n2: Decode\n0: Exit\n\nSelection: ')
                if modeSelect == '1':
    
                    def enc():
                        subprocess.call(['cls'], shell=True)
                        userInput = input("Enter plain text here: ")
                        subprocess.call(['cls'], shell=True)
    
                        """
                        Uses base64 library to encode and decode text
                        https://docs.python.org/3/library/base64.html
                        """
                        b64enc = base64.b64encode(userInput.encode('utf-8'))
    
                        print('Original Text: ' + userInput + '\n\nEncoded Conversions\n_______________________\n\nBase64 Encoded:', b64enc.decode())
    
                        input('\n\n\nPress Enter to continue...')
    
                    enc()
    
    
                if modeSelect == '2':
                    subprocess.call(['cls'],shell=True)
                    def b64dec():
                        try:
                            subprocess.call(['cls'], shell=True)
                            userInput = input("Enter encoded text here: ")
                            subprocess.call(['cls'], shell=True)
    
                            """
                            Uses base64 library to encode and decode text
                            https://docs.python.org/3/library/base64.html
                            """
                            b64dec = base64.b64decode(userInput)
    
                            print('Converted Text: ' + b64dec.decode() + '\nBase64 Encoded: ', userInput)
                            input('\n\n\nPress Enter to continue...')
    
    
                        except:
                            input('Incorrect text format, please enter encoded Base64.\n\nPress enter')
                    b64dec()  
    
    
                if modeSelect == '0':
                    subprocess.call(['cls'], shell=True)
                    break
    
            except KeyboardInterrupt:
                subprocess.call(['cls'], shell=True)
                input('Program Terminated. Press Enter to continue...')
                subprocess.call(['cls'], shell=True)
    
                break
    if platform == "linux" or platform == "linux2" or platform == "darwin":
    
        while True:
            try:
                subprocess.call(['clear'],shell=True) 
                modeSelect = input('Select a conversion mode: \n1: Encode\n2: Decode\n0: Exit\n\nSelection: ')
                if modeSelect == '1':
    
                    def enc():
                        subprocess.call(['clear'], shell=True)
                        userInput = input("Enter plain text here: ")
                        subprocess.call(['clear'], shell=True)
    
                        """
                        Uses base64 library to encode and decode text
                        https://docs.python.org/3/library/base64.html
                        """
                        b64enc = base64.b64encode(userInput.encode('utf-8'))
    
                        print('Original Text: ' + userInput + '\n\nEncoded Conversions\n_______________________\n\nBase64 Encoded:', b64enc.decode())
    
                        input('\n\n\nPress Enter to continue...')
    
                    enc()
    
    
                if modeSelect == '2':
                    subprocess.call(['clear'],shell=True)
                    def b64dec():
                        try:
                            subprocess.call(['clear'], shell=True)
                            userInput = input("Enter encoded text here: ")
                            subprocess.call(['clear'], shell=True)
    
                            """
                            Uses base64 library to encode and decode text
                            https://docs.python.org/3/library/base64.html
                            """
                            b64dec = base64.b64decode(userInput)
    
                            print('Converted Text: ' + b64dec.decode() + '\nBase64 Encoded: ', userInput)
                            input('\n\n\nPress Enter to continue...')
    
    
                        except:
                            input('Incorrect text format, please enter encoded Base64.\n\nPress enter')
                    b64dec()  
    
    
                if modeSelect == '0':
                    subprocess.call(['clear'], shell=True)
                    break
    
            except KeyboardInterrupt:
                subprocess.call(['clear'], shell=True)
                input('Program Terminated. Press Enter to continue...')
                subprocess.call(['clear'], shell=True)
    
                break
    
    Enter fullscreen mode Exit fullscreen mode

    osCheck()

    text-converter.py | GitHub

    You try out the script on an online IDE called Repl.it or of course, you can use an online decoder, for this demonstration I will be using the decoder I wrote on Repl.it: L0WK3Y's Text Encoder/Decoder. Once you are on Repl select the decode mode and then copy and paste the encoded data string from the JSON into the terminal, and the script will decode the data string for you and give you the last URL string for the last POST request to getting the invite code /api/invite/generate. Now it's time to head back to reqbin for the final POST request.

    Invite Code Acquired

    We've finally reached the last stage of our quest to getting the invite code to hackthebox once you've made a POST request to hackthebox.eu/api/invite/generate.


    {
    "success": 1,
    "data": {
    "code": "Q0VUQ1EtUk5FRlItT0VES1ktTUtQTk0tSkNaVU4=",
    "format": "encoded"
    },
    "0": 200
    }

    You will receive yet another base64 encoded data string. Just pop that bad boy in the text decoder again and you've got your invite code!

    There it is in all of its glory the final key to getting into hackthebox, with that said, this concluding our journey to getting the invite code for hackthebox. I hope you've learned a lot from this blog and hope you continue to strive in your cybersecurity endeavors. This has been your guide L0WK3Y, and I hope you visit again in another learning adventure with me. Happy Hacking! 😊

    Connect With Me 😊

    Website Website Website Website

    Discussion (0)