finding.inc - removed ID property to prevent duplicate findings from being added to the table host_list.inc - deleted unused constructor import.inc - formatting db_schema.json - removed sagacity.findings.id field (making tgt_id and pdi_id new primary keys), and updated references Database_Baseline.zip - updated routines for above change background_results.php - fixed bug #19 export-ckl.php - performance adjustments parse_excel_echecklist.php - performance improvements, ensure duplicate findings are not created, make eChecklist true status, update for removing findings.id field parse_nvd_json_cve.php - convert reading json to array instead of object for reading CPEs (which were updated to CPE 2.3 instead of 2.2) parse_* - remove findings.id field database.inc - formatting, and update for removing findings.id field index.php - ensure user can't import a host list without uploading a host list file Fixed: #65, #51, #28, #27, #10
		
			
				
	
	
		
			203 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			203 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * File: parse_nvd_json_cve
 | |
|  * Author: Ryan Prather <ryan.prather@cyberperspectives.com>
 | |
|  * 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 <<<EOF
 | |
| Purpose: To import the National Vulnerability Database (NVD) CVE JSON files
 | |
| 
 | |
| Usage: php parse_nvd_json_cve.php -f={JSON file} [-h]
 | |
| 
 | |
|  -f={JSON file}     The CVE file to import
 | |
|  -h                 This screen
 | |
| 
 | |
| EOF;
 | |
| }
 |