lib/tasks/helpers/vulndb.rb
def query_local_nvd_json

      # Set a data directory underneath our folder if we're not in the context of core
      if $intrigue_basedir
        nvd_data_directory = "#{$intrigue_basedir}/data/nvd"
      else
        nvd_data_directory = "#{File.expand_path('data/nvd', File.dirname(__FILE__))}"
      end

      # fail unless we have something to match
      return [] unless @version

      vulns = []
      matched = []
      # TODO.. should be last 3-4 years... (dependent on memory req)
      files = [
          "#{nvd_data_directory}/nvdcve-1.0-2019.json",
          "#{nvd_data_directory}/nvdcve-1.0-2018.json",
          "#{nvd_data_directory}/nvdcve-1.0-2017.json",
          "#{nvd_data_directory}/nvdcve-1.0-2016.json"
        ]

      files.each do |file|
        #puts "DEBUG Checking file: #{f}"
        next unless File.exist? file

        # open and read the file
        f = File.open(file,"r")
        json = JSON.parse(f.read)
        # free memory
        f.close

        json["CVE_Items"].each do |v|

          # Note that the JSON has CVE stuff under a hash, so
          # pull that out separately

          # data sanity check, no affects data, no continue
          unless v["cve"]["affects"] && v["cve"]["affects"]["vendor"] && v["cve"]["affects"]["vendor"]["vendor_data"]
            next
          end

          # check to make sure it includes our vendor
          vendors = v["cve"]["affects"]["vendor"]["vendor_data"].map{|x| x["vendor_name"].downcase }
          next unless vendors.uniq.include? @vendor.downcase

          # iterate through the heirarchy to get to product and version we can match on
          v["cve"]["affects"]["vendor"]["vendor_data"].each do |vd|
            next if matched.include? v["cve"]["CVE_data_meta"]["ID"] # skip if we got it already

            vd["product"]["product_data"].each do |p|
              next if matched.include? v["cve"]["CVE_data_meta"]["ID"] # skip if we got it already

              p["version"]["version_data"].each do |vd|
                next if matched.include? v["cve"]["CVE_data_meta"]["ID"] # skip if we got it already
                next unless p["product_name"].downcase == @product.downcase
                #puts "DEBUG Matching: #{vd["version_value"]} with #{@version}"

                # first make sure we share the same major version
                next unless  vd["version_value"].split(".").first == @version.split(".").first

                # if so, check that this affects versions equal to or newer than uors
                vuln_version = ::Versionomy.parse(vd["version_value"])
                our_version = ::Versionomy.parse(@version)

                if vuln_version >= our_version
                  puts "VulnDB DEBUG - VULN MATCHED (#{v["cve"]['CVE_data_meta']['ID']}): #{Versionomy.parse(vd['version_value'])} >= #{Versionomy.parse(@version)}}!"
                  matched << v["cve"]["CVE_data_meta"]["ID"]
                  cve_id = v["cve"]["CVE_data_meta"]["ID"]
                  puts "VulnDB DEBUG - got CVE: #{cve_id}"

                  # Get the CWE if we have it
                  if v["cve"]["problemtype"] && v["cve"]["problemtype"]["problemtype_data"].first
                    cwe_id = v["cve"]["problemtype"]["problemtype_data"].first["description"].first["value"]
                    puts "VulnDB DEBUG - got CWE: #{cwe_id}"
                  end

                  # Get the CVSS data if we have it
                  if v["impact"]

                    cvss_v2 = v["impact"]["baseMetricV2"]["cvssV2"]
                    cvss_v3 = v["impact"]["baseMetricV3"]["cvssV3"]

                    cvss_v2_score = v["impact"]["baseMetricV2"]["cvssV2"]["baseScore"]
                    cvss_v2_vector = v["impact"]["baseMetricV2"]["cvssV2"]["vectorString"]

                    # v3 only goes back to 2016
                    if v["impact"]["baseMetricV3"]
                      cvss_v3_score = v["impact"]["baseMetricV3"]["cvssV3"]["baseScore"]
                      cvss_v3_vector = v["impact"]["baseMetricV3"]["cvssV3"]["vectorString"]
                    end
                  end

                  # create a hash with the vuln's data, matches "slim" export from the
                  # vulndb server  
                  vuln = {
                    cve: cve_id,
                    cwe: cwe_id,
                    cvss_v2_score: cvss_v2_score,
                    cvss_v3_score: cvss_v3_score,
                    auth: (cvss_v2 && cvss_v2["cvssV2"] ? !(cvss_v2["cvssV2"]["authentication"] == "NONE") : nil )
                  }

                  vulns << vuln
                end

              end
            end
          end
        end
      end

      #puts "DEBUG Sending #{vulns.uniq.count} vulns"
      json = nil

    vulns.uniq
    end
