* Purpose: * Created: Apr 29, 2018 * * Copyright 2018: Cyber Perspective, LLC, All rights reserved * Released under the Apache v2.0 License * * See license.txt for details * * Change Log: * - Apr 29, 2018 - File created * - May 10, 2018 - Formatting and fixed performance issue on Windows (bug #403) * - Jun 5, 2018 - Fix for bug #425 */ include_once 'config.inc'; include_once 'helper.inc'; include_once 'database.inc'; include_once 'vendor/autoload.php'; use Monolog\Logger; use Monolog\Handler\StreamHandler; use Monolog\Formatter\LineFormatter; ini_set('memory_limit', '2G'); $cmd = getopt("f:"); if (!isset($cmd['f']) || isset($cmd['h'])) { die(usage()); } $log_level = Logger::ERROR; switch (LOG_LEVEL) { case E_WARNING: $log_level = Logger::WARNING; break; case E_NOTICE: $log_level = Logger::NOTICE; break; case E_DEBUG: $log_level = Logger::DEBUG; break; } $log = new Logger("nvd_cve"); $log->pushHandler(new StreamHandler(LOG_PATH . "/nvd_cve.log", $log_level)); $db = new db(); $json = json_decode(file_get_contents($cmd['f']), true); $existing_cves = []; $db->help->select("cve_db", ['cve_id']); $cves = $db->help->execute(); if (is_array($cves) && count($cves)) { foreach ($cves as $cve) { $existing_cves["{$cve['cve_id']}"] = 1; } } print "Currently " . count($existing_cves) . " in DB" . PHP_EOL . "Parsing: " . count($json['CVE_Items']) . " items" . PHP_EOL; $db_cpes = []; $db_cpes23 = []; $new_cves = []; $new_cve_refs = []; $sw_rows = []; $new = 0; $existing = 0; $db->help->select("software", ['id', 'cpe', 'cpe23']); $rows = $db->help->execute(); foreach ($rows as $row) { $db_cpes["{$row['cpe']}"] = $row['id']; $db_cpes23["{$row['cpe23']}"] = $row['id']; } $cve_fields = [ 'cve_id', 'seq', 'status', 'phase', 'phase_date', 'desc' ]; $ref_fields = [ 'cve_seq', 'source', 'url', 'val' ]; foreach ($json['CVE_Items'] as $cve) { if (!isset($existing_cves["{$cve['cve']['CVE_data_meta']['ID']}"])) { $log->debug("Adding {$cve['cve']['CVE_data_meta']['ID']}"); $new++; $desc = []; $status = null; $phase = null; $cpes = []; $name = $cve['cve']['CVE_data_meta']['ID']; $seq = $cve['cve']['CVE_data_meta']['ID']; $pd = new DateTime($cve['publishedDate']); if (is_array($cve['cve']['description']['description_data']) && count($cve['cve']['description']['description_data'])) { foreach ($cve['cve']['description']['description_data'] as $d) { $desc[] = $d['value']; } } $new_cves[] = [ $name, $seq, $status, $phase, $pd, implode(PHP_EOL, $desc) ]; if (is_array($cve['cve']['references']['reference_data']) && count($cve['cve']['references']['reference_data'])) { foreach ($cve['cve']['references']['reference_data'] as $ref) { $log->debug("Adding reference {$ref['url']}"); $new_cve_refs[] = [ $name, null, $ref['url'], null ]; } } if(is_array($cve['configurations']['nodes']) && count($cve['configurations']['nodes'])) { foreach($cve['configurations']['nodes'] as $n) { if(isset($n['cpe_match']) && is_array($n['cpe_match']) && count($n['cpe_match'])) { foreach($n['cpe_match'] as $c) { if($c['vulnerable'] && $c['cpe23Uri']) { $cpes[] = $c['cpe23Uri']; } } } } } if (count($cpes)) { foreach ($cpes as $cpe) { if (isset($db_cpes["{$cpe}"])) { $sw_rows[] = [$name, $db_cpes["{$cpe}"]]; } elseif (isset($db_cpes23["{$cpe}"])) { $sw_rows[] = [$name, $db_cpes23["{$cpe}"]]; } } } print "*"; } else { $existing++; print "."; } if (($new + $existing) % 100 == 0) { if (count($new_cves)) { $db->help->extended_insert("cve_db", $cve_fields, $new_cves, true); $db->help->execute(); } if (count($new_cve_refs)) { $db->help->extended_insert("cve_references", $ref_fields, $new_cve_refs, true); $db->help->execute(); } if (count($sw_rows)) { $db->help->extended_insert("cve_sw_lookup", ['cve_id', 'sw_id'], $sw_rows, true); $db->help->execute(); } $new_cves = []; $new_cve_refs = []; $sw_rows = []; print "\t" . ($existing + $new) . " completed" . PHP_EOL; } } if (count($new_cves)) { $db->help->extended_insert("cve_db", $cve_fields, $new_cves, true); $db->help->execute(); } if (count($new_cve_refs)) { $db->help->extended_insert("cve_references", $ref_fields, $new_cve_refs, true); $db->help->execute(); } if (count($sw_rows)) { $db->help->extended_insert("cve_sw_lookup", ['cve_id', 'sw_id'], $sw_rows, true); $db->help->execute(); } //unlink($cmd['f']); print PHP_EOL; function usage() { print <<