big commit with lots of tools and cve data too

This commit is contained in:
Brendan McDevitt 2019-07-22 01:49:12 -05:00
parent 0ef45ebe5d
commit 2563cc2ce4
29 changed files with 287 additions and 4 deletions

View file

@ -65,4 +65,4 @@ class CveReport
cve = find(cve_id) cve = find(cve_id)
cve['cve']['references']['reference_data'] cve['cve']['references']['reference_data']
end end
end end

View file

@ -58,4 +58,4 @@ class APIClient
handle_response(response) handle_response(response)
end end
end end

View file

@ -26,4 +26,4 @@ download_tool_methods = downloading_tools.map do |tool|
list_methods(tool) list_methods(tool)
end end
Pry.start Pry.start

View file

@ -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

View file

@ -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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -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

View file

@ -0,0 +1,4 @@
require './asset_generator'
require './vuln_generator'
require './cve_info'
require './kdi_jsonify'

View file

@ -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

View file

@ -1,2 +1,2 @@
module NvdTools module NvdTools
end end