HackTheBox Writeup: Registry
Registry was a hard rated Linux machine that was a bit of a journey but a lot of fun for me. The initial foothold was gained by taking advantage of a weak password on a Docker registry which enabled us to download sensitive files, one of which was a private ssh key for the user 'bolt' and its passphrase. While enumerating the system, a database file for the Bolt CMS was found which contained a hash for a weak password. Cracking the hash enabled admin access to the CMS, which let us upload a webshell and pivot to the 'www-data' user. 'Www-data' had sudo access to run a Restic backup, so a Restic REST server was deployed on my attacking machine and a ssh tunnel used to make it appear the rest server was local to Registry. From there, a backup of Registry's /root folder was run and restored to my attacking machine which included root's private ssh key.
Whew, let's get started!
Enumeration
nmap scan:
The results on port 443 show a certificate for 'docker.registry.htb' so I added that to my /etc/hosts.
Let's check out http:
Https looked the same. I tried http://docker.registry.htb and got a blank page. Let's try running Gobuster:
Nothing interesting on http://registry.htb except for backup.php which we can't view. Let's see what Gobuster turns up on http://docker.registry.htb:
Initial Foothold
Going to http://docker.registry.htb/v2 brings up a login prompt:
I put in 'admin/admin' for creds and got this:
I googled around for 'docker registry' and landed on this page which helpfully detailed the anatomy of a docker registry hack. Following their lead, let's list the repos:
Let's see the tags listed for the "bolt-image" repo:
Now that we have the repo and tags, going to https://docker.registry.htb/v2/bolt-image/manifests/latest prompted me to download a json file saved as "latest". Piping it to 'jq' makes it a bit easier to read:
I saved all the "blobSum" values to a file 'blobs.txt' and used a for loop to download them all:
I then renamed all of these files to have a .tar.gz extension, extracted them all and started exploring the contents. Naturally I was very interested in the id_rsa file but there was a passphrase on it. Putting that to the side, there were some interesting commands in root's .bash_history:
There are a lot of breadcrumbs here. 'Sync.sh' looks interesting:
Despite appearing like the user 'bolt' was added and deleted, /root/.ssh/config references a user 'bolt':
You can also see that the id_rsa key is probably for 'bolt' if you look at the id_rsa.pub file:
One of the last files root was editing, /etc/profile.d/01-ssh.sh:
The passphrase works and we now have a stable shell as 'bolt':
User flag:
User Pivot
In /var/www/html there's an interesting php file:
The 'bolt' user does not have sudo access to restic so given that it's in /var/www/html, we probably need to become 'www-data'. While enumerating the system, I saw that nginx was installed and checked out this file:
Going to http://registry.htb/bolt/bolt brings up a login page:
After striking out with the usual weak passwords, I continued to enumerate the system and eventually found a promising looking database file. Since Registry did not have SQLite installed, I transferred it to my system by running scp -i id_rsa bolt@registry.htb:/var/www/html/bolt/app/database/bolt.db /root/htb/Registry/bolt.db
from my attacking machine. Opening it up in DB Browser revealed a hash for the admin user:
I pasted that hash into a file 'admin.hash' and cracked it:
The password works and we now have access to the Bolt CMS:
The first thing I checked was 'File Management' which did have an upload function but php files were forbidden. Fortunately, we are logged in as admin and can fix that by adding php files to the accepted file types:
I uploaded a webshell:
The webshell would stop working pretty quickly and the file would disappear. Why??? Remember that interesting 'sync.sh' file we found earlier? That's probably running as a cron job very regularly and overwriting everything in /var/www/html/bolt and its subdirectories. Well, the simple solution is to put it somewhere else that's accessible. I re-uploaded the webshell through the CMS, then used the webshell to upload another copy of itself into /var/www/html:
Now we have a stable webshell as www-data accessible at http://registry.htb/webshell.php:
Bash reverse shells didn't work but a python one did and we now have a shell as www-data:
Privilege Escalation
Www-data is allowed to run restic as root:
Remember that backup.php file we found earlier? Let's look at it again:
That gives us a good idea of the syntax needed. A quick google search lead me to Restic docs - specifically the section on REST server. The steps I followed:
- Install restic by running
apt-get install restic
- Create a repo:
3. Set up a ssh tunnel for port 8000 on my machine to port 8000 on Registry:
4. Install the REST server on my machine from here.
5. Set up the repository:
6. Run the Restic backup as root, telling it to backup Registry's /root folder to the REST server at http://127.0.0.1:8000 (which is tunneled to my machine):
We can see that the backup ran successfully so let's check out the Restic snapshots on my machine:
Restore the snapshot:
Looks like it worked!
The id_rsa file lets us login as root:
The root flag is finally ours: