Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/tools/modules/cve_xref.rb
Views: 11766
#!/usr/bin/env ruby12msfbase = __FILE__3while File.symlink?(msfbase)4msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase))5end6$:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', '..', 'lib')))7$:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB']89require 'nokogiri'1011module CVE12class XRefTable1314attr_reader :module_full_name_ref15attr_reader :edb_ref16attr_reader :bid_ref17attr_reader :osvdb_ref18attr_reader :msb_ref19attr_reader :zdi_ref20attr_reader :url_refs2122def initialize(refs)23@module_full_name_ref = refs['fullname']24@edb_ref = refs['EDB']25@bid_ref = refs['BID']26@osvdb_ref = refs['OSVDB']27@msb_ref = refs['MSB']28@zdi_ref = refs['ZDI']29@url_refs = refs['URL']30end3132def has_match?(ref_match)33if (34(module_full_name_ref && ref_match.match(/#{module_full_name_ref}/)) ||35(edb_ref && ref_match.match(/EXPLOIT\-DB:#{edb_ref}$/)) ||36(osvdb_ref && ref_match.match(/OSVDB:#{osvdb_ref}$/)) ||37(bid_ref && ref_match.match(/BID:#{bid_ref}$/)) ||38(msb_ref && ref_match.match(/http:\/\/technet\.microsoft\.com\/security\/bulletin\/#{msb_ref}$/)) ||39(zdi_ref && ref_match.match(/zerodayinitiative\.com\/advisories\/ZDI\-#{zdi_ref}/)) ||40(url_refs_match?(ref_match))41)42return true43end4445false46end4748private4950def url_refs_match?(ref_match)51return false unless url_refs52return false unless ref_match.match(/^http/)5354url_refs.each do |url|55return true if url == ref_match56end5758false59end60end6162class Database63attr_reader :database6465def initialize(db_path)66@database = normalize(db_path)67end6869def cross_reference(reference_matches)70return nil if reference_matches.empty?71xref_table = XRefTable.new(reference_matches)7273database.each_pair do |cve_name, references|74references.each do |cve_ref|75if xref_table.has_match?(cve_ref)76return cve_name77end78end79end8081nil82end8384private8586def normalize(db_path)87html = load_cve_html_file(db_path)88normalize_html_to_hash(html)89end9091def load_cve_html_file(db_path)92puts "[*] Loading database..."93raw_data = File.read(db_path)94Nokogiri::HTML(raw_data)95end9697def normalize_html_to_hash(html)98puts "[*] Normalizing database..."99100db = {}101current_cve = nil102metasploit_refs = []103html.traverse do |element|104if current_cve105if element.text =~ /(https*:\/\/.*metasploit.+)/106metasploit_refs << $1107elsif element.text =~ /(http:\/\/www\.exploit\-db\.com\/.+)/108metasploit_refs << $1109elsif element.text =~ /(BID:\d+)/110metasploit_refs << $1111elsif element.text =~ /(OSVDB:\d+)/112metasploit_refs << $1113elsif element.text =~ /http:\/\/technet\.microsoft\.com\/security\/bulletin\/(MS\d+\-\d+)$/114metasploit_refs << $1115elsif element.text =~ /zerodayinitiative\.com\/advisories\/(ZDI\-\d+\-\d+)/116metasploit_refs << $1117elsif element.text =~ /URL:(http.+)/118metasploit_refs << $1119end120end121122if element.text =~ /^Name: (CVE\-\d+\-\d+)$/123current_cve = $1124elsif element.text =~ /^Votes:/125unless metasploit_refs.empty?126db[current_cve] = metasploit_refs127end128current_cve = nil129metasploit_refs = []130end131end132133db134end135end136137end138139class Utility140def self.ignore_module?(module_full_name)141[142'exploit/multi/handler'143].include?(module_full_name)144end145146def self.collect_references_from_module!(module_references, ref_ids, mod)147if ref_ids.include?('EDB')148edb_ref = mod.references.select { |r| r.ctx_id == 'EDB' }.first.ctx_val149module_references['EDB'] = edb_ref150end151152if ref_ids.include?('BID')153bid_ref = mod.references.select { |r| r.ctx_id == 'BID' }.first.ctx_val154module_references['BID'] = bid_ref155end156157if ref_ids.include?('OSVDB')158osvdb_ref = mod.references.select { |r| r.ctx_id == 'OSVDB' }.first.ctx_val159module_references['OSVDB'] = osvdb_ref160end161162if ref_ids.include?('MSB')163msb_ref = mod.references.select { |r| r.ctx_id == 'MSB' }.first.ctx_val164module_references['MSB'] = msb_ref165end166167if ref_ids.include?('ZDI')168zdi_ref = mod.references.select { |r| r.ctx_id == 'ZDI' }.first.ctx_val169module_references['ZDI'] = zdi_ref170end171172if ref_ids.include?('URL')173url_refs = mod.references.select { |r| r.ctx_id == 'URL' }.collect { |r| r.ctx_val if r }174module_references['URL'] = url_refs175end176end177178end179180require 'msfenv'181182def main183filter = 'All'184filters = ['all','exploit','payload','post','nop','encoder','auxiliary']185type = 'CVE'186db_path = nil187188opts = Rex::Parser::Arguments.new(189"-h" => [ false, 'Help menu.' ],190"-f" => [ true, 'Filter based on Module Type [All,Exploit,Payload,Post,NOP,Encoder,Auxiliary] (Default = ALL).'],191"-d" => [ true, 'Source of CVE database in HTML (allitems.html)'],192)193194opts.parse(ARGV) { |opt, idx, val|195case opt196when "-h"197puts "\nMetasploit script for finding CVEs from other references."198puts "=========================================================="199puts opts.usage200exit201when "-f"202unless filters.include?(val.downcase)203puts "Invalid Filter Supplied: #{val}"204puts "Please use one of these: #{filters.map{|f|f.capitalize}.join(", ")}"205exit206end207filter = val208when "-d"209unless File.exist?(val.to_s)210raise RuntimeError, "#{val} not found"211end212213db_path = val214end215}216217framework_opts = { 'DisableDatabase' => true }218framework_opts[:module_types] = [ filter.downcase ] if filter.downcase != 'all'219$framework = Msf::Simple::Framework.create(framework_opts)220cve_database = CVE::Database.new(db_path)221222puts "[*] Going through Metasploit modules for missing references..."223$framework.modules.each { |name, mod|224if mod.nil?225elog("Unable to load #{name}")226next227end228229elog "Loading #{name}"230m = mod.new231next if Utility.ignore_module?(m.fullname)232233ref_ids = m.references.collect { |r| r.ctx_id }234next if ref_ids.include?(type)235236elog "Checking references for #{m.fullname}"237module_references = {}238module_references['fullname'] = m.fullname239Utility.collect_references_from_module!(module_references, ref_ids, m)240cve_match = cve_database.cross_reference(module_references)241if cve_match242puts "[*] #{m.fullname}: Found #{cve_match}"243end244}245end246247if __FILE__ == $PROGRAM_NAME248main249end250251252253