From b0b72b05d516e5ed699ddf96093070173bd2d4c1 Mon Sep 17 00:00:00 2001 From: Brandon Perry Date: Sun, 13 May 2012 13:02:48 -0500 Subject: [PATCH 1/7] Adding the beginning of the wapiti report import nokogiri document --- lib/rex/parser/wapiti_nokogiri.rb | 73 +++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 lib/rex/parser/wapiti_nokogiri.rb diff --git a/lib/rex/parser/wapiti_nokogiri.rb b/lib/rex/parser/wapiti_nokogiri.rb new file mode 100644 index 0000000000..c95e58cb67 --- /dev/null +++ b/lib/rex/parser/wapiti_nokogiri.rb @@ -0,0 +1,73 @@ +require "rex/parser/nokogiri_doc_mixin" + +module Rex + module Parser + + load_nokoigiri && class WapitiDocument < Nokogiri::XML::SAX::Document + + def start_element(name=nil,attrs=[]) + attrs = normalize_attrs(attrs) + block = @block + @state[:current_tag][name] = true + + case name + when "report" + when "generateBy" + when "bugTypeList" + when "bugType" + when "bug" + when "timestamp" + @state[:has_text] = true + when "url" + @state[:has_text] = true + when "peer" + when "addr" + @state[:has_text] = true + when "port" + @state[:has_text] = true + when "parameter" + @state[:has_text] = true + when "info" + @state[:has_text] = true + when "description" + @state[:has_text] = true + when "solution" + @state[:has_text] = true + when "references" + when "reference" + when "title" + @state[:has_text] = true + end + end + + def end_element(name=nil) + block = @block + case name + when "timestamp" + @state[:timestamp] = @text.strip + @text = nil + when "url" + @state[:url] = @text.strip + @text = nil + when "addr" + @state[:host] = @text.strip + @text = nil + when "port" + @state[:port] = @text.strip + @text = nil + when "parameter" + @state[:parameter] = @text.strip + @text = nil + when "info" + @state[:info] = @text.strip + @text = nil + when "bug" + report_vuln + end + end + + def report_vuln + + end + end +end From d0f49c121325cf6a4fa1f7d6c44ca716648024a1 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 13 May 2012 13:58:25 -0700 Subject: [PATCH 2/7] Finished! Importing wapiti now adds Mdm::WebVulns to the db. However, I see no way to actually seeing the webvulns in framework after importing the report. --- lib/rex/parser/wapiti_nokogiri.rb | 52 +++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/lib/rex/parser/wapiti_nokogiri.rb b/lib/rex/parser/wapiti_nokogiri.rb index c95e58cb67..8a294f7bef 100644 --- a/lib/rex/parser/wapiti_nokogiri.rb +++ b/lib/rex/parser/wapiti_nokogiri.rb @@ -3,7 +3,9 @@ require "rex/parser/nokogiri_doc_mixin" module Rex module Parser - load_nokoigiri && class WapitiDocument < Nokogiri::XML::SAX::Document + load_nokogiri && class WapitiDocument < Nokogiri::XML::SAX::Document + + include NokogiriDocMixin def start_element(name=nil,attrs=[]) attrs = normalize_attrs(attrs) @@ -11,16 +13,10 @@ module Rex @state[:current_tag][name] = true case name - when "report" - when "generateBy" - when "bugTypeList" - when "bugType" - when "bug" when "timestamp" @state[:has_text] = true when "url" @state[:has_text] = true - when "peer" when "addr" @state[:has_text] = true when "port" @@ -33,8 +29,6 @@ module Rex @state[:has_text] = true when "solution" @state[:has_text] = true - when "references" - when "reference" when "title" @state[:has_text] = true end @@ -66,8 +60,46 @@ module Rex end end - def report_vuln + def report_vuln(&block) + p @state.inspect + proto = @state[:url].split(":")[0] + path = '/' + (@state[:url].split("/")[3..(@state[:url].split("/").length - 1)].join('/')) + + web_vuln_info = {} + web_vuln_info[:web_site] = proto + "://" + @state[:host] + ":" + @state[:port] + web_vuln_info[:path] = path + web_vuln_info[:query] = @state[:url].split("?")[1] + + if @state[:url].index(@state[:parameter]) + web_vuln_info[:method] = "GET" + else + web_vuln_info[:method] = "POST" + end + + @state[:parameter].split("&").each do |param| + if param.index("%27") #apostrophe + web_vuln_info[:pname] = param #sql injection + break + elsif param.index("alert") + web_vuln_info[:pname] = param #xss + end + end + + web_vuln_info[:host] = @state[:host] + web_vuln_info[:port] = @state[:port] + web_vuln_info[:ssl] = (proto =~ /https/) + web_vuln_info[:proof] = "" + web_vuln_info[:risk] = "" + web_vuln_info[:params] = @state[:parameter] + web_vuln_info[:category] = "imported" + web_vuln_info[:confidence] = 90 + web_vuln_info[:name] = @state[:info] + + db.emit(:web_vuln, web_vuln_info[:name], &block) if block + vuln = db_report(:web_vuln, web_vuln_info) + p vuln.inspect end end end +end From 253802761fd969c0b833fb59bc4e91c166048b3a Mon Sep 17 00:00:00 2001 From: root Date: Sun, 13 May 2012 14:19:19 -0700 Subject: [PATCH 3/7] Remove extraneous puts --- lib/rex/parser/wapiti_nokogiri.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/rex/parser/wapiti_nokogiri.rb b/lib/rex/parser/wapiti_nokogiri.rb index 8a294f7bef..efde9e7dc9 100644 --- a/lib/rex/parser/wapiti_nokogiri.rb +++ b/lib/rex/parser/wapiti_nokogiri.rb @@ -61,8 +61,6 @@ module Rex end def report_vuln(&block) - p @state.inspect - proto = @state[:url].split(":")[0] path = '/' + (@state[:url].split("/")[3..(@state[:url].split("/").length - 1)].join('/')) @@ -71,6 +69,8 @@ module Rex web_vuln_info[:path] = path web_vuln_info[:query] = @state[:url].split("?")[1] + #if the URL contains the parameter found to be vulnerable, it is probably a GET + #if it does not contains the parameter, it is probably a POST if @state[:url].index(@state[:parameter]) web_vuln_info[:method] = "GET" else @@ -98,7 +98,6 @@ module Rex db.emit(:web_vuln, web_vuln_info[:name], &block) if block vuln = db_report(:web_vuln, web_vuln_info) - p vuln.inspect end end end From d5cec05cc3770ba7140b8be93cf30fc3e0ebb16e Mon Sep 17 00:00:00 2001 From: root Date: Sun, 13 May 2012 14:28:50 -0700 Subject: [PATCH 4/7] fix tabs --- lib/rex/parser/wapiti_nokogiri.rb | 184 +++++++++++++++--------------- 1 file changed, 92 insertions(+), 92 deletions(-) diff --git a/lib/rex/parser/wapiti_nokogiri.rb b/lib/rex/parser/wapiti_nokogiri.rb index efde9e7dc9..34424c0209 100644 --- a/lib/rex/parser/wapiti_nokogiri.rb +++ b/lib/rex/parser/wapiti_nokogiri.rb @@ -1,104 +1,104 @@ require "rex/parser/nokogiri_doc_mixin" module Rex - module Parser + module Parser - load_nokogiri && class WapitiDocument < Nokogiri::XML::SAX::Document + load_nokogiri && class WapitiDocument < Nokogiri::XML::SAX::Document - include NokogiriDocMixin + include NokogiriDocMixin - def start_element(name=nil,attrs=[]) - attrs = normalize_attrs(attrs) - block = @block - @state[:current_tag][name] = true + def start_element(name=nil,attrs=[]) + attrs = normalize_attrs(attrs) + block = @block + @state[:current_tag][name] = true - case name - when "timestamp" - @state[:has_text] = true - when "url" - @state[:has_text] = true - when "addr" - @state[:has_text] = true - when "port" - @state[:has_text] = true - when "parameter" - @state[:has_text] = true - when "info" - @state[:has_text] = true - when "description" - @state[:has_text] = true - when "solution" - @state[:has_text] = true - when "title" - @state[:has_text] = true - end - end - - def end_element(name=nil) - block = @block - case name - when "timestamp" - @state[:timestamp] = @text.strip - @text = nil - when "url" - @state[:url] = @text.strip - @text = nil - when "addr" - @state[:host] = @text.strip - @text = nil - when "port" - @state[:port] = @text.strip - @text = nil - when "parameter" - @state[:parameter] = @text.strip - @text = nil - when "info" - @state[:info] = @text.strip - @text = nil - when "bug" - report_vuln - end - end - - def report_vuln(&block) - proto = @state[:url].split(":")[0] - path = '/' + (@state[:url].split("/")[3..(@state[:url].split("/").length - 1)].join('/')) - - web_vuln_info = {} - web_vuln_info[:web_site] = proto + "://" + @state[:host] + ":" + @state[:port] - web_vuln_info[:path] = path - web_vuln_info[:query] = @state[:url].split("?")[1] - - #if the URL contains the parameter found to be vulnerable, it is probably a GET - #if it does not contains the parameter, it is probably a POST - if @state[:url].index(@state[:parameter]) - web_vuln_info[:method] = "GET" - else - web_vuln_info[:method] = "POST" - end - - @state[:parameter].split("&").each do |param| - if param.index("%27") #apostrophe - web_vuln_info[:pname] = param #sql injection - break - elsif param.index("alert") - web_vuln_info[:pname] = param #xss + case name + when "timestamp" + @state[:has_text] = true + when "url" + @state[:has_text] = true + when "addr" + @state[:has_text] = true + when "port" + @state[:has_text] = true + when "parameter" + @state[:has_text] = true + when "info" + @state[:has_text] = true + when "description" + @state[:has_text] = true + when "solution" + @state[:has_text] = true + when "title" + @state[:has_text] = true + end end - end - web_vuln_info[:host] = @state[:host] - web_vuln_info[:port] = @state[:port] - web_vuln_info[:ssl] = (proto =~ /https/) - web_vuln_info[:proof] = "" - web_vuln_info[:risk] = "" - web_vuln_info[:params] = @state[:parameter] - web_vuln_info[:category] = "imported" - web_vuln_info[:confidence] = 90 - web_vuln_info[:name] = @state[:info] + def end_element(name=nil) + block = @block + case name + when "timestamp" + @state[:timestamp] = @text.strip + @text = nil + when "url" + @state[:url] = @text.strip + @text = nil + when "addr" + @state[:host] = @text.strip + @text = nil + when "port" + @state[:port] = @text.strip + @text = nil + when "parameter" + @state[:parameter] = @text.strip + @text = nil + when "info" + @state[:info] = @text.strip + @text = nil + when "bug" + report_vuln + end + end - db.emit(:web_vuln, web_vuln_info[:name], &block) if block - vuln = db_report(:web_vuln, web_vuln_info) - end - end + def report_vuln(&block) + proto = @state[:url].split(":")[0] + path = '/' + (@state[:url].split("/")[3..(@state[:url].split("/").length - 1)].join('/')) + + web_vuln_info = {} + web_vuln_info[:web_site] = proto + "://" + @state[:host] + ":" + @state[:port] + web_vuln_info[:path] = path + web_vuln_info[:query] = @state[:url].split("?")[1] + + #if the URL contains the parameter found to be vulnerable, it is probably a GET + #if it does not contains the parameter, it is probably a POST + if @state[:url].index(@state[:parameter]) + web_vuln_info[:method] = "GET" + else + web_vuln_info[:method] = "POST" + end + + @state[:parameter].split("&").each do |param| + if param.index("%27") #apostrophe + web_vuln_info[:pname] = param #sql injection + break + elsif param.index("alert") + web_vuln_info[:pname] = param #xss + end + end + + web_vuln_info[:host] = @state[:host] + web_vuln_info[:port] = @state[:port] + web_vuln_info[:ssl] = (proto =~ /https/) + web_vuln_info[:proof] = "" + web_vuln_info[:risk] = "" + web_vuln_info[:params] = @state[:parameter] + web_vuln_info[:category] = "imported" + web_vuln_info[:confidence] = 90 + web_vuln_info[:name] = @state[:info] + + db.emit(:web_vuln, web_vuln_info[:name], &block) if block + vuln = db_report(:web_vuln, web_vuln_info) + end + end end end From 2906686da19d72b750cce646694be8b6d4ee6be9 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 13 May 2012 14:30:27 -0700 Subject: [PATCH 5/7] forgot to git add db.rb. oops --- lib/msf/core/db.rb | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/lib/msf/core/db.rb b/lib/msf/core/db.rb index 50ae9b47ae..c0ddd7bc0b 100644 --- a/lib/msf/core/db.rb +++ b/lib/msf/core/db.rb @@ -8,6 +8,7 @@ require 'rex/parser/acunetix_nokogiri' require 'rex/parser/appscan_nokogiri' require 'rex/parser/burp_session_nokogiri' require 'rex/parser/ci_nokogiri' +require 'rex/parser/wapiti_nokogiri' # Legacy XML parsers -- these will be converted some day @@ -2440,6 +2441,7 @@ class DBManager line_count = 0 data.each_line { |line| line =~ /<([a-zA-Z0-9\-\_]+)[ >]/ + case $1 when "niktoscan" @import_filedata[:type] = "Nikto XML" @@ -2459,6 +2461,9 @@ class DBManager when "SCAN" @import_filedata[:type] = "Qualys Scan XML" return :qualys_scan_xml + when "report" + @import_filedata[:type] = "Wapiti XML" + return :wapiti_xml when "ASSET_DATA_REPORT" @import_filedata[:type] = "Qualys Asset XML" return :qualys_asset_xml @@ -2591,6 +2596,29 @@ class DBManager end end + def import_wapiti_xml_file(args={}) + filename = args[:filename] + wspace = args[:wspace] || workspace + + + data = "" + ::File.open(filename, 'rb') do |f| + data = f.read(f.stat.size) + end + import_wapiti_xml(args.merge(:data => data)) + + end + + def import_wapiti_xml(args={}, &block) + if block + doc = Rex::Parser::WapitiDocument.new(args,framework.db) {|type, data| yield type,data } + else + doc = Rex::Parser::WapitiDocument.new(args,self) + end + parser = ::Nokogiri::XML::SAX::Parser.new(doc) + parser.parse(args[:data]) + end + def import_libpcap_file(args={}) filename = args[:filename] wspace = args[:wspace] || workspace From 99a5d1a7b5732b7f2d211dd706404b6c8b232c02 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 13 May 2012 14:43:02 -0700 Subject: [PATCH 6/7] fix :pname in the web_vuln_info hash to no include the parameter value --- lib/rex/parser/wapiti_nokogiri.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rex/parser/wapiti_nokogiri.rb b/lib/rex/parser/wapiti_nokogiri.rb index 34424c0209..4acb93a0cc 100644 --- a/lib/rex/parser/wapiti_nokogiri.rb +++ b/lib/rex/parser/wapiti_nokogiri.rb @@ -79,10 +79,10 @@ module Rex @state[:parameter].split("&").each do |param| if param.index("%27") #apostrophe - web_vuln_info[:pname] = param #sql injection + web_vuln_info[:pname] = param.split('=')[0] #sql injection break elsif param.index("alert") - web_vuln_info[:pname] = param #xss + web_vuln_info[:pname] = param.split('=')[0] #xss end end From 5aeab77499b9f5e6aa6d42ce3d65216b8053d791 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 14 May 2012 07:26:37 -0700 Subject: [PATCH 7/7] fix tabs that I missed in db.rb --- lib/msf/core/db.rb | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/lib/msf/core/db.rb b/lib/msf/core/db.rb index c0ddd7bc0b..675a735664 100644 --- a/lib/msf/core/db.rb +++ b/lib/msf/core/db.rb @@ -2600,23 +2600,21 @@ class DBManager filename = args[:filename] wspace = args[:wspace] || workspace - - data = "" - ::File.open(filename, 'rb') do |f| - data = f.read(f.stat.size) - end - import_wapiti_xml(args.merge(:data => data)) - + data = "" + ::File.open(filename, 'rb') do |f| + data = f.read(f.stat.size) + end + import_wapiti_xml(args.merge(:data => data)) end def import_wapiti_xml(args={}, &block) - if block - doc = Rex::Parser::WapitiDocument.new(args,framework.db) {|type, data| yield type,data } - else - doc = Rex::Parser::WapitiDocument.new(args,self) - end - parser = ::Nokogiri::XML::SAX::Parser.new(doc) - parser.parse(args[:data]) + if block + doc = Rex::Parser::WapitiDocument.new(args,framework.db) {|type, data| yield type,data } + else + doc = Rex::Parser::WapitiDocument.new(args,self) + end + parser = ::Nokogiri::XML::SAX::Parser.new(doc) + parser.parse(args[:data]) end def import_libpcap_file(args={})