From 98ea166a224c43c9b8fb3eb40751648bd9652405 Mon Sep 17 00:00:00 2001 From: Ryan Prather Date: Wed, 17 Oct 2018 22:19:41 -0400 Subject: [PATCH] Fix for #10, #57, & #58 --- exec/parse_scc_xccdf.php | 1172 ++++++++++++++++++++------------------ inc/database.inc | 2 +- inc/helper.inc | 2 +- 3 files changed, 610 insertions(+), 566 deletions(-) diff --git a/exec/parse_scc_xccdf.php b/exec/parse_scc_xccdf.php index 004ed73..eea21f9 100644 --- a/exec/parse_scc_xccdf.php +++ b/exec/parse_scc_xccdf.php @@ -24,643 +24,687 @@ * - May 13, 2017 - Fixed error when trying to delete a USGCB scan file (not supported) * - Oct 23, 2017 - Fixed error of finding statuses being overwritten */ -$cmd = getopt("f:", ['debug::', 'help::']); +$cmd = getopt("f:", [ + 'debug::', + 'help::' +]); -if (!isset($cmd['f']) || isset($cmd['help'])) { - die(usage()); +if (! isset($cmd['f']) || isset($cmd['help'])) { + die(usage()); } $conf = parse_ini_file("parse_config.ini"); -if (!$conf) { - die("Could not find parse_config.ini configuration file"); +if (! $conf) { + die("Could not find parse_config.ini configuration file"); } chdir($conf['doc_root']); set_time_limit(0); +require_once 'vendor/autoload.php'; include_once 'config.inc'; include_once 'xml_parser.inc'; include_once 'database.inc'; include_once 'helper.inc'; +use Monolog\Logger; +use Monolog\Handler\StreamHandler; + chdir(TMP); $db = new db(); +$log_level = convert_log_level(); + $base_name = basename($cmd['f']); -$host_list = array(); -$err = new Sagacity_Error($cmd['f']); +$log = new Logger("scc-import"); +$log->pushHandler(new StreamHandler(logify($cmd['f']), $log_level)); -if (!file_exists($cmd['f'])) { - $db->update_Running_Scan($base_name, ['name' => 'status', 'value' => 'ERROR']); - $err->script_log("File not found", E_ERROR); -} -elseif (preg_match('/.*Results\_iavm\_(2009|2010)|Results\_USGCB/i', $cmd['f'])) { - $scan = $db->get_ScanData($conf['ste'], $cmd['f']); - if (is_array($scan) && count($scan) && isset($scan[0]) && is_a($scan[0], 'scan')) { - $db->delete_Scan($scan[0]->get_ID(), false); - } - $err->script_log("Cannot parse these types of files", E_ERROR); +if (! file_exists($cmd['f'])) { + $db->update_Running_Scan($base_name, [ + 'name' => 'status', + 'value' => 'ERROR' + ]); + $log->error("File not found"); + die(); +} elseif (preg_match('/.*Results\_iavm\_(2009|2010)|Results\_USGCB/i', $cmd['f'])) { + $scan = $db->get_ScanData($conf['ste'], $cmd['f']); + if (is_array($scan) && count($scan) && isset($scan[0]) && is_a($scan[0], 'scan')) { + $db->delete_Scan($scan[0]->get_ID(), false); + } + $log->error("Cannot parse these types of files"); + die(); } -class scc_parser extends scan_xml_parser { +class scc_parser extends scan_xml_parser +{ - var $values; - var $value_id; - var $getvalue = false; - var $groups; - var $group_id; - var $vms_id; - var $vms = null; - var $sv_rule; - var $tgt; - var $tag; - var $int_count = 0; - var $found_rule = false; + var $values; - /** - * Constructor - * - * @param int $ste_id_in - * @param string $fname_in - */ - public function __construct($ste_id_in, $fname_in) { - $this->values = array(); - $this->groups = array(); - $this->tag = array(); - parent::__construct($this, $ste_id_in, $fname_in); - $this->db->update_Running_Scan($this->scan->get_File_Name(), ['name' => 'pid', 'value' => getmypid()]); - } + var $value_id; - /** - * Function to parse \cdf:Benchmark\cdf:Value tag - * - * @param array $attrs - */ - public function cdf_Benchmark_cdf_Value($attrs) { - $this->values[$attrs['id']] = null; - $this->value_id = $attrs['id']; - } + var $getvalue = false; - /** - * Function to parse \cdf:Benchmark\cdf:Value\cdf:value tag - * - * @param array $attrs - */ - public function cdf_Benchmark_cdf_Value_cdf_value($attrs) { - if (!isset($attrs['selector'])) { - $this->getvalue = true; - } - else { - $this->getvalue = false; - } - } + var $groups; - /** - * Function to parse \cdf:Benchmark\cdf:value\cdf:value character data - * - * @param string $data - */ - public function cdf_Benchmark_cdf_Value_cdf_value_data($data) { - if ($this->getvalue) { - $this->values[$this->value_id] = $data; - } - } + var $group_id; - /** - * Function to parse \cdf:Benchmark\cdf:Group tag - * - * @param array $attrs - */ - public function cdf_Benchmark_cdf_Group($attrs) { - $this->vms = $this->db->get_GoldDisk($attrs['id']); + var $vms_id; - if (is_array($this->vms) && count($this->vms) && isset($this->vms[0]) && is_a($this->vms[0], 'golddisk')) { - $this->group_id = $this->vms[0]->get_PDI_ID(); - } - else { - $this->group_id = $attrs['id']; - $this->vms = null; + var $vms = null; + + var $sv_rule; + + var $tgt; + + var $tag; + + var $int_count = 0; + + var $found_rule = false; + + var $log = null; + + /** + * Constructor + * + * @global Monolog\Logger $log + * + * @param int $ste_id_in + * @param string $fname_in + */ + public function __construct($ste_id_in, $fname_in) + { + $this->values = []; + $this->groups = []; + $this->tag = []; + parent::__construct($this, $ste_id_in, $fname_in); + $this->db->update_Running_Scan($this->scan->get_File_Name(), [ + 'name' => 'pid', + 'value' => getmypid() + ]); } - $this->vms_id = $attrs['id']; - $this->groups[$this->group_id] = array(); - $this->found_rule = false; - } - - /** - * Function to parse \cdf:Benchmark\cdf:Group\cdf:Rule tag - * - * @param array $attrs - */ - public function cdf_Benchmark_cdf_Group_cdf_Rule($attrs) { - $sv_rule = $this->db->get_SV_Rule(null, $attrs['id']); - - if (is_array($sv_rule) && count($sv_rule) && isset($sv_rule[0]) && is_a($sv_rule[0], 'sv_rule')) { - $this->found_rule = true; - $this->sv_rule = $sv_rule[0]; - - unset($this->groups[$this->group_id]); - $this->group_id = $this->sv_rule->get_PDI_ID(); - - $this->groups[$this->group_id] = [ - 'sv_rule' => $this->sv_rule, - 'stig' => null, - 'version' => null, - 'title' => null, - 'vms_id' => $this->vms_id, - 'oval_id' => null, - 'val_id' => null, - 'value' => null, - 'cce' => null, - 'fix' => null, - 'desc' => null, - 'status' => "Not Reviewed", - 'cat' => 2 - ]; - } - else { - return; + /** + * Function to parse \cdf:Benchmark\cdf:Value tag + * + * @param array $attrs + */ + public function cdf_Benchmark_cdf_Value($attrs) + { + $this->values[$attrs['id']] = null; + $this->value_id = $attrs['id']; } - $stig = $this->db->get_STIG_By_PDI($this->sv_rule->get_PDI_ID()); - - if (is_a($stig, 'stig')) { - $this->groups[$this->group_id]['stig'] = $stig; - $this->groups[$this->group_id]['version'] = $stig->get_ID(); - } - } - - /** - * Function to parse \cdf:Benchmark\cdf:Group\cdf:Rule\cdf:version character data (STIG id) - * - * @param string $data - */ - public function cdf_Benchmark_cdf_Group_cdf_Rule_cdf_version_data($data) { - $stig = $this->db->get_Stig($data); - if (is_array($stig) && count($stig) && isset($stig[0]) && is_a($stig[0], 'stig')) { - $this->found_rule = true; - $stig = $stig[0]; - - unset($this->groups[$this->group_id]); - $this->group_id = $stig->get_PDI_ID(); - - $this->groups[$this->group_id] = [ - 'sv_rule' => (is_a($this->sv_rule, 'sv_rule') ? $this->sv_rule : null), - 'stig' => $stig, - 'version' => $stig->get_ID(), - 'title' => null, - 'vms_id' => $this->vms_id, - 'oval_id' => null, - 'val_id' => null, - 'value' => null, - 'cce' => null, - 'fix' => null, - 'desc' => null, - 'status' => "Not Reviewed", - 'cat' => 2 - ]; - } - } - - /** - * Function to parse \cdf:Benchmark\cdf:Group\cdf:Rule\cdf:title character data (short title) - * - * @param string $data - */ - public function cdf_Benchmark_cdf_Group_cdf_Rule_cdf_title_data($data) { - if (empty($this->groups[$this->group_id]['title'])) { - $this->groups[$this->group_id]['title'] = $data; - } - else { - //error_log(print_r($this->group_id, true)); - } - } - - /** - * Function to parse \cdf:Benchmark\cdf:Group\cdf:Rule\cdf:description character data (description) - * - * @param string $data - */ - public function cdf_Benchmark_cdf_Group_cdf_Rule_cdf_description_data($data) { - if (!isset($this->groups[$this->group_id])) { - $this->groups[$this->group_id] = array(); + /** + * Function to parse \cdf:Benchmark\cdf:Value\cdf:value tag + * + * @param array $attrs + */ + public function cdf_Benchmark_cdf_Value_cdf_value($attrs) + { + $this->getvalue = false; + if (! isset($attrs['selector'])) { + $this->getvalue = true; + } } - if (isset($this->groups[$this->group_id]['desc'])) { - $this->groups[$this->group_id]['desc'] .= $data; - } - else { - $this->groups[$this->group_id]['desc'] = $data; - } - } - - /** - * Function to parse \cdf:Benchmark\cdf:Group\cdf:Rule\cdf:ident character data (CCI,CCE,etc) - * - * @param string $data - */ - public function cdf_Benchmark_cdf_Group_cdf_Rule_cdf_ident_data($data) { - if (empty($this->groups[$this->group_id]['cce']) && preg_match("/CCE/", $data)) { - $this->groups[$this->group_id]['cce'] = $data; - } - } - - /** - * Function to parse \cdf:Benchmark\cdf:Group\cdf:Rule\cdf:fixtext character data - * - * @param string $data - */ - public function cdf_Benchmark_cdf_Group_cdf_Rule_cdf_fixtext_data($data) { - if (empty($this->groups[$this->group_id]['fix'])) { - $this->groups[$this->group_id]['fix'] = htmlentities($data); - } - } - - /** - * Function to parse \cdf:Benchmark\cdf:Group\cdf:Rule\cdf:check\cdf:check-export tag - * - * @param array $attrs - */ - public function cdf_Benchmark_cdf_Group_cdf_Rule_cdf_check_cdf_check_export($attrs) { - if (empty($this->groups[$this->group_id]['val_id'])) { - $this->groups[$this->group_id]['val_id'] = $attrs['value-id']; - $this->groups[$this->group_id]['value'] = $this->values[$attrs['value-id']]; - - $this->groups[$this->group_id]['oval_id'] = $attrs['export-name']; - } - } - - /** - * Function to parse \cdf:Benchmark\cdf:Group end tag and store content parsed from previous functions - */ - public function cdf_Benchmark_cdf_Group_end() { - if (!$this->found_rule) { - $this->log->script_log("Rule tag was not present for " . $this->group_id); - unset($this->groups[$this->group_id]); - return; + /** + * Function to parse \cdf:Benchmark\cdf:value\cdf:value character data + * + * @param string $data + */ + public function cdf_Benchmark_cdf_Value_cdf_value_data($data) + { + if ($this->getvalue) { + $this->values[$this->value_id] = $data; + } } - if (empty($this->groups[$this->group_id]['stig'])) { - $ia_controls = array(); - $this->log->script_log("STIG ID " . $this->groups[$this->group_id]['version'] . " is not in the database, adding", E_WARNING); - $pdi = new pdi(null, '', 'NOW'); - $pdi->set_Short_Title($this->groups[$this->group_id]['title']); - $pdi->set_Group_Title($this->groups[$this->group_id]['title']); - $pdi->set_Description($this->groups[$this->group_id]['desc']); - $pdi_id = $this->db->save_PDI($pdi); - $stig = new stig($pdi_id, $this->groups[$this->group_id]['version'], $this->groups[$this->group_id]['title']); - $this->db->add_Stig($stig); - $this->groups[$this->group_id]['stig'] = $stig; + /** + * Function to parse \cdf:Benchmark\cdf:Group tag + * + * @param array $attrs + */ + public function cdf_Benchmark_cdf_Group($attrs) + { + $this->vms = $this->db->get_GoldDisk($attrs['id']); - if (!empty($this->groups[$this->group_id]['desc'])) { - $match = array(); - if (preg_match("/\(.*)\<\/IAControls\>/", $this->groups[$this->group_id]['desc'], $match)) { - $ias = explode(", ", $match[1]); - if (is_array($ias) && count($ias)) { - foreach ($ias as $ia) { - $ia_controls[] = new ia_control($pdi_id, substr($ia, 0, 4), substr($ia, -1)); + if (is_array($this->vms) && count($this->vms) && isset($this->vms[0]) && is_a($this->vms[0], 'golddisk')) { + $this->group_id = $this->vms[0]->get_PDI_ID(); + } else { + $this->group_id = $attrs['id']; + $this->vms = null; + } + + $this->vms_id = $attrs['id']; + $this->groups[$this->group_id] = array(); + $this->found_rule = false; + } + + /** + * Function to parse \cdf:Benchmark\cdf:Group\cdf:Rule tag + * + * @param array $attrs + */ + public function cdf_Benchmark_cdf_Group_cdf_Rule($attrs) + { + $sv_rule = $this->db->get_SV_Rule(null, $attrs['id']); + + if (is_array($sv_rule) && count($sv_rule) && isset($sv_rule[0]) && is_a($sv_rule[0], 'sv_rule')) { + $this->found_rule = true; + $this->sv_rule = $sv_rule[0]; + + unset($this->groups[$this->group_id]); + $this->group_id = $this->sv_rule->get_PDI_ID(); + + $this->groups[$this->group_id] = [ + 'sv_rule' => $this->sv_rule, + 'stig' => null, + 'version' => null, + 'title' => null, + 'vms_id' => $this->vms_id, + 'oval_id' => null, + 'val_id' => null, + 'value' => null, + 'cce' => null, + 'fix' => null, + 'desc' => null, + 'status' => "Not Reviewed", + 'cat' => 2 + ]; + } else { + return; + } + + $stig = $this->db->get_STIG_By_PDI($this->sv_rule->get_PDI_ID()); + + if (is_a($stig, 'stig')) { + $this->groups[$this->group_id]['stig'] = $stig; + $this->groups[$this->group_id]['version'] = $stig->get_ID(); + } + } + + /** + * Function to parse \cdf:Benchmark\cdf:Group\cdf:Rule\cdf:version character data (STIG id) + * + * @param string $data + */ + public function cdf_Benchmark_cdf_Group_cdf_Rule_cdf_version_data($data) + { + $stig = $this->db->get_Stig($data); + if (is_array($stig) && count($stig) && isset($stig[0]) && is_a($stig[0], 'stig')) { + $this->found_rule = true; + $stig = $stig[0]; + + unset($this->groups[$this->group_id]); + $this->group_id = $stig->get_PDI_ID(); + + $this->groups[$this->group_id] = [ + 'sv_rule' => (is_a($this->sv_rule, 'sv_rule') ? $this->sv_rule : null), + 'stig' => $stig, + 'version' => $stig->get_ID(), + 'title' => null, + 'vms_id' => $this->vms_id, + 'oval_id' => null, + 'val_id' => null, + 'value' => null, + 'cce' => null, + 'fix' => null, + 'desc' => null, + 'status' => "Not Reviewed", + 'cat' => 2 + ]; + } + } + + /** + * Function to parse \cdf:Benchmark\cdf:Group\cdf:Rule\cdf:title character data (short title) + * + * @param string $data + */ + public function cdf_Benchmark_cdf_Group_cdf_Rule_cdf_title_data($data) + { + if (empty($this->groups[$this->group_id]['title'])) { + $this->groups[$this->group_id]['title'] = $data; + } else { + // error_log(print_r($this->group_id, true)); + } + } + + /** + * Function to parse \cdf:Benchmark\cdf:Group\cdf:Rule\cdf:description character data (description) + * + * @param string $data + */ + public function cdf_Benchmark_cdf_Group_cdf_Rule_cdf_description_data($data) + { + if (! isset($this->groups[$this->group_id])) { + $this->groups[$this->group_id] = []; + } + + if (isset($this->groups[$this->group_id]['desc'])) { + $this->groups[$this->group_id]['desc'] .= $data; + } else { + $this->groups[$this->group_id]['desc'] = $data; + } + } + + /** + * Function to parse \cdf:Benchmark\cdf:Group\cdf:Rule\cdf:ident character data (CCI,CCE,etc) + * + * @param string $data + */ + public function cdf_Benchmark_cdf_Group_cdf_Rule_cdf_ident_data($data) + { + if (empty($this->groups[$this->group_id]['cce']) && preg_match("/CCE/", $data)) { + $this->groups[$this->group_id]['cce'] = $data; + } + } + + /** + * Function to parse \cdf:Benchmark\cdf:Group\cdf:Rule\cdf:fixtext character data + * + * @param string $data + */ + public function cdf_Benchmark_cdf_Group_cdf_Rule_cdf_fixtext_data($data) + { + if (empty($this->groups[$this->group_id]['fix'])) { + $this->groups[$this->group_id]['fix'] = htmlentities($data); + } + } + + /** + * Function to parse \cdf:Benchmark\cdf:Group\cdf:Rule\cdf:check\cdf:check-export tag + * + * @param array $attrs + */ + public function cdf_Benchmark_cdf_Group_cdf_Rule_cdf_check_cdf_check_export($attrs) + { + if (empty($this->groups[$this->group_id]['val_id'])) { + $this->groups[$this->group_id]['val_id'] = $attrs['value-id']; + $this->groups[$this->group_id]['value'] = $this->values[$attrs['value-id']]; + + $this->groups[$this->group_id]['oval_id'] = $attrs['export-name']; + } + } + + /** + * Function to parse \cdf:Benchmark\cdf:Group end tag and store content parsed from previous functions + */ + public function cdf_Benchmark_cdf_Group_end() + { + if (! $this->found_rule) { + $this->log->script_log("Rule tag was not present for " . $this->group_id); + unset($this->groups[$this->group_id]); + return; + } + + if (empty($this->groups[$this->group_id]['stig'])) { + $ia_controls = []; + $this->log->script_log("STIG ID " . $this->groups[$this->group_id]['version'] . " is not in the database, adding", E_WARNING); + $pdi = new pdi(null, '', 'NOW'); + $pdi->set_Short_Title($this->groups[$this->group_id]['title']); + $pdi->set_Group_Title($this->groups[$this->group_id]['title']); + $pdi->set_Description($this->groups[$this->group_id]['desc']); + $pdi_id = $this->db->save_PDI($pdi); + $stig = new stig($pdi_id, $this->groups[$this->group_id]['version'], $this->groups[$this->group_id]['title']); + $this->db->add_Stig($stig); + $this->groups[$this->group_id]['stig'] = $stig; + + if (! empty($this->groups[$this->group_id]['desc'])) { + $match = array(); + if (preg_match("/\(.*)\<\/IAControls\>/", $this->groups[$this->group_id]['desc'], $match)) { + $ias = explode(", ", $match[1]); + if (is_array($ias) && count($ias)) { + foreach ($ias as $ia) { + $ia_controls[] = new ia_control($pdi_id, substr($ia, 0, 4), substr($ia, - 1)); + } + } else { + $ia_controls[] = new ia_control($pdi_id, "ECSC", 1); + } + } + } else { + $ia_controls[] = new ia_control($pdi_id, 'ECSC', 1); } - } - else { - $ia_controls[] = new ia_control($pdi_id, "ECSC", 1); - } - } - } - else { - $ia_controls[] = new ia_control($pdi_id, 'ECSC', 1); - } - $this->db->save_IA_Control($ia_controls); - } - - if (empty($this->vms)) { - $this->vms = new golddisk($this->groups[$this->group_id]['stig']->get_PDI_ID(), $this->vms_id, $this->groups[$this->group_id]['title']); - $this->db->save_GoldDisk($this->vms); - } - } - - /** - * Function to parse \cdf:Benchmark\cdf:TestResult\cdf:target-facts\cdf:fact tag - * - * @param array $attrs - */ - public function cdf_Benchmark_cdf_TestResult_cdf_target_facts_cdf_fact($attrs) { - $tmp = explode(":", $attrs['name']); - $this->tag_id = end($tmp); - if (isset($this->tag[$this->tag_id])) { - if ($this->tag_id == 'interface_name') { - $this->int_count++; - } - $this->tag_id .= $this->int_count; - } - } - - /** - * Function to parse \cdf:Benchmark\cdf:TestResult\cdf:target-facts\cdf:fact character data - * - * @param string $data - */ - public function cdf_Benchmark_cdf_TestResult_cdf_target_facts_cdf_fact_data($data) { - $this->tag[$this->tag_id] = str_replace("\n", "", $data); - } - - /** - * Function to parse \cdf:Benchmark\cdf:TestResult\cdf:target-facts end tag and store results - */ - public function cdf_Benchmark_cdf_TestResult_cdf_target_facts_end() { - //error_log(print_r($this->tag, true)); - $host_name = $this->tag['host_name']; - if (preg_match("/\./", $host_name)) { - $host_name = preg_replace("/^([^\.]+)\./i", "$1", $host_name); - } - - if (!($tgt_id = $this->db->check_Target($this->ste_id, $host_name))) { - $this->log->script_log("Creating new target with hostname $host_name", E_DEBUG); - $os = array(); - if (isset($this->tag['os_name']) && isset($this->tag['os_version']) && is_numeric($this->tag['os_version'])) { - $this->tag['os_name'] .= " {$this->tag['os_version']}"; - } - - if (isset($this->tag['os_name'])) { - $os_regex = $this->db->get_Regex_Array("os"); - $os = software::identify_Software($os_regex, $this->tag['os_name']); - $os = $this->db->get_Software($os); - } - - $this->log->script_log("Identified OS " . print_r($os, true), E_DEBUG); - - if (is_array($os) && count($os) && isset($os[0]) && is_a($os[0], 'software')) { - $os = $os[0]; - } - else { - $os = $this->db->get_Software("cpe:/o:generic:generic:-")[0]; - } - - if (!is_a($os, 'software')) { - $this->log->script_log("Failed to identify the OS", E_ERROR); - } - - $tgt = new target($host_name); - $tgt->set_STE_ID($this->ste_id); - $tgt->set_Notes("New target found by SCC"); - - if (is_a($os, "software")) { - $this->log->script_log("Assigning OS {$os->get_CPE()}", E_DEBUG); - - $tgt->set_OS_ID($os->get_ID()); - $tgt->set_OS_String($os->get_Shortened_SW_String()); - } - - $tgt_id = $this->db->save_Target($tgt); - } - - $this->tgt = $this->db->get_Target_Details($this->ste_id, $tgt_id)[0]; - - $int_keys = preg_grep("/interface_name/", array_keys($this->tag)); - $match = array(); - foreach ($int_keys as $key) { - $idx = ''; - if (preg_match("/interface_name(\d+)/", $key, $match)) { - $idx = $match[1]; - } - - if (isset($this->tag["ipv4$idx"])) { - $ip = explode(",", $this->tag["ipv4$idx"]); - - $ipv4 = null; - $ipv6 = null; - - if (is_array($ip) && count($ip) == 1) { - if (preg_match("/\d+\./", $ip[0])) { - $ipv4 = $ip[0]; - } - elseif (preg_match("/[a-f0-9]+/", $ip[0])) { - $ipv6 = $ip[0]; - } - } - elseif (is_array($ip) && count($ip) == 2) { - $ipv4 = $ip[0]; - $ipv6 = $ip[1]; + $this->db->save_IA_Control($ia_controls); } - if ($ipv4) { - $int = new interfaces(null, $tgt_id, $this->tag["interface_name$idx"], $ipv4, null, (isset($this->tag['host_name']) ? $this->tag['host_name'] : ""), (isset($this->tag['fqdn']) ? $this->tag['fqdn'] : ""), null); - if (isset($this->tag["mac$idx"])) { - $int->set_MAC($this->tag["mac$idx"]); - } - $this->db->save_Interface($int); + if (empty($this->vms)) { + $this->vms = new golddisk($this->groups[$this->group_id]['stig']->get_PDI_ID(), $this->vms_id, $this->groups[$this->group_id]['title']); + $this->db->save_GoldDisk($this->vms); + } + } + + /** + * Function to parse \cdf:Benchmark\cdf:TestResult\cdf:target-facts\cdf:fact tag + * + * @param array $attrs + */ + public function cdf_Benchmark_cdf_TestResult_cdf_target_facts_cdf_fact($attrs) + { + $tmp = explode(":", $attrs['name']); + $this->tag_id = end($tmp); + if (isset($this->tag[$this->tag_id])) { + if ($this->tag_id == 'interface_name') { + $this->int_count ++; + } + $this->tag_id .= $this->int_count; + } + } + + /** + * Function to parse \cdf:Benchmark\cdf:TestResult\cdf:target-facts\cdf:fact character data + * + * @param string $data + */ + public function cdf_Benchmark_cdf_TestResult_cdf_target_facts_cdf_fact_data($data) + { + $this->tag[$this->tag_id] = str_replace("\n", "", $data); + } + + /** + * Function to parse \cdf:Benchmark\cdf:TestResult\cdf:target-facts end tag and store results + */ + public function cdf_Benchmark_cdf_TestResult_cdf_target_facts_end() + { + // error_log(print_r($this->tag, true)); + $host_name = $this->tag['host_name']; + if (preg_match("/\./", $host_name)) { + $host_name = preg_replace("/^([^\.]+)\./i", "$1", $host_name); } - if ($ipv6) { - $int = new interfaces(null, $tgt_id, $this->tag["interface_name$idx"], null, $ipv6, (isset($this->tag['host_name']) ? $this->tag['host_name'] : ""), (isset($this->tag['fqdn']) ? $this->tag['fqdn'] : ""), null); - if (isset($this->tag["mac$idx"])) { - $int->set_MAC($this->tag["mac$idx"]); - } - $this->db->save_Interface($int); - } - } - } - } + if (! ($tgt_id = $this->db->check_Target($this->ste_id, $host_name))) { + $this->log->script_log("Creating new target with hostname $host_name", E_DEBUG); + $os = array(); + if (isset($this->tag['os_name']) && isset($this->tag['os_version']) && is_numeric($this->tag['os_version'])) { + $this->tag['os_name'] .= " {$this->tag['os_version']}"; + } - /** - * Function to parse \cdf:Benchmark\cdf:TestResult\cdf:platform tag (stores CPE) - * - * @param array $attrs - */ - public function cdf_Benchmark_cdf_TestResult_cdf_platform($attrs) { - if (isset($attrs['idref']) && substr($attrs['idref'], 0, 3) == 'cpe') { - $cpe = $attrs['idref']; + if (isset($this->tag['os_name'])) { + $os_regex = $this->db->get_Regex_Array("os"); + $os = software::identify_Software($os_regex, $this->tag['os_name']); + $os = $this->db->get_Software($os); + } - $sw = $this->db->get_Software($cpe); + $this->log->script_log("Identified OS " . print_r($os, true), E_DEBUG); - if (is_array($sw) && count($sw) && is_a($this->tgt, 'target')) { - $sw = $sw[0]; - if ($sw->is_OS() && $this->tgt->get_OS_ID() != $sw->get_ID()) { - $this->log->script_log("Update OS " . $sw->get_CPE()); - $this->tgt->set_OS_ID($sw->get_ID()); - $this->tgt->set_OS_String($sw->get_Shortened_SW_String()); - } - elseif (!$sw->is_OS() && !in_array($sw, $this->tgt->software)) { - $this->log->script_log("Assigning software " . $sw->get_CPE()); - $this->tgt->software[] = $sw; - } - } + if (is_array($os) && count($os) && isset($os[0]) && is_a($os[0], 'software')) { + $os = $os[0]; + } else { + $os = $this->db->get_Software("cpe:/o:generic:generic:-")[0]; + } - $this->db->save_Target($this->tgt); - } - } + if (! is_a($os, 'software')) { + $this->log->script_log("Failed to identify the OS", E_ERROR); + } - /** - * Function to parse \cdf:Benchmark\cdf:TestResult\cdf:rule-result tag - * - * @param array $attrs - */ - public function cdf_Benchmark_cdf_TestResult_cdf_rule_result($attrs) { - $stig = $this->db->get_Stig($attrs['version']); - $sv_rule = $this->db->get_SV_Rule(null, $attrs['idref']); + $tgt = new target($host_name); + $tgt->set_STE_ID($this->ste_id); + $tgt->set_Notes("New target found by SCC"); - $this->log->script_log("Version: {$attrs['version']}", E_DEBUG); - $this->log->script_log("STIG data: " . print_r($stig, true), E_DEBUG); + if (is_a($os, "software")) { + $this->log->script_log("Assigning OS {$os->get_CPE()}", E_DEBUG); - if (is_array($stig) && count($stig) && isset($stig[0]) && is_a($stig[0], 'stig')) { - $stig = $stig[0]; - $this->group_id = $stig->get_PDI_ID(); - } - elseif (is_array($sv_rule) && count($sv_rule) && isset($sv_rule[0]) && is_a($sv_rule[0], 'sv_rule') && !$this->group_id) { - $sv_rule = $sv_rule[0]; - $this->group_id = $sv_rule->get_PDI_ID(); - } - else { - $this->log->script_log("Cannot find PDI ID (" . $attrs['version'] . "/" . $attrs['idref'] . ") CREATING", E_WARNING); + $tgt->set_OS_ID($os->get_ID()); + $tgt->set_OS_String($os->get_Shortened_SW_String()); + } - $this->group_id = null; - - return; - /* - $level = 1; - if ($attrs['severity'] == 'medium') { - $level = 2; - } - elseif ($attrs['severity'] == 'low') { - $level = 3; - } - $pdi = new pdi(null, $level, new DateTime); - $pdi_id = $this->db->save_PDI($pdi); - - $this->group_id = $pdi_id; - - if (!empty($attrs['version'])) { - $stig = new stig($pdi_id, $attrs['version'], null, null); - $this->db->add_Stig($stig); + $tgt_id = $this->db->save_Target($tgt); } - if (!empty($attrs['idref'])) { - $sv_rule = new sv_rule($pdi_id, $attrs['idref']); - $this->db->save_SV_Rule($sv_rule); + $this->tgt = $this->db->get_Target_Details($this->ste_id, $tgt_id)[0]; + + $int_keys = preg_grep("/interface_name/", array_keys($this->tag)); + $match = []; + foreach ($int_keys as $key) { + $idx = ''; + if (preg_match("/interface_name(\d+)/", $key, $match)) { + $idx = $match[1]; + } + + if (isset($this->tag["ipv4$idx"])) { + $ip = explode(",", $this->tag["ipv4$idx"]); + + $ipv4 = null; + $ipv6 = null; + + if (is_array($ip) && count($ip) == 1) { + if (preg_match("/\d+\./", $ip[0])) { + $ipv4 = $ip[0]; + } elseif (preg_match("/[a-f0-9]+/", $ip[0])) { + $ipv6 = $ip[0]; + } + } elseif (is_array($ip) && count($ip) == 2) { + $ipv4 = $ip[0]; + $ipv6 = $ip[1]; + } + + if ($ipv4) { + $int = new interfaces(null, $tgt_id, $this->tag["interface_name$idx"], $ipv4, null, (isset($this->tag['host_name']) ? $this->tag['host_name'] : ""), (isset($this->tag['fqdn']) ? $this->tag['fqdn'] : ""), null); + if (isset($this->tag["mac$idx"])) { + $int->set_MAC($this->tag["mac$idx"]); + } + $this->db->save_Interface($int); + } + + if ($ipv6) { + $int = new interfaces(null, $tgt_id, $this->tag["interface_name$idx"], null, $ipv6, (isset($this->tag['host_name']) ? $this->tag['host_name'] : ""), (isset($this->tag['fqdn']) ? $this->tag['fqdn'] : ""), null); + if (isset($this->tag["mac$idx"])) { + $int->set_MAC($this->tag["mac$idx"]); + } + $this->db->save_Interface($int); + } + } + } + } + + /** + * Function to parse \cdf:Benchmark\cdf:TestResult\cdf:platform tag (stores CPE) + * + * @param array $attrs + */ + public function cdf_Benchmark_cdf_TestResult_cdf_platform($attrs) + { + if (isset($attrs['idref']) && substr($attrs['idref'], 0, 3) == 'cpe') { + $cpe = $attrs['idref']; + + $sw = $this->db->get_Software($cpe); + + if (is_array($sw) && count($sw) && is_a($this->tgt, 'target')) { + $sw = $sw[0]; + if ($sw->is_OS() && $this->tgt->get_OS_ID() != $sw->get_ID()) { + $this->log->script_log("Update OS " . $sw->get_CPE()); + $this->tgt->set_OS_ID($sw->get_ID()); + $this->tgt->set_OS_String($sw->get_Shortened_SW_String()); + } elseif (! $sw->is_OS() && ! in_array($sw, $this->tgt->software)) { + $this->log->script_log("Assigning software " . $sw->get_CPE()); + $this->tgt->software[] = $sw; + } + } + + $this->db->save_Target($this->tgt); + } + } + + /** + * Function to parse \cdf:Benchmark\cdf:TestResult\cdf:rule-result tag + * + * @param array $attrs + */ + public function cdf_Benchmark_cdf_TestResult_cdf_rule_result($attrs) + { + $stig = $this->db->get_Stig($attrs['version']); + $sv_rule = $this->db->get_SV_Rule(null, $attrs['idref']); + + $this->log->script_log("Version: {$attrs['version']}", E_DEBUG); + $this->log->script_log("STIG data: " . print_r($stig, true), E_DEBUG); + + if (is_array($stig) && count($stig) && isset($stig[0]) && is_a($stig[0], 'stig')) { + $stig = $stig[0]; + $this->group_id = $stig->get_PDI_ID(); + } elseif (is_array($sv_rule) && count($sv_rule) && isset($sv_rule[0]) && is_a($sv_rule[0], 'sv_rule') && ! $this->group_id) { + $sv_rule = $sv_rule[0]; + $this->group_id = $sv_rule->get_PDI_ID(); + } else { + $this->log->script_log("Cannot find PDI ID (" . $attrs['version'] . "/" . $attrs['idref'] . ") CREATING", E_WARNING); + + $this->group_id = null; + + return; + /* + * $level = 1; + * if ($attrs['severity'] == 'medium') { + * $level = 2; + * } + * elseif ($attrs['severity'] == 'low') { + * $level = 3; + * } + * $pdi = new pdi(null, $level, new DateTime); + * $pdi_id = $this->db->save_PDI($pdi); + * + * $this->group_id = $pdi_id; + * + * if (!empty($attrs['version'])) { + * $stig = new stig($pdi_id, $attrs['version'], null, null); + * $this->db->add_Stig($stig); + * } + * + * if (!empty($attrs['idref'])) { + * $sv_rule = new sv_rule($pdi_id, $attrs['idref']); + * $this->db->save_SV_Rule($sv_rule); + * } + * + * return; + */ } - return; - */ - } - - if (empty($this->groups[$this->group_id]['sv_rule']) && is_a($sv_rule, "sv_rule")) { - $this->groups[$this->group_id]['sv_rule'] = $sv_rule; - } - - if (empty($this->groups[$this->group_id]['stig']) && is_a($stig, "stig")) { - $this->groups[$this->group_id]['stig'] = $stig; - } - - if (isset($attrs['severity'])) { - switch ($attrs['severity']) { - case 'low': - $this->groups[$this->group_id]['cat'] = 3; - break; - case 'high': - $this->groups[$this->group_id]['cat'] = 1; - break; - } - } - } - - /** - * Function to parse \cdf:Benchmark\cdf:TestResult\cdf:rule-result\cdf:result character data - * - * @param string $data - */ - public function cdf_Benchmark_cdf_TestResult_cdf_rule_result_cdf_result_data($data) { - if (preg_match("/pass|true/i", $data)) { - $this->groups[$this->group_id]['status'] = "Not a Finding"; - } - elseif (preg_match("/fail|false/i", $data)) { - $this->groups[$this->group_id]['status'] = "Open"; - } - - $this->log->script_log("{$this->group_id} {$this->groups[$this->group_id]['status']}", E_DEBUG); - } - - /** - * Function to parse \cdf:Benchmark\cdf:TestResult\cdf:rule-result\cdf:ident character data - * - * @param string $data - */ - public function cdf_Benchmark_cdf_TestResult_cdf_rule_result_cdf_ident_data($data) { - - } - - /** - * Function to parse \cdf:Benchmark\cdf:TestResult end tag and store all results - */ - public function cdf_Benchmark_cdf_TestResult_end() { - $new_findings = []; - $update_findings = []; - foreach ($this->groups as $pdi_id => $group) { - if (!empty($group['val_id'])) { - $note = "(SCC) " . $group['val_id'] . "\nRequired: " . $group['value'] . "\nActual: " . $this->values[$group['val_id']]; - } - else { - $note = "(SCC) "; - } - - if (isset($group['stig']) && is_a($group['stig'], 'stig')) { - $ref = $group['stig']; - } - elseif (!empty($group['vms_id'])) { - $vms = $this->db->get_GoldDisk($group['vms_id']); - if (is_array($vms) && count($vms) && isset($vms[0]) && is_a($vms[0], 'golddisk')) { - $ref = $vms[0]; + if (empty($this->groups[$this->group_id]['sv_rule']) && is_a($sv_rule, "sv_rule")) { + $this->groups[$this->group_id]['sv_rule'] = $sv_rule; } - } - elseif (isset($group['sv_rule']) && is_a($group['sv_rule'], 'sv_rule')) { - $ref = $group['sv_rule']; - } - else { - $this->log->script_log("Error finding reference to search for PDI $pdi_id\n" . print_r($group, true), E_WARNING); - continue; - } - $existing_finding = $this->db->get_Finding($this->tgt, $ref); - if (is_array($existing_finding) && count($existing_finding) && isset($existing_finding[0])) { - $finding = $existing_finding[0]; + if (empty($this->groups[$this->group_id]['stig']) && is_a($stig, "stig")) { + $this->groups[$this->group_id]['stig'] = $stig; + } - $finding->set_Finding_Status_By_String( - $finding->get_Deconflicted_Status($group['status']) - ); - $finding->prepend_Notes($note); - - $update_findings[$finding->get_PDI_ID()] = $finding; - } - else { - $new_findings[$pdi_id] = new finding(null, $this->tgt->get_ID(), $pdi_id, $this->scan->get_ID(), $group['status'], $note, finding::NC, null, 1); - } + if (isset($attrs['severity'])) { + switch ($attrs['severity']) { + case 'low': + $this->groups[$this->group_id]['cat'] = 3; + break; + case 'high': + $this->groups[$this->group_id]['cat'] = 1; + break; + } + } } - $this->db->add_Findings_By_Target($update_findings, $new_findings); + /** + * Function to parse \cdf:Benchmark\cdf:TestResult\cdf:rule-result\cdf:result character data + * + * @param string $data + */ + public function cdf_Benchmark_cdf_TestResult_cdf_rule_result_cdf_result_data($data) + { + if (preg_match("/pass|true/i", $data)) { + $this->groups[$this->group_id]['status'] = "Not a Finding"; + } elseif (preg_match("/fail|false/i", $data)) { + $this->groups[$this->group_id]['status'] = "Open"; + } - $hl = new host_list(); - $hl->setTargetId($this->tgt->get_ID()); - $hl->setTargetName($this->tgt->get_Name()); - $hl->setFindingCount(count($new_findings) + count($update_findings)); - $hl->setScanError(false); + $this->log->script_log("{$this->group_id} {$this->groups[$this->group_id]['status']}", E_DEBUG); + } - $this->scan->add_Target_to_Host_List($hl); - } + /** + * Function to parse \cdf:Benchmark\cdf:TestResult\cdf:rule-result\cdf:ident character data + * + * @param string $data + */ + public function cdf_Benchmark_cdf_TestResult_cdf_rule_result_cdf_ident_data($data) + {} + /** + * Function to parse \cdf:Benchmark\cdf:TestResult end tag and store all results + */ + public function cdf_Benchmark_cdf_TestResult_end() + { + $new_findings = []; + $update_findings = []; + $existing_findings = $this->db->get_Finding($this->tgt); + foreach ($this->groups as $pdi_id => $group) { + if (! empty($group['val_id'])) { + $note = "(SCC) " . $group['val_id'] . "\nRequired: " . $group['value'] . "\nActual: " . $this->values[$group['val_id']]; + } else { + $note = "(SCC) "; + } + + /* + if (isset($group['stig']) && is_a($group['stig'], 'stig')) { + $ref = $group['stig']; + } elseif (! empty($group['vms_id'])) { + $vms = $this->db->get_GoldDisk($group['vms_id']); + if (is_array($vms) && count($vms) && isset($vms[0]) && is_a($vms[0], 'golddisk')) { + $ref = $vms[0]; + } + } elseif (isset($group['sv_rule']) && is_a($group['sv_rule'], 'sv_rule')) { + $ref = $group['sv_rule']; + } else { + $this->log->script_log("Error finding reference to search for PDI $pdi_id\n" . print_r($group, true), E_WARNING); + continue; + } + */ + + if (is_array($existing_findings) && count($existing_findings) && isset($existing_findings[$pdi_id])) { + /** + * @var finding $finding + */ + $finding = $existing_findings[$pdi_id]; + + $finding->set_Finding_Status_By_String($finding->get_Deconflicted_Status($group['status'])); + if(preg_match("/" . preg_quote($note, "/") . "/", $finding->get_Notes())) { + $finding->set_Notes($note); + } else { + $finding->prepend_Notes($note); + } + + $update_findings[$pdi_id] = $finding; + } else { + $new_findings[$pdi_id] = new finding(null, $this->tgt->get_ID(), $pdi_id, $this->scan->get_ID(), $group['status'], $note, finding::NC, null, 1); + } + } + + $this->db->add_Findings_By_Target($update_findings, $new_findings); + + $hl = new host_list(); + $hl->setTargetId($this->tgt->get_ID()); + $hl->setTargetName($this->tgt->get_Name()); + $hl->setFindingCount(count($new_findings) + count($update_findings)); + $hl->setScanError(false); + + $this->db->update_Target_Counts($this->tgt->get_ID()); + + $this->scan->add_Target_to_Host_List($hl); + } } $xml = new scc_parser($conf['ste'], $cmd['f']); $xml->debug = (isset($cmd['debug']) ? true : false); $xml->parse(); -if (!$xml->debug) { - rename($cmd['f'], TMP . "/scc/" . $base_name); +if (! $xml->debug) { + rename($cmd['f'], TMP . "/scc/" . $base_name); } -$db->update_Running_Scan($base_name, ["name" => "perc_comp", "value" => 100, "complete" => 1]); +$db->update_Running_Scan($base_name, [ + "name" => "perc_comp", + "value" => 100, + "complete" => 1 +]); -function usage() { - print <<get_PDI_ID()] = $find; } } diff --git a/inc/helper.inc b/inc/helper.inc index 42419b0..6cbd4bc 100644 --- a/inc/helper.inc +++ b/inc/helper.inc @@ -831,7 +831,7 @@ function logify($fname) touch(LOG_PATH . "/{$fname}.log"); } - return LOG_PATH . "/{$fname}.log"; + return realpath(LOG_PATH . "/{$fname}.log"); } /**