sagacity/exec/parse_mbsa.php
2018-05-07 10:51:08 -04:00

285 lines
7.8 KiB
PHP

<?php
/**
* File: parse_mbsa.php
* Author: Ryan Prather
* Purpose: Background script to parse MBSA files
* Created: July 3, 2014
*
* Portions Copyright 2016: Cyber Perspectives, All rights reserved
* Released under the Apache v2.0 License
*
* Portions Copyright (c) 2012-2015, Salient Federal Solutions
* Portions Copyright (c) 2008-2011, Science Applications International Corporation (SAIC)
* Released under Modified BSD License
*
* See license.txt for details
*
* Change Log:
* - July 3, 2014 - File created
* - Sep 1, 2016 - Copyright Updated, added CWD parameter, and updated functions after class merger
* - Mar 4, 2017 - Removed Thread class calls
* - Jun 3, 2017 - Changed to check thread status and die if changed to TERMINATED
*/
$cmd = getopt("f:s:d:", array('debug::', 'help::'));
if (!isset($cmd['f']) || !isset($cmd['s']) || isset($cmd['help'])) {
usage();
exit;
}
include_once 'config.inc';
include_once 'helper.inc';
include_once 'database.inc';
check_path(TMP . "/mbsa");
chdir(TMP);
set_time_limit(0);
$err = new Sagacity_Error($cmd['f']);
if (!file_exists($cmd['f'])) {
$db->update_Running_Scan(basename($cmd['f']), array('name' => 'status', 'value' => 'ERROR'));
$err->script_log("File not found", E_ERROR);
}
$db = new db();
$base_name = basename($cmd['f']);
$host_list = array();
$db->update_Running_Scan($base_name, array('name' => 'pid', 'value' => getmypid()));
$src = $db->get_Sources("MBSA");
$existing_scan = $db->get_ScanData($cmd['s'], $base_name);
if (is_array($existing_scan) && count($existing_scan)) {
$scan = $existing_scan[0];
}
else {
$dt = new DateTime();
$ste = $db->get_STE($cmd['s'])[0];
$scan = new scan(null, $src, $ste, 0, $base_name, $dt->format("Y-m-d"));
$scan_id = $db->save_Scan($scan);
$scan->set_ID($scan_id);
}
if (substr($base_name, -3) == 'xml') {
$match = array();
if (preg_match('/([^\\\\]+)\-mbsa\.xml/i', $cmd['f'], $match)) {
$tgt_id = get_a_tgt_id($db, $cmd['s'], $match[1], $match[1]);
$tgt = $db->get_Target_Details($cmd['s'], $tgt_id)[0];
}
else {
$err->script_log("File name is not the correct format (hostname)-mbsa.xml required! (" . $base_name . ")", E_ERROR);
}
$host_list = array(
'target' => $tgt,
'count' => 0
);
$xml = new DOMDocument();
$xml->load($cmd['f']);
$checks = getValue($xml, "/x:XMLOut/x:Check/x:Detail/x:UpdateData", null, true);
foreach ($checks as $check) {
$db->help->select("sagacity.scans", array('status'), array(
array(
'field' => 'id',
'op' => '=',
'value' => $scan->get_ID()
)
));
$thread_status = $db->help->execute();
if ($thread_status['status'] == 'TERMINATED') {
unset($xml);
rename(realpath(TMP . "/{$scan->get_File_Name()}"), TMP . "/terminated/{$scan->get_File_Name()}");
$err->script_log("File parsing terminated by user");
die();
}
$ms = getValue($xml, "@BulletinID", $check);
$kb = getValue($xml, "@KBID", $check) ? "KB" . getValue($xml, "@KBID", $check) : "";
$installed = (getValue($xml, "@IsInstalled", $check) == 'true' ? true : false);
if ($ms) {
$adv = $db->get_Advisory($ms);
$iavm = $db->get_IAVM_From_External($ms);
if (is_null($iavm) && $kb) {
$iavm = $db->get_IAVM_From_External($kb);
}
}
elseif ($kb) {
$adv = $db->get_Advisory($kb);
$iavm = $db->get_IAVM_From_External($kb);
}
else {
$adv = null;
$iavm = null;
}
$err->script_log("$ms/$kb");
if (is_array($adv) && count($adv)) {
$adv = $adv[0];
}
if ($iavm && $iavm->get_PDI_ID()) {
$status = 'Open';
if ($installed) {
$status = 'Not a Finding';
}
$stig = $db->get_Stig($iavm->get_Notice_Number());
if (is_array($stig) && count($stig) && isset($stig[0]) && is_a($stig[0], 'stig')) {
$stig = $stig[0];
}
$err->script_log("pdi\t=\t" . $stig->get_PDI_ID() . "\tstig\t=\t" . $stig->get_ID());
$pdi = $db->get_PDI($stig->get_PDI_ID());
$vms = $db->get_GoldDisk_By_PDI($pdi->get_ID());
$ias = $db->get_IA_Controls_By_PDI($pdi->get_ID());
if (is_array($vms) && count($vms) && isset($vms[0]) && is_a($vms[0], 'stig')) {
$vms = $vms[0];
}
else {
$vms = '';
}
$finding = $db->get_Finding($tgt, $iavm, $scan);
if (!count($finding)) {
$ia_str = '';
foreach ($ias as $key => $ia):$ia_str .= $ia->get_Type() . "-" . $ia->get_Type_ID() . " ";
endforeach;
$finding = array(
0 => $stig->get_ID(),
1 => (is_a($vms, 'golddisk') ? $vms->get_ID() : $vms),
2 => $pdi->get_Category_Level_String(),
3 => $ia_str,
4 => $pdi->get_Short_Title(),
5 => $status,
6 => '(MBSA)',
7 => $pdi->get_Check_Contents(),
8 => ''
);
$host_list['count'] ++;
if (!$db->add_Finding($scan, $tgt, $finding)) {
$err->script_log("add finding failure");
}/**/
}
else {
// need to code update for MBSA
}
}
else {
$err->script_log("don't have iavm");
$cves = getValue($xml, "x:OtherIDs/x:OtherID[@Type='CVE']", $check, true);
if ($cves->length) {
foreach ($cves as $cve) {
$db_cve = $db->get_CVE($cve->textContent);
if ($db_cve) {
if (count($db_cve->get_IAVM())) {
$iavm = $db->get_IAVM($db_cve->get_IAVM()[0]);
}
break;
}
}
if ($iavm && $iavm->get_PDI_ID()) {
$err->script_log("found one");
$status = 'Open';
if ($installed) {
$status = 'Not a Finding';
}
$pdi = $db->get_PDI($iavm->get_PDI_ID());
$vms = $db->get_GoldDisk_By_PDI($pdi->get_ID());
$ias = $db->get_IA_Controls_By_PDI($pdi->get_ID());
if (is_array($vms) && count($vms)) {
$vms = $vms[0];
}
else {
$vms = '';
}
$finding = $db->get_Finding($tgt, $iavm, $scan);
if (!count($finding)) {
$ia_str = '';
foreach ($ias as $key => $ia):$ia_str .= $ia->get_Type() . "-" . $ia->get_Type_ID() . " ";
endforeach;
$finding = array(
0 => $iavm->get_Notice_Number(),
1 => (is_a($vms, 'golddisk') ? $vms->get_ID() : $vms),
2 => $pdi->get_Category_Level_String(),
3 => $ia_str,
4 => $pdi->get_Short_Title(),
5 => $status,
6 => '',
7 => $pdi->get_Check_Contents(),
8 => ''
);
$host_list['count'] ++;
if (!$db->add_Finding($scan, $tgt, $finding)) {
$err->script_log("add finding failure");
}/**/
}
else {
}
}
}
else {
$cve = $db->get_CVE_From_External(substr($kb, 2));
if ($cve && $cve->get_PDI_ID()) {
$err->script_log("found one");
$err->script_log("pdi: " . $cve->get_PDI_ID());
}
else {
$err->script_log("still don't have it");
}
}
}
}
}
elseif (substr($base_name, -3) == 'txt') {
}
$db->update_Scan_Host_List($scan, array(0 => $host_list));
if (!isset($cmd['debug'])) {
rename($cmd['f'], DOC_ROOT . "/tmp/mbsa/$base_name");
}
$db->update_Running_Scan($base_name, array('name' => 'perc_comp', 'value' => 100, 'complete' => 1));
function usage() {
print <<<EOO
Purpose: To import an MBSA result file
Usage: php parse_mbsa.php -s={ST&E ID} -f={result file} [--debug] [--help]
-s={ST&E ID} The ST&E ID this result file is being imported for
-f={result file} The result file to import
--debug Debugging output
--help This screen
EOO;
}