Craft just retired today. I had lots of fun solving it and I learnt about a new interesting program called vault. Also, I loved the Silicon Valley theme. Its IP address is 10.10.10.110 and I added it to /etc/hosts as craft.htb. Without further ado, let’s jump right in!
Scanning & Web App Enumeration
Like most boxes, a light nmap offered me enough information to start exploiting this app.
Port 443 is open, meaning that a (most likely) HTTPS site is running on it. I opened https://craft.htb in a browser:
In the upper right corner, I found buttons that take me to 2 different sub-domains: api.craft.htb and gogs.craft.htb. I added them to /etc/hosts and accessed them.
Enumerating the 2 Sub-Domains
The first sub-domain, api.craft.htb, was not very interesting, because it hosted an API that could only be accessed with valid credentials.
Before testing the API, I wanted to make sure there’s nothing easier to exploit on gogs.craft.htb.
It turned out I was right. There’s a publicly-accessible repository that contains the API’s source-code:
Moreover, there was an interesting issue opened:
I viewed the commit that contained the patch and immediately saw the vulnerability:
The ‘patch’ uses eval() to check that that the ABV value (whatever that was 🙂 ) is less than 1. eval() should never be used on user input, because a malicious attacker could use it to gain RCE. At this moment, I knew I could get a shell if I had valid a valid username/password combo.
Note: For those of you that are wondering, the key that Dinesh supplied in the PoC code DID NOT WORK.
Credentials and ‘Shell As Root’
After I started looking for credentials, it wasn’t long before I found them. As it tuned out, Dinesh initially added a test script with his credentials:
Now that I had valid credentials, I made a simple script that would spawn a reverse shell:
After running the script, a reverse shell connected on port 443. I upgraded it to a tty and saw that it was root:
The root was a lie! It took me some time, but I realized that I was inside a docker container.
GOGS Credentials & User
As I was in the app’s directory, I read the contents of dbtest.py in order to find the credentials for the database:
The credentials were stored in craft_api/settings.py, so I listed that file’s contents:
After that, I connected to the database to see if there are any credentials I could use:
The database contained the following credentials:
I tried them on SSH, but they didn’t work. However, they seemed to be working on the GOGS platform. Gilfoyle had another private repository which seemed interesting:
I clicked on the .ssh folder to see if there are any keys:
Due to my VM configuration, I couldn’t change permissions of files in the current folder, so I created the id_rsa.gilfoyle file in /root/.ssh/:
The key is protected by a password. Fortunately, Gilfoyle reused his GOGS password, ZEU3N8WNM2rh4T, so I had the ability to connect to the machine:
The user proof starts with bb 🙂
Getting Root
(for real, this time)
After getting the user flag, I remembered an interesting folder in the private repository named vault, so I checked it out:
Basically, the system uses token to grant access to services across machines. I also found a file named .vault-token in the user’s home directory, so I tried to see the token’s capabilities:
The token had root privileges! This means that I could turn its privilege into a shell with the right set of commands. After more googling, I found out the exact procedure. First, I needed to authenticate:
After that, I connected to SSH as root using the One-Time Password (OTP) option of vault:
The password is the OTP code given by the application a few rows up. In my case it was 7982e0d2-0391-7733-bb4e-d508ac1ddd75.