Hack The Box Craft Writeup –

Welcome to my Hack The Box writeup series. Today, let us go through a step-by-step walkthrough of getting the root of the Craft machine.

Hack The Box Craft Writeup -
Hack The Box Craft Writeup –

Craft is a very nicely done box, in fact, I really enjoyed a lot rooting this machine. The rooting process actually finds a vulnerability in the Git Repository with the help of Flask. The majority part of owning the machine will be done in the initial foothold. And this box will be an example of how the simplest mistake by a developer/ or a staff can compromise the backbone infrastructure of the organization.

Enumeration and Information Gathering

Let us start off with running a port scan using Nmap.

The nmap scan says a couple of ports wide open. By name, a port 22 and 443 are open, by description, we have an SSH and HTTPS ports for further recon. At this moment, let us add machine IP to the etc/hosts file as craft.htb and browse the HTTP(Secure) website.

An HTTPS Site:

The website on port 443 has limited information, but there are two links on the top menubar that discloses tow more sub-domains, namely API links to https://api.craft.htb/api/ and Git links to https://gogs.craft.htb/. Initially, I was not able to access the site, but after adding the newly discovered virtual hosts to etc/hosts to point to machine IP, I managed to access both of them.

Virtual HostsUnder Craft:

The API page is a documentation page of Craft API 1.0. This page gives further information about the API endpoints and how a developer or an end-user can interact with them.

After I proceed to enumerate the other page http://gogs.craft.htb/. This page is a self-hosted Git Repository. Since I have previous experience of Git Repo exposing credentials in commits, I went through the commit history to look for them. To my surprise I come across some committed API credentials of user Dinesh. However, the credential was not useful as the user Dinesh has limited information to disclose.

By further enumeration of repo and codes, I found that it’s a Python-based Flask application. I also found that the application endpoint /craft_api/api/brew/endpoints/brew.py calls the eval() function on the end-user action. Obviously, the authentication is required, I use the user Dinesh’s credentials to authenticate myself as Dinesh.

At this point, I’m certain that creating a reverse shell is possible by exploiting my favorite “Eval()” function with an unsanitized input. Also, to my joy, I as well found a test.py script ran by user Dinesh which I could use for authentication. I just need to download the Python script locally and modify it and use it to send it as a payload to the application to get a reverse shell. Let us exploit.

Test.py: https://gogs.craft.htb/Craft/craft-api/src/master/tests/test.py

From the tests folder, let us open the test.py script, We have two options to copy it, 1. We can download the whole folder in Zip format and get the test.py or just copy-paste the code into a new python file and make it ourselves.

I modified the response and as well added my payload.



Original test.py:

Modified test.py:

Once everything is in place, let us start the listener to get the reverse shell. Now the new test.py file is ready to be fired and our listener is ready to listen, let us run directly from the terminal -> python test.py and here we go, we have the shell.

We have the shell and it says we have a shell as root, however, we are stuck in a docker container that doesn’t have user.txt. We need to find out how to get out of the docker and get ourselves escalated to actual machine and the user. This is only possible after finding the right possible path. To find the path, we need to begin our exploration.

Escaping from Docker Container and Getting The User

Here we found a couple of credentials in the crafts_api folder and as well a python script called dbtest.py. It looks like dbtest.py is handly for us if we modify it and make it return the credentials stored in a database.

If we run the script without modification we will have the following output:

After running the modified mod.py with edited SQL command we found the following credentials:

Now you should be understood that saving credentials in plain-text how dangerous it is. 2 of the three credentials we just found should be able to get us the required access. As we found earlier, the website Gogs required credentials to log in, let us use these. The credential gilfoyle:ZEU3N8WNM2rh4T worked and we logged in to Gilfoyle’s private repository.

The initial exploration of Gilfoyle’s repository we found there is a directory /craft-infra with a padlock. After logging into the directory, we found his ssh public and private keys. Looks like the company Craft is full of mindless staff. This dude committed his private keys into the repository and the company saves his password in a plain text format.

Well, we don’t care about Craft company’s security policy, it is their problem, what we care about is how fast we can get our flags right? :).

Let’s go ahead and see what we have, the user Gilfoyle even has a directory called a vault and has a bash script running called secrets.sh. maybe this will be useful in the later stages. Let us concentrate on the user flag.

First, let us copy id_rsa and id_rsa.pub keys into ourKali machine ./ssh directory. And then run chmod 400 id_rsa to avoid permission error. And then run ssh gilfoyle@craft.htb. The Craft machine asks for the password of user GilFoyle. The password is the one we got from SQL command.

So we finally have the user.txt:

Getting Into the Root


The root is very simple and straight forward. As we already know from the “craft-infra” repository about “vault” and the script inside the vault directory that runs as root. Let us list all the directories of user Gil Folyle including hidden.

There is a hidden folder called “.vault-token”. A simple google search “Vault Token” led me to a project called “The Vault project“. An article from the project document shows how to log in as root using the One-time password (OTP).

As per the documentAn authenticated client requests credentials from the Vault server and, if authorized, is issued an OTP. When the client establishes an SSH connection to the desired remote host, the OTP used during SSH authentication is received by the Vault helper, which then validates the OTP with the Vault server. The Vault server then deletes this OTP, ensuring that it is only used once.

Rooting Easy Way

Since we are an authenticated user, it very simple to get the OTP and log-in as root.

That’s it, thanks for reading.


Hey there, I'm Navin, a passionate Info-Sec enthusiast from Bahrain. I started this blog to share my knowledge. I usually write on HackTheBox machines and challenges, cybersecurity-related articles and bug-bounty. If you are an HTB user and like my articles, please respect here: https://www.hackthebox.eu/home/users/profile/68523

View all posts by Navin →
Notify of
Inline Feedbacks
View all comments
Sorry, that action is blocked.
%d bloggers like this: