class HeimdallTools::NiktoMapper
Public Class Methods
new(nikto_json, _name = nil)
click to toggle source
# File lib/heimdall_tools/nikto_mapper.rb, line 29 def initialize(nikto_json, _name = nil) @nikto_json = nikto_json begin @nikto_nist_mapping = parse_mapper rescue StandardError => e raise "Invalid Nikto to NIST mapping file: Exception: #{e}" end # TODO: Support Multi-target scan results # Nikto multi-target scans generate invalid format JSONs # Possible workaround to use https://stackoverflow.com/a/58209963/1670307 begin @project = JSON.parse(nikto_json) rescue StandardError => e raise "Invalid Nikto JSON file provided\nNote: nikto_mapper does not support multi-target scan results\n\nException: #{e}" end end
Public Instance Methods
collapse_duplicates(controls)
click to toggle source
Nikto report could have multiple vulnerability entries for multiple findings of same issue type. The meta data is identical across entries method collapse_duplicates
return unique controls with applicable findings collapsed into it.
# File lib/heimdall_tools/nikto_mapper.rb, line 96 def collapse_duplicates(controls) unique_controls = [] controls.map { |x| x['id'] }.uniq.each do |id| collapsed_results = controls.select { |x| x['id'].eql?(id) }.map { |x| x['results'] } unique_control = controls.find { |x| x['id'].eql?(id) } unique_control['results'] = collapsed_results.flatten unique_controls << unique_control end unique_controls end
extract_scaninfo(project)
click to toggle source
# File lib/heimdall_tools/nikto_mapper.rb, line 49 def extract_scaninfo(project) info = {} begin info['policy'] = 'Nikto Website Scanner' info['version'] = NA_STRING info['projectName'] = "Host: #{project['host']} Port: #{project['port']}" info['summary'] = "Banner: #{project['banner']}" info rescue StandardError => e raise "Error extracting project info from nikto JSON file provided Exception: #{e}" end end
finding(vulnerability)
click to toggle source
# File lib/heimdall_tools/nikto_mapper.rb, line 63 def finding(vulnerability) finding = {} finding['status'] = 'failed' finding['code_desc'] = "URL : #{vulnerability['url']} Method: #{vulnerability['method']}" finding['run_time'] = NA_FLOAT finding['start_time'] = NA_STRING [finding] end
impact(severity)
click to toggle source
# File lib/heimdall_tools/nikto_mapper.rb, line 78 def impact(severity) IMPACT_MAPPING[severity.to_sym] end
nist_tag(niktoid)
click to toggle source
# File lib/heimdall_tools/nikto_mapper.rb, line 72 def nist_tag(niktoid) entries = @nikto_nist_mapping.select { |x| niktoid.eql?(x[:niktoid].to_s) && !x[:nistid].nil? } tags = entries.map { |x| x[:nistid] } tags.empty? ? DEFAULT_NIST_TAG : tags.flatten.uniq end
parse_mapper()
click to toggle source
# File lib/heimdall_tools/nikto_mapper.rb, line 82 def parse_mapper csv_data = CSV.read(NIKTO_NIST_MAPPING_FILE, **{ encoding: 'UTF-8', headers: true, header_converters: :symbol }) csv_data.map(&:to_hash) end
to_hdf()
click to toggle source
# File lib/heimdall_tools/nikto_mapper.rb, line 108 def to_hdf controls = [] @project['vulnerabilities'].each do |vulnerability| printf("\rProcessing: %s", $spinner.next) item = {} item['tags'] = {} item['descriptions'] = [] item['refs'] = NA_ARRAY item['source_location'] = NA_HASH item['descriptions'] = NA_ARRAY item['title'] = vulnerability['msg'].to_s item['id'] = vulnerability['id'].to_s # Nikto results JSON does not description fields # Duplicating vulnerability msg field item['desc'] = vulnerability['msg'].to_s # Nitko does not provide finding severity; hard-coding severity to medium item['impact'] = impact('medium') item['code'] = NA_STRING item['results'] = finding(vulnerability) item['tags']['nist'] = nist_tag(vulnerability['id'].to_s) item['tags']['ösvdb'] = vulnerability['OSVDB'] controls << item end controls = collapse_duplicates(controls) scaninfo = extract_scaninfo(@project) results = HeimdallDataFormat.new(profile_name: scaninfo['policy'], version: scaninfo['version'], title: "Nikto Target: #{scaninfo['projectName']}", summary: "Banner: #{scaninfo['summary']}", controls: controls, target_id: scaninfo['projectName']) results.to_hdf end