CVE-2020-12078: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') (CWE-78)
value: An issue was discovered in Open-AudIT 3.3.1. There is shell metacharacter injection via attributes to an open-audit/configuration/ URI. An attacker can exploit this by adding an excluded IP address to the global discovery settings (internally called exclude_ip). This exclude_ip value is passed to the exec function in the discoveries_helper.php file (inside the all_ip_list function) without being filtered, which means that the attacker can provide a payload instead of a valid IP address.
CWE description: The product constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component.
CVSS v3 base score: 8.8
Published: 2020-04-28T14:15Z
Repository: https://github.com/Opmantek/open-audit
Language: PHP
Files changed: code_igniter/application/helpers/discoveries_helper.php
Commit date: 2020-04-24 09:59:41 +1000
Commit message: Validate correct character for subnet and exclude_ip attributes when running a discovery.

Diff: diff --git a/code_igniter/application/helpers/discoveries_helper.php b/code_igniter/application/helpers/discoveries_helper.php
index 2a64f8da9..2ad851114 100644
--- a/code_igniter/application/helpers/discoveries_helper.php
+++ b/code_igniter/application/helpers/discoveries_helper.php
@@ -270,10 +270,17 @@ if ( ! function_exists('discover_subnet')) {
 
 		$sql = '/* discoveries_helper::discover_subnet */ ' . "UPDATE `discoveries` SET `status` = 'running', `ip_all_count` = 0, `ip_responding_count` = 0, `ip_scanned_count` = 0, `ip_discovered_count` = 0, `ip_audited_count` = 0, `last_run` = NOW() WHERE id = ?";
 		$data = array($discovery_id);
 		$CI->db->query($sql, $data);
 
+		if ( ! preg_match('/^[\d,\.,\/,\-]*$/', $discovery->attributes->other->subnet)) {
+			$log->message = 'Invalid subnet value supplied of ' . htmlentities($discovery->attributes->other->subnet);
+			$log->severity = 5;
+			discovery_log($log);
+			return;
+		}
+
 		if ( ! empty($CI->config->config['discovery_ip_exclude'])) {
 			// Account for users adding multiple spaces which would be converted to multiple comma's.
 			$exclude_ip = preg_replace('!\s+!', ' ', $CI->config->config['discovery_ip_exclude']);
 			// Convert spaces to comma's
 			$exclude_ip = str_replace(' ', ',', $exclude_ip);
@@ -281,10 +288,17 @@ if ( ! function_exists('discover_subnet')) {
 				$discovery->attributes->other->nmap->exclude_ip .= ',' . $exclude_ip;
 			} else {
 				$discovery->attributes->other->nmap->exclude_ip = $exclude_ip;
 			}
 		}
+		// Ensure we only have valid characters of digit, dot, slash and comma in attribute
+		if ( ! preg_match('/^[\d,\.,\/,\-,\,]*$/', $discovery->attributes->other->nmap->exclude_ip)) {
+			$discovery->attributes->other->nmap->exclude_ip = '';
+			$log->message = 'Invalid characters supplied in exclude_ip, setting to blank.';
+			$log->severity = 5;
+			discovery_log($log);
+		}
 
 		$all_ip_list = all_ip_list($discovery);
 
 		$count = @count($all_ip_list);
 		$log->command_status = 'notice';

Fixed code: 		if ( ! preg_match('/^[\d,\.,\/,\-]*$/', $discovery->attributes->other->subnet)) {
			$log->message = 'Invalid subnet value supplied of ' . htmlentities($discovery->attributes->other->subnet);
			$log->severity = 5;
			discovery_log($log);
			return;
		}

		// Ensure we only have valid characters of digit, dot, slash and comma in attribute
		if ( ! preg_match('/^[\d,\.,\/,\-,\,]*$/', $discovery->attributes->other->nmap->exclude_ip)) {
			$discovery->attributes->other->nmap->exclude_ip = '';
			$log->message = 'Invalid characters supplied in exclude_ip, setting to blank.';
			$log->severity = 5;
			discovery_log($log);
		}