# hacktastic! matches vulns by CPE
hacktastic. matches vulns by CPE
hacktastic . matches vulns by CPE
def query_local_nvd_json
      if $intrigue_basedir
        nvd_data_directory = "#{$intrigue_basedir}/data/nvd"
      else
        nvd_data_directory = "#{File.expand_path('data/nvd', File.dirname(__FILE__))}"
      end
      return [] unless @version
      vulns = []
      matched = []
      files = [
          "#{nvd_data_directory}/nvdcve-1.0-2019.json",
          "#{nvd_data_directory}/nvdcve-1.0-2018.json",
          "#{nvd_data_directory}/nvdcve-1.0-2017.json",
          "#{nvd_data_directory}/nvdcve-1.0-2016.json"
        ]
      files.each do |file|
        next unless File.exist? file
        f = File.open(file,"r")
        json = JSON.parse(f.read)
        f.close
        json["CVE_Items"].each do |v|
          unless v["cve"]["affects"] && v["cve"]["affects"]["vendor"] && v["cve"]["affects"]["vendor"]["vendor_data"]
            next
          end
          vendors = v["cve"]["affects"]["vendor"]["vendor_data"].map{|x| x["vendor_name"].downcase }
          next unless vendors.uniq.include? @vendor.downcase
          v["cve"]["affects"]["vendor"]["vendor_data"].each do |vd|
            next if matched.include? v["cve"]["CVE_data_meta"]["ID"] 
            vd["product"]["product_data"].each do |p|
              next if matched.include? v["cve"]["CVE_data_meta"]["ID"] 
              p["version"]["version_data"].each do |vd|
                next if matched.include? v["cve"]["CVE_data_meta"]["ID"] 
                next unless p["product_name"].downcase == @product.downcase
                next unless  vd["version_value"].split(".").first == @version.split(".").first
                vuln_version = ::Versionomy.parse(vd["version_value"])
                our_version = ::Versionomy.parse(@version)
                if vuln_version >= our_version
                  puts "VulnDB DEBUG - VULN MATCHED (#{v["cve"]['CVE_data_meta']['ID']}): #{Versionomy.parse(vd['version_value'])} >= #{Versionomy.parse(@version)}}!"
                  matched << v["cve"]["CVE_data_meta"]["ID"]
                  cve_id = v["cve"]["CVE_data_meta"]["ID"]
                  puts "VulnDB DEBUG - got CVE: #{cve_id}"
                  if v["cve"]["problemtype"] && v["cve"]["problemtype"]["problemtype_data"].first
                    cwe_id = v["cve"]["problemtype"]["problemtype_data"].first["description"].first["value"]
                    puts "VulnDB DEBUG - got CWE: #{cwe_id}"
                  end
                  if v["impact"]
                    cvss_v2 = v["impact"]["baseMetricV2"]["cvssV2"]
                    cvss_v3 = v["impact"]["baseMetricV3"]["cvssV3"]
                    cvss_v2_score = v["impact"]["baseMetricV2"]["cvssV2"]["baseScore"]
                    cvss_v2_vector = v["impact"]["baseMetricV2"]["cvssV2"]["vectorString"]
                    if v["impact"]["baseMetricV3"]
                      cvss_v3_score = v["impact"]["baseMetricV3"]["cvssV3"]["baseScore"]
                      cvss_v3_vector = v["impact"]["baseMetricV3"]["cvssV3"]["vectorString"]
                    end
                  end
                  vuln = {
                    cve: cve_id,
                    cwe: cwe_id,
                    cvss_v2_score: cvss_v2_score,
                    cvss_v3_score: cvss_v3_score,
                    auth: (cvss_v2 && cvss_v2["cvssV2"] ? !(cvss_v2["cvssV2"]["authentication"] == "NONE") : nil )
                  }
                  vulns << vuln
                end
              end
            end
          end
        end
      end
      json = nil
    vulns.uniq
    end
