Skip to content

Insecure deserialization of filter data

Moderate
netniV published GHSA-77rf-774j-6h3p Sep 5, 2023

Package

Cacti (PHP)

Affected versions

< 1.2.25

Patched versions

1.2.25, 1.3.0

Description

Summary

There are two instances of insecure deserialization in Cacti version 1.2.24. While a viable gadget chain exists in Cacti’s vendor directory (phpseclib), the necessary gadgets are not included, making them inaccessible and the insecure deserializations not exploitable.

Details

Each instance of insecure deserialization is due to using the unserialize function without sanitizing the user input. Cacti has a “safe” deserialization that attempts to sanitize the content and check for specific values before calling unserialize, but it isn’t used in these instances.

In graphs_new.php

The vulnerable code lies in graphs_new.php, specifically within the host_new_graphs_save function. The following code is taken from the beginning of the function in Cacti 1.2.10:

function host_new_graphs_save($host_id) {
        $selected_graphs_array = unserialize(stripslashes(get_nfilter_request_var('selected_graphs_array')));
        $values = array();

This function unserializes the user controlled parameter ‘selected_graphs_array’. While stripslashes is run first, this simply removes extra slashes that are needed in strings during pre-processing (e.g. &rdquo; to “). In order to reach this function, the user makes a request to graphs_new with two parameters: action=save and save_component_new_graphs, which causes the vulnerable function to be called, as shown in the two code snippets below:

switch (get_request_var('action')) {
        case 'save':
            form_save();
            break;
        case 'query_reload':
            ...
        ...
        ...
function form_save() {
	...
        ...
	...
	if (isset_request_var('save_component_new_graphs')) {
		host_new_graphs_save(get_filter_request_var('host_id'));

		header('Location: graphs_new.php?host_id=' . get_filter_request_var('host_id') . &header=false');
	}
}

In managers.php

The vulnerable code lies in managers.php, specifically within the form_actions function. The following code is extracted from the function in Cacti 1.2.10:

function form_actions() {
	global $manager_actions, $manager_notification_actions;
	
	if (isset_request_var('selected_items')) {
		if (isset_request_var('action_receivers')) {
			...
			...
			...
		} elseif (isset_request_var('action_receiver_notifications')) {
			get_filter_request_var('id');
			$selected_items = unserialize(stripslashes(get_nfilter_request_var('selected_items')));
			...
		}
	...
}

By setting the request variable action_receiver_notifications, we can control the code flow to hit the unserialize call in form_actions. In order to reach form_actions, we need to set the action variable to actions, as shown in the extracted code snippet below:

switch (get_request_var('action')) {
	case 'save':
		form_save();
		break;
	case 'actions':
		form_actions();
		break;
	...
	...
}

PoC

In graphs_new.php

To hit the vulnerable code, an authenticated user sends a POST request that looks like the following:
graphs_new_example_request
If we put an invalid object (e.g. one that is malformed or includes a class Cacti does not know about) as the value for the selected_graphs_array, we can see Cacti attempting to unserialize the payload in the logs:
graphs_new_unserialize_error
At this point, we can easily control code flow to call unserialize on an arbitrary injected object.

In managers.php

To hit the vulnerable code, an authenticated user sends a POST request that looks like the following:
managers_example_request
If we put an invalid object (e.g. one that is malformed or includes a class Cacti does not know about) as the value for the selected_graphs_array, we can see Cacti attempting to unserialize the payload in the logs:
managers_unserialize_error

At this point, we can easily control code flow to call unserialize on an arbitrary injected object.

Impact

Searching for Gadget Chains

There is one known usable gadget chain in Cacti’s PHP vendors, PHPSecLib. However, Cacti does not require or include any of the necessary php files that are needed in order to use the PHPSecLib gadget. Thus, these deserialization vulnerabilities can not be exploited in a vanilla installation of Cacti.

Severity

Moderate
4.3
/ 10

CVSS base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
Low
User interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
None
Availability
None
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N

CVE ID

CVE-2023-30534

Weaknesses

Credits