Craft was a well designed moderate box from HTB that exemplified bad coding practice, sensitive data disclosures and token abuse into root. From a technical standpoint this machine did not introduce any drastic new concepts however I did enjoy the thought that went into the box and it allowed me a chance to be hands-on with the VaultProject solution. Let's dive right into it.
As per usual we start off with enumerating the machine using NMAP.
The main page did not have anything useful at first look. Digging a bit under the hood we do discover that there are two additional domains.
We then add the domains to our hosts file and take another look.
Initially I believed the API endpoints would be our initial avenue in, however after exploring /auth/check and /auth/login that thought changed. We do have the ability to login and check whether a token is valid, however do not have an idea on valid credentials are just yet.
Once we move over to gogs.craft.htb we immediately see that a gogs (a self-hosted Git service) instance is running.
We discovered that the craft-api repository was publicly accessible. Perusing the repo we stumble upon two interesting tidbits.
Based on these finds and with the previous /auth/login api endpoint we looked at we're starting to shape up. We should initially be able to login and generate a valid token as dinesh using his credentials. Combine this with an unsanitized eval() in the /brew endpoint and we should be able to be able to pass a payload through a POST request. A few different payloads were tested however the following payload ended up working
Combining all the parts we write a small script to put it all together.
Despite generating a valid token and submitting a bogus ABV successfully I had issues getting the payload to trigger through the script. I ended up going the manual route and executed it directly.
Wait, root!? Well let's just pop over and get our root flag. Doh... after a few seconds of poking around it became evident that we were in a docker container, not the actual host.
After a bit of poking around we discover a dbtest.py file that seems to connect to the mysql instance running on the docker instance.
We copy this file and make slight modifications to see if we can enumerate some data from the mysql instance. Firstly, and this is the part that tripped me up for much too long, we need to change cursor.fetchone() to cursor.fetchall(). This little oversight caused me a lot of pain and ended up sending me down a few rabbit holes before realizing my mistakes. With fetchall set, we can change the query itself to:
We could use "SHOW TABLES" instead of the query above to determine the tables user and brew would exist, however I initially took a guess and assumed a table user would be present. The final code used ends up looking like the following.
And just like that we now have a few more credentials to add to the list.
With these credentials we can try a few different thing: SSH into the host and attempt to log back in to the gogs instance. SSH was unfortunately a bust butgilfoyle ends up being our lucky credential set and we manage to get in to the gogs instance. In addition to the previous craft-api repo we now also have access to the repo craft-infra. Let's poke around and see what additional information we can find!
Immediately my attention was drawn to the .ssh folder. Sure enough we manage to get what seems like gilfoyle's private key into the host.
Copying the contents over to our own host we attempt to SSH into the host using the key. We're asked for the key's password, and we made an assumption that gilfoyle uses the same password in various places. Sure enough, we are successful and finally have access to the user flag.
For as long as it took to get to the user flag the root flag seemed much simpler in comparison. From the user homedirectory we found something interesting - a .vault-token.
After a bit of searching around discovered that this is a VaultProject Token and is used to generate One-Time Passwords (OTP) and can be used for various things, including SSH. This seems like an interesting avenue. Sure enough, quickly see that this is what we are dealing with by confirming that vault utlity is installed on the machine, and that we can see the root_otp SSH role is defined on the repo.
With this information in our hands, we are able to initiate an OTP request and acquire a root shell.
And just like that we finish up our journey with Craft. Thanks everyone, until next time!
Follow me and let me know what you think of this article on twitter!