Land #6527, add support for importing Burp suite vuln exports

bug/bundler_fix
Brent Cook 2016-02-10 13:19:21 -06:00
commit 2386cb1344
No known key found for this signature in database
GPG Key ID: 1FFAA0B24B708F96
8 changed files with 175 additions and 4 deletions

View File

@ -16,7 +16,8 @@ module Msf::DBManager::Import
autoload :Acunetix, 'msf/core/db_manager/import/acunetix' autoload :Acunetix, 'msf/core/db_manager/import/acunetix'
autoload :Amap, 'msf/core/db_manager/import/amap' autoload :Amap, 'msf/core/db_manager/import/amap'
autoload :Appscan, 'msf/core/db_manager/import/appscan' 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 :CI, 'msf/core/db_manager/import/ci'
autoload :Foundstone, 'msf/core/db_manager/import/foundstone' autoload :Foundstone, 'msf/core/db_manager/import/foundstone'
autoload :FusionVM, 'msf/core/db_manager/import/fusion_vm' 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::Acunetix
include Msf::DBManager::Import::Amap include Msf::DBManager::Import::Amap
include Msf::DBManager::Import::Appscan 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::CI
include Msf::DBManager::Import::Foundstone include Msf::DBManager::Import::Foundstone
include Msf::DBManager::Import::FusionVM include Msf::DBManager::Import::FusionVM
@ -267,6 +269,9 @@ module Msf::DBManager::Import
elsif (data[0,1024] =~ /<!ATTLIST\s+items\s+burpVersion/) elsif (data[0,1024] =~ /<!ATTLIST\s+items\s+burpVersion/)
@import_filedata[:type] = "Burp Session XML" @import_filedata[:type] = "Burp Session XML"
return :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")) elsif (firstline.index("<?xml"))
# it's xml, check for root tags we can handle # it's xml, check for root tags we can handle
line_count = 0 line_count = 0

View File

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

View File

@ -1,6 +1,6 @@
require 'rex/parser/burp_session_nokogiri' require 'rex/parser/burp_session_nokogiri'
module Msf::DBManager::Import::Burp module Msf::DBManager::Import::BurpSession
def import_burp_session_noko_stream(args={},&block) def import_burp_session_noko_stream(args={},&block)
if block if block
doc = Rex::Parser::BurpSessionDocument.new(args,framework.db) {|type, data| yield type,data } doc = Rex::Parser::BurpSessionDocument.new(args,framework.db) {|type, data| yield type,data }

View File

@ -1647,6 +1647,7 @@ class Db
print_line " Amap Log -m" print_line " Amap Log -m"
print_line " Appscan" print_line " Appscan"
print_line " Burp Session XML" print_line " Burp Session XML"
print_line " Burp Issue XML"
print_line " CI" print_line " CI"
print_line " Foundstone" print_line " Foundstone"
print_line " FusionVM XML" print_line " FusionVM XML"

View File

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

View File

@ -157,7 +157,7 @@ module Rex
host_info = {:workspace => @args[:wspace]} host_info = {:workspace => @args[:wspace]}
host_info[:address] = @state[:web_site].service.host.address host_info[:address] = @state[:web_site].service.host.address
host_info[:name] = @state[:uri].host host_info[:name] = @state[:uri].host
report_db(:host, host_info) db_report(:host, host_info)
end end
def report_web_service_info def report_web_service_info

View File

@ -200,6 +200,11 @@ module Parser
return attr_pairs return attr_pairs
end 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. # This breaks xml-encoded characters, so need to append.
# It's on the end_element tag name to turn the appending # It's on the end_element tag name to turn the appending
# off and clear out the data. # off and clear out the data.

View File

@ -340,6 +340,7 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Db do
" Amap Log", " Amap Log",
" Amap Log -m", " Amap Log -m",
" Appscan", " Appscan",
" Burp Issue XML",
" Burp Session XML", " Burp Session XML",
" CI", " CI",
" Foundstone", " Foundstone",