* 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'])); $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 = []; $new_cves = []; $new_cve_refs = []; $sw_rows = []; $new = 0; $existing = 0; $db->help->select("software", ['id', 'cpe']); $rows = $db->help->execute(); foreach ($rows as $row) { $db_cpes["{$row['cpe']}"] = $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; $type = $cve->cve->data_type; $seq = $cve->cve->CVE_data_meta->ID; $pd = new DateTime($cve->publishedDate); $lmd = new DateTime($cve->lastModifiedDate); 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) && is_array($n->cpe) && count($n->cpe)) { foreach ($n->cpe as $cpe) { if (isset($cpe->cpe22Uri)) { $cpes[] = $cpe->cpe22Uri; } elseif (isset($cpe->cpeMatchString)) { $cpes[] = $cpe->cpeMatchString; } } } } } if (count($cpes)) { foreach ($cpes as $cpe) { if (isset($db_cpes["{$cpe}"])) { $sw_rows[] = [$name, $db_cpes["{$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 <<