Land #6527, add support for importing Burp suite vuln exports
commit
2386cb1344
|
@ -16,7 +16,8 @@ module Msf::DBManager::Import
|
|||
autoload :Acunetix, 'msf/core/db_manager/import/acunetix'
|
||||
autoload :Amap, 'msf/core/db_manager/import/amap'
|
||||
autoload :Appscan, 'msf/core/db_manager/import/appscan'
|
||||
autoload :Burp, 'msf/core/db_manager/import/burp'
|
||||
autoload :BurpIssue, 'msf/core/db_manager/import/burp_issue'
|
||||
autoload :BurpSession, 'msf/core/db_manager/import/burp_session'
|
||||
autoload :CI, 'msf/core/db_manager/import/ci'
|
||||
autoload :Foundstone, 'msf/core/db_manager/import/foundstone'
|
||||
autoload :FusionVM, 'msf/core/db_manager/import/fusion_vm'
|
||||
|
@ -41,7 +42,8 @@ module Msf::DBManager::Import
|
|||
include Msf::DBManager::Import::Acunetix
|
||||
include Msf::DBManager::Import::Amap
|
||||
include Msf::DBManager::Import::Appscan
|
||||
include Msf::DBManager::Import::Burp
|
||||
include Msf::DBManager::Import::BurpIssue
|
||||
include Msf::DBManager::Import::BurpSession
|
||||
include Msf::DBManager::Import::CI
|
||||
include Msf::DBManager::Import::Foundstone
|
||||
include Msf::DBManager::Import::FusionVM
|
||||
|
@ -267,6 +269,9 @@ module Msf::DBManager::Import
|
|||
elsif (data[0,1024] =~ /<!ATTLIST\s+items\s+burpVersion/)
|
||||
@import_filedata[:type] = "Burp Session XML"
|
||||
return :burp_session_xml
|
||||
elsif (data[0,1024] =~ /<!ATTLIST\s+issues\s+burpVersion/)
|
||||
@import_filedata[:type] = "Burp Issue XML"
|
||||
return :burp_issue_xml
|
||||
elsif (firstline.index("<?xml"))
|
||||
# it's xml, check for root tags we can handle
|
||||
line_count = 0
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
require 'rex/parser/burp_issue_nokogiri'
|
||||
|
||||
module Msf::DBManager::Import::BurpIssue
|
||||
def import_burp_issue_xml(args={}, &block)
|
||||
bl = validate_ips(args[:blacklist]) ? args[:blacklist].split : []
|
||||
wspace = args[:wspace] || workspace
|
||||
parser = "Nokogiri v#{::Nokogiri::VERSION}"
|
||||
noko_args = args.dup
|
||||
noko_args[:blacklist] = bl
|
||||
noko_args[:wspace] = wspace
|
||||
if block
|
||||
yield(:parser, parser)
|
||||
doc = Rex::Parser::BurpIssueDocument.new(args,framework.db) {|type, data| yield type,data }
|
||||
else
|
||||
doc = Rex::Parser::BurpIssueDocument.new(args,self)
|
||||
end
|
||||
parser = ::Nokogiri::XML::SAX::Parser.new(doc)
|
||||
parser.parse(args[:data])
|
||||
end
|
||||
end
|
|
@ -1,6 +1,6 @@
|
|||
require 'rex/parser/burp_session_nokogiri'
|
||||
|
||||
module Msf::DBManager::Import::Burp
|
||||
module Msf::DBManager::Import::BurpSession
|
||||
def import_burp_session_noko_stream(args={},&block)
|
||||
if block
|
||||
doc = Rex::Parser::BurpSessionDocument.new(args,framework.db) {|type, data| yield type,data }
|
|
@ -1647,6 +1647,7 @@ class Db
|
|||
print_line " Amap Log -m"
|
||||
print_line " Appscan"
|
||||
print_line " Burp Session XML"
|
||||
print_line " Burp Issue XML"
|
||||
print_line " CI"
|
||||
print_line " Foundstone"
|
||||
print_line " FusionVM XML"
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
# -*- coding: binary -*-
|
||||
require "rex/parser/nokogiri_doc_mixin"
|
||||
require 'uri'
|
||||
|
||||
module Rex
|
||||
module Parser
|
||||
|
||||
# If Nokogiri is available, define Burp Issue document class.
|
||||
load_nokogiri && class BurpIssueDocument < Nokogiri::XML::SAX::Document
|
||||
|
||||
include NokogiriDocMixin
|
||||
|
||||
def start_element(name=nil,attrs=[])
|
||||
attrs = normalize_attrs(attrs)
|
||||
block = @block
|
||||
@state[:current_tag][name] = true
|
||||
case name
|
||||
when "host", "name", "info", "issueDetail", "references"
|
||||
@state[:has_text] = true
|
||||
end
|
||||
end
|
||||
|
||||
def end_element(name=nil)
|
||||
block = @block
|
||||
case name
|
||||
when "issue"
|
||||
report_web_host_info
|
||||
report_web_service_info
|
||||
report_vuln
|
||||
# Reset the state once we close a host
|
||||
@state = @state.select {|k| [:current_tag].include? k}
|
||||
when "host"
|
||||
@state[:has_text] = false
|
||||
collect_host_info
|
||||
@text = nil
|
||||
when "name"
|
||||
@state[:has_text] = false
|
||||
collect_name
|
||||
@text = nil
|
||||
when "issueDetail"
|
||||
@state[:has_text] = false
|
||||
collect_issue_detail
|
||||
@text = nil
|
||||
when "references"
|
||||
@state[:has_text] = false
|
||||
collect_references
|
||||
@text = nil
|
||||
end
|
||||
@state[:current_tag].delete name
|
||||
end
|
||||
|
||||
def collect_host_info
|
||||
return unless in_issue
|
||||
return unless has_text
|
||||
uri = URI(@text)
|
||||
|
||||
@state[:host] = uri.host
|
||||
@state[:service_name] = uri.scheme
|
||||
@state[:proto] = "tcp"
|
||||
|
||||
case @state[:service_name]
|
||||
when "http"
|
||||
@state[:port] = 80
|
||||
when "https"
|
||||
@state[:port] = 443
|
||||
end
|
||||
end
|
||||
|
||||
def collect_name
|
||||
return unless in_issue
|
||||
return unless has_text
|
||||
@state[:vuln_name] = @text
|
||||
end
|
||||
|
||||
def collect_issue_detail
|
||||
return unless in_issue
|
||||
return unless has_text
|
||||
@state[:issue_detail] = @text
|
||||
end
|
||||
|
||||
def collect_references
|
||||
return unless in_issue
|
||||
return unless has_text
|
||||
uri = @text.match('href=[\'"]?([^\'" >]+)')[1]
|
||||
@state[:refs] = ["URI-#{uri}"]
|
||||
end
|
||||
|
||||
def report_web_host_info
|
||||
return unless @state[:host]
|
||||
address = Rex::Socket.resolv_to_dotted(@state[:host]) rescue nil
|
||||
host_info = {:workspace => @args[:wspace]}
|
||||
host_info[:address] = address
|
||||
host_info[:name] = @state[:host]
|
||||
db_report(:host, host_info)
|
||||
end
|
||||
|
||||
def report_web_service_info
|
||||
return unless @state[:host]
|
||||
return unless @state[:port]
|
||||
return unless @state[:proto]
|
||||
return unless @state[:service_name]
|
||||
service_info = {}
|
||||
service_info[:host] = @state[:host]
|
||||
service_info[:port] = @state[:port]
|
||||
service_info[:proto] = @state[:proto]
|
||||
service_info[:name] = @state[:service_name]
|
||||
@state[:service_object] = db_report(:service, service_info)
|
||||
end
|
||||
|
||||
def report_vuln
|
||||
return unless @state[:service_object]
|
||||
return unless @state[:vuln_name]
|
||||
return unless @state[:issue_detail]
|
||||
return unless @state[:refs]
|
||||
vuln_info = {}
|
||||
vuln_info[:service_id] = @state[:service_object].id
|
||||
vuln_info[:host] = @state[:host]
|
||||
vuln_info[:name] = @state[:vuln_name]
|
||||
vuln_info[:info] = @state[:issue_detail]
|
||||
vuln_info[:refs] = @state[:refs]
|
||||
@state[:vuln_object] = db_report(:vuln, vuln_info)
|
||||
end
|
||||
|
||||
def in_issue
|
||||
return false unless in_tag("issue")
|
||||
return false unless in_tag("issues")
|
||||
return true
|
||||
end
|
||||
|
||||
def has_text
|
||||
return false unless @text
|
||||
return false if @text.strip.empty?
|
||||
@text = @text.strip
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -157,7 +157,7 @@ module Rex
|
|||
host_info = {:workspace => @args[:wspace]}
|
||||
host_info[:address] = @state[:web_site].service.host.address
|
||||
host_info[:name] = @state[:uri].host
|
||||
report_db(:host, host_info)
|
||||
db_report(:host, host_info)
|
||||
end
|
||||
|
||||
def report_web_service_info
|
||||
|
|
|
@ -200,6 +200,11 @@ module Parser
|
|||
return attr_pairs
|
||||
end
|
||||
|
||||
# Removes HTML from a string
|
||||
def strip_html_tags(text)
|
||||
return text.gsub!(/(<[^>]*>)|\n|\t/s) {" "}
|
||||
end
|
||||
|
||||
# This breaks xml-encoded characters, so need to append.
|
||||
# It's on the end_element tag name to turn the appending
|
||||
# off and clear out the data.
|
||||
|
|
|
@ -340,6 +340,7 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Db do
|
|||
" Amap Log",
|
||||
" Amap Log -m",
|
||||
" Appscan",
|
||||
" Burp Issue XML",
|
||||
" Burp Session XML",
|
||||
" CI",
|
||||
" Foundstone",
|
||||
|
|
Loading…
Reference in New Issue