Bitlab just retired today. I had lots of fun solving it and I certainly enjoyed using an unintended exploit to get root. Its IP address is ‘10.10.10.114’ and I added it to ‘/etc/hosts’ as ‘bitlab.htb’. Without further ado, let’s jump right in!
Scanning & Initial Web Enum
A light nmap scan provided me with enough information to get started:
After seeing the results, I opened a browser and accessed the machine on port 80:
I also started dirb, which discovered some accesible URIs:
The ‘help’ directory had directory listing enabled and only contained one file named ‘bookmarks.html’:
The file contained some links:
Deobfuscating bookmarks.html
The last link, ‘Gitlab Login’ didn’t work, so I downloaded the page and inspected the source. The owner probably obfuscated the link:
The first step was to isolate the JavaScript code, HTML decode and prettify it using an online tool (I used this one and this one):
After that, I renamed the array ‘arr’ and converted the \x chars to ASCII (using python’s print() function):
As soon as I finished doing that, I completely removed arr by replacing arr[i] with its string value:
Most of my readers will probably understand that code, but let’s finish deobfuscating it anyway:
I tried using clave/11des0081x to log in to Gitlab and it worked:
Shell as www-data
After some playing around, I discovered that the ‘Profile’ repository had AutoDevOps enabled, meaning that the repository would be synced with bitlab.htb/profile/ (which can be accessed by clicking on your avatar and selecting ‘settings’). I tried to create a .php file that would get me a shell. The first step was to navigate to the repo and select ‘New File’:
After clicking ‘Commit changes’ ans ‘Submit merge request’, I tried accessing yakuhito.php, but it didn’t work. The reason was simple: I also needed to merge the changes. I did that by simply clicking the green ‘Merge’ button on the page that I was redirected to:
After that, I tried running a simple command to test if the server runs PHP code:
I wanted to upgrade to an interactive shell, so I used shellgenerator to generate a command that used python to start a reverse shell:
Getting user.txt
After looking around for a bit, I found an interesting snippet on Gitlab:
I made a simple PHP script that dumped the ‘profiles’ database using the credentials found in the above snippet:
The base64 sctring decodes to ‘ssh-str0ng-p@ss’, however, the password for ‘clave’ is the encoded string (‘c3NoLXN0cjBuZy1wQHNz==’):
The user proof starts with ‘1e’ 😉
Privesc – The Intended Method
Once I logged in as ‘clave’, I listed the contents of the home directory and saw a Windows executable:
The intended solution was probably to reverse engineer this executable and get SSH creds for root, however, I suck at reversing, so I used the next method.
Privesc – The Unintended Method
After enumerating as www-data for a bit, I dicovered that the user was able to run ‘git pull’ with root privileges:
I searched the internet for way to abuse this and found an interesting thread about executing commands automatically after running git pull. Basically, I had to use git hooks, which are just files that get executed after git finishes specific actions. First, I cloned the profile repository and created the hook:
The repository was owned by root, so I had to make a local copy in order to create the ‘post-merge’ file in the ‘.git/hooks’ directory. Before executing git pull, I also created a new file and approved the merge request, so the local repository would have to be updated.
The shell hung and a revers shell connected on port 443:
The first 2 characters of the root proof are ‘8d’ 😉