Full Report
Cacti is an open source monitoring solution used by many different companies. They found this initially by scanning for bugs with their tool. The application is written in PHP. At the very beginning of the app, an authorization check is performed. If the IP address corresponds to a hostname in a table, then it will allow the user to make the request. Otherwise, it will deny it. While trying to figure out the IP, many user controlled headers are able to influence this request. A plethora of headers like HTTP_X_FORWARDED can be used to control the IP. Since the IP is used by authentication purposes, this is a complete authentication bypass. Using their tool, there appeared to be a command injection vulnerability within the user provided poller_id parameter for the bad sync proc_open. This creates a fairly trivial command injection vulnerability that can be used to get code execution. The first mitigation was to make the headers being accepted configurable but off by default. This is helpful for situations where this is behind a reverse proxy. For the command injection, cacti_escapeshellarg was used on the variable in two separate places to prevent a regression from occurring. Overall, their tool seems impressive! They keep reporting high impact issues like this one. Secondly, trusting headers that are user controlled for sensitive operations is a common problem. Good find!
Analysis Summary
# Vulnerability: Unauthenticated Remote Code Execution in Cacti
## CVE Details
- **CVE ID**: CVE-2022-46169
- **CVSS Score**: 9.8 (Critical)
- **CWE**: CWE-287 (Improper Authentication), CWE-78 (OS Command Injection)
## Affected Systems
- **Products**: Cacti Monitoring Solution
- **Versions**: 1.2.22 and below
- **Configurations**: Instances where at least one monitored device uses a data source with the `POLLER_ACTION_SCRIPT_PHP` action.
## Vulnerability Description
The vulnerability is a chain of two distinct flaws:
1. **Authentication Bypass**: The `remote_agent.php` script utilizes a hostname-based authorization check. The application relies on the `get_client_addr()` function, which can be manipulated via attacker-controlled HTTP headers (e.g., `HTTP_X_FORWARDED_FOR`). By spoofing an IP address that resolves to the internal Cacti server's hostname (often present in the `poller` table by default), an unauthenticated attacker can bypass the authorization check.
2. **Command Injection**: Once authenticated, the `poll_for_data()` function takes a user-provided parameter, `poller_id`, via `get_nfilter_request_var()`, which does not sanitize input. This variable is concatenated into a string executed by `proc_open()`. If a poller item exists with a PHP script action, arbitrary commands can be executed.
## Exploitation
- **Status**: PoC available; widely discussed in security research and exploited in the wild.
- **Complexity**: Low
- **Attack Vector**: Network
## Impact
- **Confidentiality**: High (Full access to server data and monitored device info)
- **Integrity**: High (Ability to modify files and system configurations)
- **Availability**: High (Ability to shut down services or delete data)
## Remediation
### Patches
- Upgrade to Cacti **1.2.23**, **1.3.0**, or later.
- Manual patches are available via the official GitHub security advisory for legacy versions.
### Workarounds
- Disable the `remote_agent.php` functionality if not required.
- Implement strict firewall rules to allow access to Cacti only from trusted IP addresses, bypassing the application's internal check.
- Edit the PHP configuration to restrict the headers used to determine the client IP (though patching is strongly preferred).
## Detection
- **Indicators of Compromise**:
- Unusual `POST` or `GET` requests to `remote_agent.php` containing shell metacharacters in the `poller_id` parameter.
- Presence of headers like `X-Forwarded-For` containing the IP address of the Cacti server itself in web server logs.
- **Detection Methods**: Scan for the existence of `remote_agent.php` and test for header-based bypass. Use static analysis tools (like SonarQube) to identify unsanitized `proc_open` calls.
## References
- Vendor Advisory: [https://github.com/Cacti/cacti/security/advisories/GHSA-6p93-p743-35gf](https://github.com/Cacti/cacti/security/advisories/GHSA-6p93-p743-35gf)
- SonarSource Blog: [https://www.sonarsource.com/blog/cacti-unauthenticated-remote-code-execution/](https://www.sonarsource.com/blog/cacti-unauthenticated-remote-code-execution/)
- ZDI Advisory: [https://www.zerodayinitiative.com/advisories/ZDI-23-042/](https://www.zerodayinitiative.com/advisories/ZDI-23-042/)