diff --git a/classes/cve_info.rb b/classes/cve_info.rb index 93a8d96..0d25da2 100644 --- a/classes/cve_info.rb +++ b/classes/cve_info.rb @@ -65,4 +65,4 @@ class CveReport cve = find(cve_id) cve['cve']['references']['reference_data'] end -end \ No newline at end of file +end diff --git a/classes/kenna_api_client.rb b/classes/kenna_api_client.rb index 0ee2e70..2752c6f 100644 --- a/classes/kenna_api_client.rb +++ b/classes/kenna_api_client.rb @@ -58,4 +58,4 @@ class APIClient handle_response(response) end -end \ No newline at end of file +end diff --git a/command_line/console.rb b/command_line/console.rb index 94f6697..b89be95 100755 --- a/command_line/console.rb +++ b/command_line/console.rb @@ -26,4 +26,4 @@ download_tool_methods = downloading_tools.map do |tool| list_methods(tool) end -Pry.start \ No newline at end of file +Pry.start diff --git a/kenna_kdi_importer/asset_generator.rb b/kenna_kdi_importer/asset_generator.rb new file mode 100644 index 0000000..24c7f3d --- /dev/null +++ b/kenna_kdi_importer/asset_generator.rb @@ -0,0 +1,35 @@ +require 'faker' + +module KennaKdi + class AssetGenerator + attr_accessor :cve_data_path, :vuln_generator + + def initialize(cve_data_path) + @cve_data_path = cve_data_path + @vuln_generator = KennaKdi::VulnGenerator.new(cve_data_path) + end + + def random_asset_hash + v_and_vd = random_vuln_and_vuln_def + + { + "skip_autoclose": true, + "assets":[ + { + "ip_address": Faker::Internet.ip_v4_address, + "vulns":[ + v_and_vd[:vuln] + ] + } + ], + "vuln_defs":[ + v_and_vd[:vuln_def] + ] + } + end + + def random_vuln_and_vuln_def + vuln_generator.random_vuln_and_vuln_def + end + end +end \ No newline at end of file diff --git a/kenna_kdi_importer/cve_info.rb b/kenna_kdi_importer/cve_info.rb new file mode 100644 index 0000000..0d25da2 --- /dev/null +++ b/kenna_kdi_importer/cve_info.rb @@ -0,0 +1,68 @@ +class CveReport + attr_accessor :filename, :file + # 1st way: + # expects a hash with the following key:values # {:filename => "nvdcve-1.0-2002.json.gz", + # :json => {"CVE_data_type"=>"CVE", + # "CVE_Items"= etc...etc...etc...} + # 2nd way: + # a json gz compressed file of cve metadata downloaded from nvd + # TO ADD: 1st way. + + def initialize(filename) + @filename = filename + @file = from_file + end + + def cve_ids + # return a list of cve data from the given filename in an array. + file["CVE_Items"].map do |item| + item["cve"]["CVE_data_meta"]["ID"] + end + end + + def cve_id?(cve_id) + cve_ids.include?(cve_id) + end + + def cve(cve_id) + find(cve_id) + end + + def cves + file["CVE_Items"].map do |cve| + cve + end + end + + def from_file + Zlib::GzipReader.open(filename) do |gz| + JSON.parse(gz.read) + end + end + + def find(cve_id) + result = cves.select do |cve| + cve["cve"]["CVE_data_meta"]["ID"] == cve_id + end + if result.count == 1 + result.first + else + "Could not find valid CVE for: #{cve}" + end + end + + def description(cve_id) + cve = find(cve_id) + cve['cve']['description']['description_data'].first['value'] + end + + def description_hash(cve_id) + description_value = description(cve_id) + { :cve_id => cve_id, :description => description_value } + end + + def reference_data(cve_id) + cve = find(cve_id) + cve['cve']['references']['reference_data'] + end +end diff --git a/kenna_kdi_importer/data/cve/nvdcve-1.0-2002.json.gz b/kenna_kdi_importer/data/cve/nvdcve-1.0-2002.json.gz new file mode 100644 index 0000000..2b72d83 Binary files /dev/null and b/kenna_kdi_importer/data/cve/nvdcve-1.0-2002.json.gz differ diff --git a/kenna_kdi_importer/data/cve/nvdcve-1.0-2003.json.gz b/kenna_kdi_importer/data/cve/nvdcve-1.0-2003.json.gz new file mode 100644 index 0000000..6a07c23 Binary files /dev/null and b/kenna_kdi_importer/data/cve/nvdcve-1.0-2003.json.gz differ diff --git a/kenna_kdi_importer/data/cve/nvdcve-1.0-2004.json.gz b/kenna_kdi_importer/data/cve/nvdcve-1.0-2004.json.gz new file mode 100644 index 0000000..8856d75 Binary files /dev/null and b/kenna_kdi_importer/data/cve/nvdcve-1.0-2004.json.gz differ diff --git a/kenna_kdi_importer/data/cve/nvdcve-1.0-2005.json.gz b/kenna_kdi_importer/data/cve/nvdcve-1.0-2005.json.gz new file mode 100644 index 0000000..dbdcede Binary files /dev/null and b/kenna_kdi_importer/data/cve/nvdcve-1.0-2005.json.gz differ diff --git a/kenna_kdi_importer/data/cve/nvdcve-1.0-2006.json.gz b/kenna_kdi_importer/data/cve/nvdcve-1.0-2006.json.gz new file mode 100644 index 0000000..507d79f Binary files /dev/null and b/kenna_kdi_importer/data/cve/nvdcve-1.0-2006.json.gz differ diff --git a/kenna_kdi_importer/data/cve/nvdcve-1.0-2007.json.gz b/kenna_kdi_importer/data/cve/nvdcve-1.0-2007.json.gz new file mode 100644 index 0000000..83cfdd5 Binary files /dev/null and b/kenna_kdi_importer/data/cve/nvdcve-1.0-2007.json.gz differ diff --git a/kenna_kdi_importer/data/cve/nvdcve-1.0-2008.json.gz b/kenna_kdi_importer/data/cve/nvdcve-1.0-2008.json.gz new file mode 100644 index 0000000..5ede362 Binary files /dev/null and b/kenna_kdi_importer/data/cve/nvdcve-1.0-2008.json.gz differ diff --git a/kenna_kdi_importer/data/cve/nvdcve-1.0-2009.json.gz b/kenna_kdi_importer/data/cve/nvdcve-1.0-2009.json.gz new file mode 100644 index 0000000..7670bfc Binary files /dev/null and b/kenna_kdi_importer/data/cve/nvdcve-1.0-2009.json.gz differ diff --git a/kenna_kdi_importer/data/cve/nvdcve-1.0-2010.json.gz b/kenna_kdi_importer/data/cve/nvdcve-1.0-2010.json.gz new file mode 100644 index 0000000..cfb5e68 Binary files /dev/null and b/kenna_kdi_importer/data/cve/nvdcve-1.0-2010.json.gz differ diff --git a/kenna_kdi_importer/data/cve/nvdcve-1.0-2011.json.gz b/kenna_kdi_importer/data/cve/nvdcve-1.0-2011.json.gz new file mode 100644 index 0000000..78f51ae Binary files /dev/null and b/kenna_kdi_importer/data/cve/nvdcve-1.0-2011.json.gz differ diff --git a/kenna_kdi_importer/data/cve/nvdcve-1.0-2012.json.gz b/kenna_kdi_importer/data/cve/nvdcve-1.0-2012.json.gz new file mode 100644 index 0000000..49ffe1d Binary files /dev/null and b/kenna_kdi_importer/data/cve/nvdcve-1.0-2012.json.gz differ diff --git a/kenna_kdi_importer/data/cve/nvdcve-1.0-2013.json.gz b/kenna_kdi_importer/data/cve/nvdcve-1.0-2013.json.gz new file mode 100644 index 0000000..5b814d9 Binary files /dev/null and b/kenna_kdi_importer/data/cve/nvdcve-1.0-2013.json.gz differ diff --git a/kenna_kdi_importer/data/cve/nvdcve-1.0-2014.json.gz b/kenna_kdi_importer/data/cve/nvdcve-1.0-2014.json.gz new file mode 100644 index 0000000..de94d5f Binary files /dev/null and b/kenna_kdi_importer/data/cve/nvdcve-1.0-2014.json.gz differ diff --git a/kenna_kdi_importer/data/cve/nvdcve-1.0-2015.json.gz b/kenna_kdi_importer/data/cve/nvdcve-1.0-2015.json.gz new file mode 100644 index 0000000..25bd8e9 Binary files /dev/null and b/kenna_kdi_importer/data/cve/nvdcve-1.0-2015.json.gz differ diff --git a/kenna_kdi_importer/data/cve/nvdcve-1.0-2016.json.gz b/kenna_kdi_importer/data/cve/nvdcve-1.0-2016.json.gz new file mode 100644 index 0000000..65e7485 Binary files /dev/null and b/kenna_kdi_importer/data/cve/nvdcve-1.0-2016.json.gz differ diff --git a/kenna_kdi_importer/data/cve/nvdcve-1.0-2017.json.gz b/kenna_kdi_importer/data/cve/nvdcve-1.0-2017.json.gz new file mode 100644 index 0000000..82e2b2e Binary files /dev/null and b/kenna_kdi_importer/data/cve/nvdcve-1.0-2017.json.gz differ diff --git a/kenna_kdi_importer/data/cve/nvdcve-1.0-2018.json.gz b/kenna_kdi_importer/data/cve/nvdcve-1.0-2018.json.gz new file mode 100644 index 0000000..246ddb4 Binary files /dev/null and b/kenna_kdi_importer/data/cve/nvdcve-1.0-2018.json.gz differ diff --git a/kenna_kdi_importer/data/cve/nvdcve-1.0-2019.json.gz b/kenna_kdi_importer/data/cve/nvdcve-1.0-2019.json.gz new file mode 100644 index 0000000..19698b3 Binary files /dev/null and b/kenna_kdi_importer/data/cve/nvdcve-1.0-2019.json.gz differ diff --git a/kenna_kdi_importer/data/cve/nvdcve-1.0-modified.json.gz b/kenna_kdi_importer/data/cve/nvdcve-1.0-modified.json.gz new file mode 100644 index 0000000..43d9b47 Binary files /dev/null and b/kenna_kdi_importer/data/cve/nvdcve-1.0-modified.json.gz differ diff --git a/kenna_kdi_importer/data/cve/nvdcve-1.0-recent.json.gz b/kenna_kdi_importer/data/cve/nvdcve-1.0-recent.json.gz new file mode 100644 index 0000000..9a2e26f Binary files /dev/null and b/kenna_kdi_importer/data/cve/nvdcve-1.0-recent.json.gz differ diff --git a/kenna_kdi_importer/kdi_jsonify.rb b/kenna_kdi_importer/kdi_jsonify.rb new file mode 100644 index 0000000..f8a9918 --- /dev/null +++ b/kenna_kdi_importer/kdi_jsonify.rb @@ -0,0 +1,129 @@ +require 'json' + +module KennaKdi + class KdiJsonify + def initialize + end + + def default_hash + # from https://help.kennasecurity.com/hc/en-us/articles/360026413111-Kenna-Data-Importer-JSON-Connector- + <<~HEREDOC + { + "skip_autoclose": boolean, + "assets":[ * + { + "file": string, + (At least one of the fields with a + is required for each asset.) + "ip_address": string, + (See help center or support for locator order set for your instance) + "mac_address": string, + + "hostname": string, + + "ec2": string, + + "netbios": string, + + "external_ip_address": string, + + "url": string, + + "fqdn": string, + + "external_id": string, + + "database": string, + + "application": string, (This field should be used as a meta data field with url or file) + "tags": [ + string (Multiple tags should be listed and separated by commas) + ], + "owner": string, + "os": string, (although not required, it is strongly recommended to populate this field when available) + "os_version": string, + "priority": integer, (defaults to 10, between 0 and 10 but default is recommended unless you have a documented risk appetite for assets) + "vulns":[ * (If an asset contains no open vulns, this can be an empty array, but to avoid vulnerabilities from being closed, use the skip-autoclose flag) + { + "scanner_identifier": string, * (each unique scanner identifier will need a corresponding entry in the vuln-defs section below, this typically should be the external identifier used by your scanner) + "scanner_type": string, * (required) + "scanner_score": integer (between 0 and 10), + "override_score": integer (between 0 and 100), + "created_at": string, (iso8601 timestamp - defaults to current date if not provided) + "last_seen_at": string, * (iso8601 timestamp) + "last_fixed_on": string, (iso8601 timestamp) + "closed_at": string, ** (required with closed status - This field used with status may be provided on remediated vulns to indicate they're closed, or vulns that are already present in Kenna but absent from this data load, for any specific asset, will be closed via our autoclose logic) + "status": string, * (required - valid values open, closed, false_positive, risk_accepted) + "port": integer, + } + ] + } + ], + "vuln_defs":[ (This section is required for mapping findings from various scanners into canonical CVE or CWE vulnerabilities in Kenna.) + { + "scanner_identifier": string, * (entry for each scanner identifier that appears in the vulns section, this typically should be the external identifier used by your scanner) + "scanner_type": string, * (matches entry in vulns section) + "cve_identifiers": string, (note that this can be a comma-delimited list format CVE-000-0000) + "wasc_identifiers": string, (note that this can be a comma-delimited list - format WASC-00) + "cwe_identifiers": string, (note that this can be a comma-delimited list - format CWE-000) + "name": string, (title or short name of the vuln, will be auto-generated if not set) + "description": string, (full description of the vuln) + "solution": string, (steps or links for remediation teams) + } + ] + } + HEREDOC + end + + def example_hash + { + "skip_autoclose": true, + "assets":[ + { + "ip_address": "172.31.42.121", + "ec2": "i-02aadcccfda719968", + "tags": ["AWS"], + "priority": 0, + "vulns":[ + { + "scanner_identifier": "aws-vuln-id-1", + "scanner_type": "AWS Inspector", + "created_at": "2018-11-10-18:08:57", + "last_seen_at": "2018-11-10-18:08:57", + "status": "open" + }, + { + "scanner_identifier": "aws-vuln-id-2", + "scanner_type": "AWS Inspector", + "created_at": "2018-11-10-18:08:57", + "last_seen_at": "2018-11-10-18:08:57", + "status": "open" + }, + { + "scanner_identifier": "aws-vuln-id-3", + "details": "some details about how CVE-2018-10853 and CVE-2018-18074 are impacting asset", + "scanner_type": "AWS Inspector", + "created_at": "2018-11-10-18:08:57", + "last_seen_at": "2018-11-10-18:08:57", + "status": "open" + } + ] + } + ], + "vuln_defs":[ + { + "scanner_identifier": "aws-vuln-id-1", + "scanner_type": "AWS Inspector", + "cve_identifiers": "CVE-2018-17456", + "name": "Name of vulnerability involving CVE-2018-17456", + "description": "Description of vuln involving CVE-2018-17456", + "solution": "Do something good to fix CVE-2018-17456" + }, + { + "scanner_identifier": "aws-vuln-id-2", + "scanner_type": "AWS Inspector", + "cve_identifiers": "CVE-2018-6555", + "name": "Name of vulnerability involving CVE-2018-6555", + "description": "Description of vuln involving CVE-2018-6555", + "solution": "Do something good to fix CVE-2018-6555" + }, + { + "scanner_identifier": "aws-vuln-id-3", + "scanner_type": "AWS Inspector", + "name": "Name of vulnerability involving CVE-2018-10853, CVE-2018-18074", + "description": "Description of vuln involving CVE-2018-10853, CVE-2018-18074", + "cve_identifiers": "CVE-2018-10853, CVE-2018-18074" + } + ] + } + end + end +end \ No newline at end of file diff --git a/kenna_kdi_importer/kenna_kdi_importer.rb b/kenna_kdi_importer/kenna_kdi_importer.rb new file mode 100644 index 0000000..9a2bdba --- /dev/null +++ b/kenna_kdi_importer/kenna_kdi_importer.rb @@ -0,0 +1,4 @@ +require './asset_generator' +require './vuln_generator' +require './cve_info' +require './kdi_jsonify' diff --git a/kenna_kdi_importer/vuln_generator.rb b/kenna_kdi_importer/vuln_generator.rb new file mode 100644 index 0000000..3c443e6 --- /dev/null +++ b/kenna_kdi_importer/vuln_generator.rb @@ -0,0 +1,47 @@ +module KennaKdi + class VulnGenerator + attr_accessor :cve_data_path, :cve_data + + def initialize(cve_data_path) + # path to a directory of json.gz nvd files for CveReport class + @cve_data_path = cve_data_path + @cve_data = random_cve_report + end + + def random_vuln_and_vuln_def + # spit out a pair of vuln/vuln_def hashes + scanner_id = Faker::Code.nric + t = Time.new + timestamp = t.strftime("%Y-%m-%d %H:%M:%S") + + + id = cve_data.cve_ids.sample + cve = cve_data.cve(id) + description = cve_data.description(id) + + { + "vuln": { + "scanner_identifier": scanner_id, + "scanner_type": "KDI Faker Data", + "created_at": timestamp, + "last_seen_at": timestamp, + "status": "open" + }, + "vuln_def": { + "scanner_identifier": scanner_id, + "scanner_type": "KDI Faker Data", + "cve_identifiers": id, + "name": "#{scanner_id} - #{id}", + "description": description + } + } + end + + private + + def random_cve_report + cve_files = Dir.glob(File.join(cve_data_path, '**', '*')).select{|file| File.file?(file)} + CveReport.new(cve_files.sample) + end + end +end \ No newline at end of file diff --git a/modules/nvd_tools.rb b/modules/nvd_tools.rb index f839688..5a22758 100644 --- a/modules/nvd_tools.rb +++ b/modules/nvd_tools.rb @@ -1,2 +1,2 @@ module NvdTools -end \ No newline at end of file +end