* Purpose: Contain all search/filtering functionality within Sagacity * Created: May 24, 2017 * * Copyright 2017: Cyber Perspective, LLC, All rights reserved * Released under the Apache v2.0 License * * See license.txt for details * * Change Log: * - May 24, 2017 - File created * - May 26, 2017 - Couple bug fixes * - Jul 13, 2017 - Fixed a couple minor display bugs * - Dec 27, 2017 - Syntax updates * - May 10, 2018 - Fixed bug #405, probably other bugs with other types * - May 31, 2018 - Bug fixes */ include_once 'config.inc'; include_once 'helper.inc'; include_once 'database.inc'; $db = new db(); $type = filter_input(INPUT_POST, 'type', FILTER_SANITIZE_STRING, FILTER_NULL_ON_FAILURE); $q = filter_input(INPUT_POST, 'q', FILTER_SANITIZE_STRING, FILTER_NULL_ON_FAILURE); $start = filter_input(INPUT_POST, 'start', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE); $len = filter_input(INPUT_POST, 'length', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE); $draw = filter_input(INPUT_POST, 'draw', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE); $filter = filter_input(INPUT_POST, 'search', FILTER_SANITIZE_STRING, FILTER_REQUIRE_ARRAY); $where = []; $op = '='; $field = null; $ret = null; if (empty($q)) { print header(JSON) . json_encode(null); die; } if (strpos($q, "%") !== false) { $op = LIKE; $q = "'$q'"; } if ($type == 'stig' || $type == 'vms' || $type == 'ia' || $type == 'nessus') { if ($type == 'stig') { $field = '`STIG_ID`'; } elseif ($type == 'vms') { $field = '`VMS_ID`'; } elseif ($type == 'ia') { $field = '`IA_Controls`'; } elseif ($type == 'nessus') { $field = '`Nessus_ID`'; } if (!is_null($field)) { $where[] = [ 'field' => $field, 'op' => $op, 'value' => $q ]; } if (!empty($filter['value'])) { $where[] = [ 'field' => 'pdi.STIG_ID', 'op' => LIKE, 'value' => "'%{$filter['value']}%'", 'open-paren' => true, 'sql_op' => 'AND' ]; $where[] = [ 'field' => 'pdi.VMS_ID', 'op' => LIKE, 'value' => "'%{$filter['value']}%'", 'sql_op' => 'OR' ]; $where[] = [ 'field' => 'pdi.IA_Controls', 'op' => LIKE, 'value' => "'%{$filter['value']}%'", 'sql_op' => 'OR' ]; $where[] = [ 'field' => 'pdi.Short_Title', 'op' => LIKE, 'value' => "'%{$filter['value']}%'", 'sql_op' => 'OR' ]; $where[] = [ 'field' => 'pdi.Description', 'op' => LIKE, 'value' => "'%{$filter['value']}%'", 'sql_op' => 'OR' ]; $where[] = [ 'field' => 'lu.check_contents', 'op' => LIKE, 'value' => "'%{$filter['value']}%'", 'sql_op' => 'OR', 'close-paren' => true ]; } $db->help->select_count("sagacity.pdi", $where, [ 'table_joins' => [ "LEFT JOIN sagacity.pdi_checklist_lookup lu ON pdi.pdi_id = lu.pdi_id", "LEFT JOIN sagacity.checklist chk ON chk.id = lu.checklist_id" ] ]); $count = $db->help->execute(); $ret = [ 'columns' => [ ['title' => 'STIG ID', 'data' => 'stig_id'], ['title' => 'VMS ID', 'data' => 'vms_id'], ['title' => 'Checklist Name', 'data' => 'name'], ['title' => 'Type', 'data' => 'type'], ['title' => 'PDI', 'data' => 'pdi_id'], ['title' => 'File Name', 'data' => 'file'] ], 'draw' => $draw, 'recordsTotal' => $count, 'recordsFiltered' => $count, 'data' => [] ]; $db->help->select("sagacity.pdi", null, $where, [ 'table_joins' => [ "LEFT JOIN sagacity.pdi_checklist_lookup lu ON pdi.pdi_id = lu.pdi_id", "LEFT JOIN sagacity.checklist chk ON chk.id = lu.checklist_id" ], 'limit' => $len, 'start' => $start ]); $rows = $db->help->execute(); if (is_array($rows) && count($rows) && isset($rows['STIG_ID'])) { $rows = [0 => $rows]; } if (is_array($rows) && count($rows) && isset($rows[0])) { foreach ($rows as $row) { $ret['data'][] = [ 'stig_id' => $row['STIG_ID'], 'vms_id' => $row['VMS_ID'], 'name' => $row['name'], 'type' => $row['type'], 'pdi_id' => $row['pdi_id'], 'file' => $row['file_name'] ]; } } } elseif ($type == 'cve') { $where[] = [ 'field' => 'db.cve_id', 'op' => $op, 'value' => $q ]; if (!empty($filter['value'])) { $where[] = [ 'field' => 'status', 'op' => LIKE, 'value' => "'%{$filter['value']}%'", 'sql_op' => 'AND', 'open-paren' => true ]; $where[] = [ 'field' => 'desc', 'op' => LIKE, 'value' => "'%{$filter['value']}%'", 'sql_op' => 'OR', 'close-paren' => true ]; } $db->help->select_count("sagacity.cve_db db", $where, [ 'table_joins' => [ "LEFT JOIN sagacity.cve ON db.cve_id = cve.cve_id" ] ]); $count = $db->help->execute(); $ret = [ 'columns' => [ ['title' => 'PDI ID', 'data' => 'pdi_id'], ['title' => 'CVE ID', 'data' => 'cve_id'], ['title' => 'Description', 'data' => 'desc'], ['title' => 'Status', 'data' => 'status'], ['title' => 'References', 'data' => 'ref'] ], 'draw' => $draw, 'recordsTotal' => $count, 'recordsFiltered' => $count, 'data' => [] ]; $db->help->select("sagacity.cve_db db", ['db.cve_id', 'cve.pdi_id', 'db.seq', 'db.status', 'db.desc'], $where, [ 'table_joins' => [ "LEFT JOIN sagacity.cve ON db.cve_id = cve.cve_id" ], 'limit' => $len, 'start' => $start ]); $rows = $db->help->execute(); if (is_array($rows) && count($rows) && isset($rows['cve_id'])) { $rows = [0 => $rows]; } if (is_array($rows) && count($rows) && isset($rows[0])) { foreach ($rows as $row) { $references = null; $db->help->select("sagacity.cve_references", ['source', 'url'], [ [ 'field' => 'cve_seq', 'op' => '=', 'value' => $row['cve_id'] ], [ 'field' => 'url', 'op' => '!=', 'value' => '', 'sql_op' => 'AND' ] ], [ 'group' => 'source' ]); $refs = $db->help->execute(); if (is_array($refs) && count($refs) && isset($refs['source'])) { $refs = [0 => $refs]; } if (is_array($refs) && count($refs) && isset($refs[0])) { foreach ($refs as $ref) { $references .= "{$ref['source']} "; } } $ret['data'][] = [ 'pdi_id' => "{$row['pdi_id']}", 'cve_id' => $row['cve_id'], 'desc' => $row['desc'], 'status' => $row['status'], 'ref' => $references ]; } } } elseif ($type == 'cpe') { $where[] = [ 'field' => 'cpe', 'op' => $op, 'value' => $q ]; if (!empty($filter['search'])) { $where[] = [ 'field' => 'cpe', 'op' => LIKE, 'value' => $filter['search'], 'sql_op' => 'OR' ]; } $db->help->select_count("sagacity.software", $where); $count = $db->help->execute(); $ret = [ 'columns' => [ ['title' => 'Man', 'data' => 'man'], ['title' => 'Name', 'data' => 'name'], ['title' => 'Ver', 'data' => 'ver'], ['title' => 'CPE', 'data' => 'cpe'], ['title' => 'String', 'data' => 'sw_string'] ], 'draw' => $draw, 'recordsTotal' => $count, 'recordsFiltered' => $count, 'data' => [] ]; $db->help->select("sagacity.software", null, $where); $rows = $db->help->execute(); if (is_array($rows) && count($rows) && isset($rows['cpe'])) { $rows = [0 => $rows]; } if (is_array($rows) && count($rows) && isset($rows[0])) { foreach ($rows as $row) { list($cpe, $type, $man, $name, $ver) = explode(":", $row['cpe']); $ret['data'][] = [ 'man' => ucwords($man), 'name' => ucwords($name), 'ver' => $ver, 'cpe' => $row['cpe'], 'sw_string' => $row['sw_string'] ]; } } } elseif ($type == 'iavm') { $where[] = [ 'field' => 'iavmNoticeNumber', 'op' => $op, 'value' => $q ]; $db->help->select_count("sagacity.iavm_notices", $where); $count = $db->help->execute(); $ret = [ 'columns' => [ ['title' => 'PDI ID', 'data' => 'pdi_id'], ['title' => 'IAVM Notice', 'data' => 'iavm'], ['title' => 'Title', 'data' => 'title'], ['title' => 'Category', 'data' => 'cat'], ['title' => 'Link', 'data' => 'link'] ], 'draw' => $draw, 'recordsTotal' => $count, 'recordsFiltered' => $count, 'data' => [] ]; $db->help->select("sagacity.iavm_notices", null, $where, [ 'order' => 'iavmNoticeNumber' ]); $rows = $db->help->execute(); if (is_array($rows) && count($rows) && isset($rows['iavmNoticeNumber'])) { $rows = [0 => $rows]; } if (is_array($rows) && count($rows) && isset($rows[0])) { foreach ($rows as $row) { $cat = implode("", array_fill(0, $row['stigFindingSeverity'], "I")); $ret['data'][] = [ 'pdi_id' => "{$row['pdi_id']}", 'iavm' => $row['iavmNoticeNumber'], 'title' => $row['title'], 'cat' => $cat, 'link' => "XML" ]; } } } else { if (strpos($q, "%") === false) { $q = "'%{$q}%'"; } $where = [ [ 'field' => 'pcl.short_title', 'op' => LIKE, 'value' => $q ], [ 'field' => 's.description', 'op' => LIKE, 'value' => $q, 'sql_op' => 'OR' ], [ 'field' => 'pcl.check_contents', 'op' => LIKE, 'value' => $q, 'sql_op' => 'OR' ] ]; if (!empty($filter['value'])) { $where[] = [ 'field' => 's.stig_id', 'op' => LIKE, 'value' => "'%{$filter['value']}%'", 'sql_op' => 'AND', 'open-paren' => true ]; $where[] = [ 'field' => 'gd.vms_id', 'op' => LIKE, 'value' => "'%{$filter['value']}%'", 'sql_op' => 'OR', 'close-paren' => true ]; } $db->help->select_count("sagacity.pdi_catalog pdi", $where, [ 'table_joins' => [ "LEFT JOIN sagacity.stigs s ON s.pdi_id=pdi.id", "LEFT JOIN sagacity.golddisk gd ON gd.pdi_id=pdi.id", "LEFT JOIN sagacity.pdi_checklist_lookup pcl ON pdi.id=pcl.pdi_id", "LEFT JOIN sagacity.checklist c ON c.id=pcl.checklist_id" ] ]); $count = $db->help->execute(); $ret = [ 'columns' => [ ['title' => 'STIG ID', 'data' => 'stig_id'], ['title' => 'VMS ID', 'data' => 'vms_id'], ['title' => 'Checklist Name', 'data' => 'name'], ['title' => 'Type', 'data' => 'type'], ['title' => 'PDI', 'data' => 'pdi_id'], ['title' => 'File Name', 'data' => 'file'] ], 'draw' => $draw, 'recordsTotal' => $count, 'recordsFiltered' => $count, 'data' => [] ]; $db->help->select("sagacity.pdi_catalog pdi", [ "pdi.id AS 'pdi_id'", "pdi.short_title AS 'Short_Title'", "s.stig_id AS 'STIG_ID'", "gd.vms_id AS 'VMS_ID'", "c.id AS 'chk_id'", "c.`name` AS 'chk_name'", "c.file_name", "c.`type`", "c.`release`", "c.`ver`" ], $where, [ 'table_joins' => [ "LEFT JOIN sagacity.stigs s ON s.pdi_id=pdi.id", "LEFT JOIN sagacity.golddisk gd ON gd.pdi_id=pdi.id", "LEFT JOIN sagacity.pdi_checklist_lookup pcl ON pdi.id=pcl.pdi_id", "LEFT JOIN sagacity.checklist c ON c.id=pcl.checklist_id" ], 'start' => $start, 'limit' => $len ]); $rows = $db->help->execute(); if (is_array($rows) && count($rows) && isset($rows['pdi_id'])) { $rows = [0 => $rows]; } if (is_array($rows) && count($rows) && isset($rows[0])) { foreach ($rows as $row) { $name = str_replace("Security Technical Implementation Guide", "STIG", $row['chk_name']); $title = "{$row['Short_Title']} (from $name)"; $file_name = basename($row['file_name']); $ret['data'][] = [ 'stig_id' => $row['STIG_ID'], 'vms_id' => $row['VMS_ID'], 'name' => "{$row['chk_name']} V{$row['ver']}R{$row['release']}", 'type' => $row['type'], 'pdi_id' => "PDI", 'file' => "" ]; } } } print header(JSON) . json_encode($ret);