def query_local_nvd_json if $intrigue_basedir nvd_data_directory = "#{$intrigue_basedir}/data/nvd" else nvd_data_directory = "#{File.expand_path('data/nvd', File.dirname(__FILE__))}" end return [ ] unless @version vulns = [ ] matched = [ ] files = [ "#{nvd_data_directory}/nvdcve-1.0-2019.json" , "#{nvd_data_directory}/nvdcve-1.0-2018.json" , "#{nvd_data_directory}/nvdcve-1.0-2017.json" , "#{nvd_data_directory}/nvdcve-1.0-2016.json" ] files . each do | file | next unless File . exist? file f = File . open ( file , "r" ) json = JSON . parse ( f . read ) f . close json [ "CVE_Items" ] . each do | v | unless v [ "cve" ] [ "affects" ] && v [ "cve" ] [ "affects" ] [ "vendor" ] && v [ "cve" ] [ "affects" ] [ "vendor" ] [ "vendor_data" ] next end vendors = v [ "cve" ] [ "affects" ] [ "vendor" ] [ "vendor_data" ] . map { | x | x [ "vendor_name" ] . downcase } next unless vendors . uniq . include? @vendor . downcase v [ "cve" ] [ "affects" ] [ "vendor" ] [ "vendor_data" ] . each do | vd | next if matched . include? v [ "cve" ] [ "CVE_data_meta" ] [ "ID" ] vd [ "product" ] [ "product_data" ] . each do | p | next if matched . include? v [ "cve" ] [ "CVE_data_meta" ] [ "ID" ] p [ "version" ] [ "version_data" ] . each do | vd | next if matched . include? v [ "cve" ] [ "CVE_data_meta" ] [ "ID" ] next unless p [ "product_name" ] . downcase == @product . downcase next unless vd [ "version_value" ] . split ( "." ) . first == @version . split ( "." ) . first vuln_version = :: Versionomy . parse ( vd [ "version_value" ] ) our_version = :: Versionomy . parse ( @version ) if vuln_version >= our_version puts "VulnDB DEBUG - VULN MATCHED (#{v["cve"]['CVE_data_meta']['ID']}): #{Versionomy.parse(vd['version_value'])} >= #{Versionomy.parse(@version)}}!" matched << v [ "cve" ] [ "CVE_data_meta" ] [ "ID" ] cve_id = v [ "cve" ] [ "CVE_data_meta" ] [ "ID" ] puts "VulnDB DEBUG - got CVE: #{cve_id}" if v [ "cve" ] [ "problemtype" ] && v [ "cve" ] [ "problemtype" ] [ "problemtype_data" ] . first cwe_id = v [ "cve" ] [ "problemtype" ] [ "problemtype_data" ] . first [ "description" ] . first [ "value" ] puts "VulnDB DEBUG - got CWE: #{cwe_id}" end if v [ "impact" ] cvss_v2 = v [ "impact" ] [ "baseMetricV2" ] [ "cvssV2" ] cvss_v3 = v [ "impact" ] [ "baseMetricV3" ] [ "cvssV3" ] cvss_v2_score = v [ "impact" ] [ "baseMetricV2" ] [ "cvssV2" ] [ "baseScore" ] cvss_v2_vector = v [ "impact" ] [ "baseMetricV2" ] [ "cvssV2" ] [ "vectorString" ] if v [ "impact" ] [ "baseMetricV3" ] cvss_v3_score = v [ "impact" ] [ "baseMetricV3" ] [ "cvssV3" ] [ "baseScore" ] cvss_v3_vector = v [ "impact" ] [ "baseMetricV3" ] [ "cvssV3" ] [ "vectorString" ] end end vuln = { cve : cve_id , cwe : cwe_id , cvss_v2_score : cvss_v2_score , cvss_v3_score : cvss_v3_score , auth : ( cvss_v2 && cvss_v2 [ "cvssV2" ] ? ! ( cvss_v2 [ "cvssV2" ] [ "authentication" ] == "NONE" ) : nil ) } vulns << vuln end end end end end end json = nil vulns . uniq end
hacktastic!
hacktastic!
# Set a data directory underneath our folder if we're not in the context of core # fail unless we have something to match # TODO.. should be last 3-4 years... (dependent on memory req) #puts "DEBUG Checking file: #{f}" # open and read the file # free memory # Note that the JSON has CVE stuff under a hash, so # pull that out separately # data sanity check, no affects data, no continue # check to make sure it includes our vendor # iterate through the heirarchy to get to product and version we can match on # skip if we got it already # skip if we got it already # skip if we got it already #puts "DEBUG Matching: #{vd["version_value"]} with #{@version}" # first make sure we share the same major version # if so, check that this affects versions equal to or newer than uors # Get the CWE if we have it # Get the CVSS data if we have it # v3 only goes back to 2016 # create a hash with the vuln's data, matches "slim" export from the # vulndb server   #puts "DEBUG Sending #{vulns.uniq.count} vulns"