dradis-burp 3.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/issue_template.md +16 -0
- data/.github/pull_request_template.md +36 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/CHANGELOG.md +57 -0
- data/CONTRIBUTING.md +3 -0
- data/Gemfile +23 -0
- data/LICENSE +339 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/dradis-burp.gemspec +34 -0
- data/lib/burp/html/issue.rb +157 -0
- data/lib/burp/issue.rb +43 -0
- data/lib/burp/xml/issue.rb +127 -0
- data/lib/dradis-burp.rb +10 -0
- data/lib/dradis/plugins/burp.rb +12 -0
- data/lib/dradis/plugins/burp/engine.rb +25 -0
- data/lib/dradis/plugins/burp/field_processor.rb +27 -0
- data/lib/dradis/plugins/burp/gem_version.rb +19 -0
- data/lib/dradis/plugins/burp/html/importer.rb +144 -0
- data/lib/dradis/plugins/burp/version.rb +13 -0
- data/lib/dradis/plugins/burp/xml/importer.rb +144 -0
- data/lib/tasks/thorfile.rb +30 -0
- data/spec/burp_upload_spec.rb +220 -0
- data/spec/fixtures/files/burp.html +229 -0
- data/spec/fixtures/files/burp.xml +100 -0
- data/spec/fixtures/files/burp_issue_severity.xml +118 -0
- data/spec/fixtures/files/invalid-utf-issue.xml +21 -0
- data/spec/fixtures/files/without-base64.xml +709 -0
- data/spec/spec_helper.rb +9 -0
- data/templates/evidence.fields +8 -0
- data/templates/evidence.sample +76 -0
- data/templates/evidence.template +20 -0
- data/templates/html_evidence.fields +13 -0
- data/templates/html_evidence.sample +36 -0
- data/templates/html_evidence.template +50 -0
- data/templates/issue.fields +8 -0
- data/templates/issue.sample +23 -0
- data/templates/issue.template +30 -0
- metadata +174 -0
data/README.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Burp Scanner plugin for Dradis
|
|
2
|
+
|
|
3
|
+
[](http://travis-ci.org/dradis/dradis-burp) [](https://codeclimate.com/github/dradis/dradis-burp.png)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
Upload Burp Scanner XML export files into Dradis.
|
|
7
|
+
|
|
8
|
+
The add-on requires [Dradis CE](https://dradisframework.org/) > 3.0, or [Dradis Pro](https://dradisframework.com/pro/).
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## More information
|
|
13
|
+
|
|
14
|
+
See the Dradis Framework's [README.md](https://github.com/dradis/dradisframework/blob/master/README.md)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## Contributing
|
|
18
|
+
|
|
19
|
+
See the Dradis Framework's [CONTRIBUTING.md](https://github.com/dradis/dradisframework/blob/master/CONTRIBUTING.md)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## License
|
|
23
|
+
|
|
24
|
+
Dradis Framework and all its components are released under [GNU General Public License version 2.0](http://www.gnu.org/licenses/old-licenses/gpl-2.0.html) as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## Feature requests and bugs
|
|
28
|
+
|
|
29
|
+
Please use the [Dradis Framework issue tracker](https://github.com/dradis/dradis-ce/issues) for add-on improvements and bug reports.
|
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "bundler/gem_tasks"
|
data/dradis-burp.gemspec
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
$:.push File.expand_path('../lib', __FILE__)
|
|
2
|
+
require 'dradis/plugins/burp/version'
|
|
3
|
+
version = Dradis::Plugins::Burp::VERSION::STRING
|
|
4
|
+
|
|
5
|
+
# Describe your gem and declare its dependencies:
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.platform = Gem::Platform::RUBY
|
|
8
|
+
spec.name = 'dradis-burp'
|
|
9
|
+
spec.version = version
|
|
10
|
+
spec.summary = 'Burp Scanner upload plugin for the Dradis Framework.'
|
|
11
|
+
spec.description = 'This plugin allows you to upload and parse output produced from Portswigger\'s Burp Scanner into Dradis.'
|
|
12
|
+
|
|
13
|
+
spec.license = 'GPL-2'
|
|
14
|
+
|
|
15
|
+
spec.authors = ['Daniel Martin']
|
|
16
|
+
spec.email = ['etd@nomejortu.com']
|
|
17
|
+
spec.homepage = 'http://dradisframework.org'
|
|
18
|
+
|
|
19
|
+
spec.files = `git ls-files`.split($\)
|
|
20
|
+
spec.executables = spec.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
21
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
22
|
+
|
|
23
|
+
# By not including Rails as a dependency, we can use the gem with different
|
|
24
|
+
# versions of Rails (a sure recipe for disaster, I'm sure), which is needed
|
|
25
|
+
# until we bump Dradis Pro to 4.1.
|
|
26
|
+
# s.add_dependency 'rails', '~> 4.1.1'
|
|
27
|
+
spec.add_dependency 'dradis-plugins', '~> 3.6'
|
|
28
|
+
spec.add_dependency 'nokogiri', '~> 1.3'
|
|
29
|
+
|
|
30
|
+
spec.add_development_dependency 'bundler'
|
|
31
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
|
32
|
+
spec.add_development_dependency 'rspec-rails'
|
|
33
|
+
spec.add_development_dependency 'combustion', '~> 0.5.2'
|
|
34
|
+
end
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
module Burp
|
|
2
|
+
module Html
|
|
3
|
+
# This class represents each of the issue elements in the Burp
|
|
4
|
+
# Scanner HTML document: all elemennts from a span.BODH0 until the next
|
|
5
|
+
# span.BODH0 (the next one excluded).
|
|
6
|
+
#
|
|
7
|
+
# It provides a convenient way to access the information scattered all over
|
|
8
|
+
# the HTML.
|
|
9
|
+
class Issue < ::Burp::Issue
|
|
10
|
+
# Accepts a Nokogiri::XML::NodeSet
|
|
11
|
+
def initialize(html)
|
|
12
|
+
@html = Nokogiri::HTML(html.to_s)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# List of supported tags
|
|
16
|
+
def supported_tags
|
|
17
|
+
[
|
|
18
|
+
# tags with contents retrieved from inside the span header
|
|
19
|
+
:name, :type,
|
|
20
|
+
|
|
21
|
+
# tags with contents retrieved following the span header
|
|
22
|
+
:background, :detail,
|
|
23
|
+
:references, :remediation_background, :remediation_detail,
|
|
24
|
+
:request, :request_1, :request_2, :request_3,
|
|
25
|
+
:response, :response_1, :response_2, :response_3,
|
|
26
|
+
:vulnerability_classifications
|
|
27
|
+
] + summary_table_tags
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def header
|
|
31
|
+
@header ||= @html.at_css('span')
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def name
|
|
35
|
+
@name ||= header.text.gsub(/^\d+\.\S/, '')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Link looks like: https://portswigger.net/kb/issues/00200400_flash-cross-domain-policy
|
|
39
|
+
# We use that 00200400 as type since in that page it calls it 'Type index'
|
|
40
|
+
def type
|
|
41
|
+
@type ||=
|
|
42
|
+
if header_link = header.at_css('a')
|
|
43
|
+
header_link.attr('href').to_s[/\/([0-9a-f]+)_.*/, 1].to_i(16)
|
|
44
|
+
else
|
|
45
|
+
nil
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# This method is invoked by Ruby when a method that is not defined in this
|
|
50
|
+
# instance is called.
|
|
51
|
+
#
|
|
52
|
+
# In our case we inspect the @method@ parameter and try to find the
|
|
53
|
+
# corresponding header in our HTML, then return the following text.
|
|
54
|
+
def method_missing(method, *args)
|
|
55
|
+
# We could remove this check and return nil for any non-recognized tag.
|
|
56
|
+
# The problem would be that it would make tricky to debug problems with
|
|
57
|
+
# typos. For instance: <>.potr would return nil instead of raising an
|
|
58
|
+
# exception
|
|
59
|
+
unless supported_tags.include?(method)
|
|
60
|
+
super
|
|
61
|
+
return
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# First we try the h2 headers.
|
|
65
|
+
translations_table = {
|
|
66
|
+
background: ['Issue background', 'Issue description'],
|
|
67
|
+
detail: 'Issue detail',
|
|
68
|
+
references: 'References',
|
|
69
|
+
remediation_background: ['Remediation background', 'Issue remediation'],
|
|
70
|
+
remediation_detail: 'Remediation detail',
|
|
71
|
+
request: 'Request',
|
|
72
|
+
request_1: 'Request 1',
|
|
73
|
+
request_2: 'Request 2',
|
|
74
|
+
request_3: 'Request 3',
|
|
75
|
+
response: 'Response',
|
|
76
|
+
response_1: 'Response 1',
|
|
77
|
+
response_2: 'Response 2',
|
|
78
|
+
response_3: 'Response 3',
|
|
79
|
+
serial_number: 'Serial number',
|
|
80
|
+
vulnerability_classifications: 'Vulnerability classifications'
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
# look for the h2 headers in the html fragment
|
|
84
|
+
method_names = translations_table.fetch(method, method.to_s)
|
|
85
|
+
method_names = [method_names].flatten
|
|
86
|
+
|
|
87
|
+
h2 = nil
|
|
88
|
+
method_names.each do |method_name|
|
|
89
|
+
h2 = @html.xpath("//h2[text()='#{method_name}']").first
|
|
90
|
+
break if h2
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
if h2
|
|
94
|
+
content =
|
|
95
|
+
if h2.text =~ /^(Request|Response)/
|
|
96
|
+
cleanup_request_response_html(h2.next_element.inner_html)
|
|
97
|
+
else
|
|
98
|
+
cleanup_html(h2.next_element.inner_html)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
return content
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# look inside the summary table in the html fragment
|
|
105
|
+
summary[method]
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
private
|
|
109
|
+
|
|
110
|
+
# In Request/Response html snippets we don't want to cleanup the whole
|
|
111
|
+
# html as we ususally do. The snippets may contain html code to be displayed,
|
|
112
|
+
# and we don't want to convert that to textile.
|
|
113
|
+
def cleanup_request_response_html(source)
|
|
114
|
+
result = source.dup
|
|
115
|
+
|
|
116
|
+
result.gsub!(/<b>(.*?)<\/b>/, '\1')
|
|
117
|
+
result.gsub!(/<br>|<\/br>/){"\n"}
|
|
118
|
+
result.gsub!(/<span.*?>/, '')
|
|
119
|
+
result.gsub!(/<\/span>/, '')
|
|
120
|
+
|
|
121
|
+
result.gsub!(/"/, '"')
|
|
122
|
+
result.gsub!(/&/, '&')
|
|
123
|
+
result.gsub!(/</, '<')
|
|
124
|
+
result.gsub!(/>/, '>')
|
|
125
|
+
result.gsub!(/ /, ' ')
|
|
126
|
+
|
|
127
|
+
result
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Returns the summary table in the HTML fragment as a Hash
|
|
131
|
+
def summary
|
|
132
|
+
@summary ||= begin
|
|
133
|
+
@summary = {}
|
|
134
|
+
h2 = @html.search("h2[text()='Summary']").first
|
|
135
|
+
return @summary if h2.nil?
|
|
136
|
+
|
|
137
|
+
table = h2.next_element
|
|
138
|
+
|
|
139
|
+
summary_table_tags.each do |tag|
|
|
140
|
+
td = table.search("td:starts-with('#{tag.to_s.capitalize}:')").first
|
|
141
|
+
@summary[tag] = td.next_element.text
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
@summary
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# List of supported tags to obtain from the summary html table
|
|
149
|
+
def summary_table_tags
|
|
150
|
+
[
|
|
151
|
+
:confidence, :host, :path, :severity
|
|
152
|
+
]
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
data/lib/burp/issue.rb
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Burp
|
|
2
|
+
# We use this string to replace invalid UTF-8 bytes with.
|
|
3
|
+
INVALID_UTF_REPLACE = '<?>'
|
|
4
|
+
|
|
5
|
+
class Issue
|
|
6
|
+
|
|
7
|
+
# This allows external callers (and specs) to check for implemented
|
|
8
|
+
# properties
|
|
9
|
+
def respond_to?(method, include_private=false)
|
|
10
|
+
return true if supported_tags.include?(method.to_sym)
|
|
11
|
+
super
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def cleanup_html(source)
|
|
17
|
+
result = source.dup
|
|
18
|
+
result.gsub!(/"/, '"')
|
|
19
|
+
result.gsub!(/&/, '&')
|
|
20
|
+
result.gsub!(/</, '<')
|
|
21
|
+
result.gsub!(/>/, '>')
|
|
22
|
+
result.gsub!(/ /, ' ')
|
|
23
|
+
|
|
24
|
+
result.gsub!(/<b>(.*?)<\/b>/, '*\1*')
|
|
25
|
+
result.gsub!(/<br>|<\/br>/){"\n"}
|
|
26
|
+
result.gsub!(/<font.*?>(.*?)<\/font>/m, '\1')
|
|
27
|
+
result.gsub!(/<h\d?>(.*?)<\/h\d?>/, '*\1*')
|
|
28
|
+
result.gsub!(/<i>(.*?)<\/i>/, '\1')
|
|
29
|
+
result.gsub!(/<p>|<\/p>/){"\n"}
|
|
30
|
+
result.gsub!(/<pre.*?>(.*?)<\/pre>/m){|m| "\n\nbc.. #{ $1 }\n\np. \n" }
|
|
31
|
+
|
|
32
|
+
result.gsub!(/<ul>(.*?)<\/ul>/m){|m| "#{ $1 }\n"}
|
|
33
|
+
result.gsub!(/<li>(.*?)<\/li>/m){|m| "\n* #{ $1 }"}
|
|
34
|
+
result.gsub!(/<a href=\"(.*?)\">(.*?)<\/a>/im) { "\"#{$2.strip}\":#{$1.strip}" }
|
|
35
|
+
|
|
36
|
+
result.gsub!(/<table>(.*?)<\/table>/m){|m| "\n\n#{ $1 }\n\n" }
|
|
37
|
+
result.gsub!(/<tr>(.*?)<\/tr>/m){|m| "|#{ $1 }\n" }
|
|
38
|
+
result.gsub!(/<td>(.*?)<\/td>/, '\1|')
|
|
39
|
+
|
|
40
|
+
result
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
module Burp
|
|
2
|
+
module Xml
|
|
3
|
+
|
|
4
|
+
# This class represents each of the /issues/issue elements in the Burp
|
|
5
|
+
# Scanner XML document.
|
|
6
|
+
#
|
|
7
|
+
# It provides a convenient way to access the information scattered all over
|
|
8
|
+
# the XML in attributes and nested tags.
|
|
9
|
+
#
|
|
10
|
+
# Instead of providing separate methods for each supported property we rely
|
|
11
|
+
# on Ruby's #method_missing to do most of the work.
|
|
12
|
+
class Issue < ::Burp::Issue
|
|
13
|
+
|
|
14
|
+
# Accepts an XML node from Nokogiri::XML.
|
|
15
|
+
def initialize(xml_node)
|
|
16
|
+
@xml = xml_node
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# List of supported tags. They can be attributes, simple descendants or
|
|
20
|
+
# collections (e.g. <references/>, <tags/>)
|
|
21
|
+
def supported_tags
|
|
22
|
+
[
|
|
23
|
+
# attributes
|
|
24
|
+
|
|
25
|
+
# simple tags
|
|
26
|
+
:background, :confidence, :detail, :host, :location, :name, :path,
|
|
27
|
+
:references, :remediation_background, :remediation_detail,
|
|
28
|
+
:serial_number, :severity, :type,
|
|
29
|
+
:vulnerability_classifications,
|
|
30
|
+
|
|
31
|
+
# nested tags
|
|
32
|
+
:request, :response
|
|
33
|
+
]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# This method is invoked by Ruby when a method that is not defined in this
|
|
37
|
+
# instance is called.
|
|
38
|
+
#
|
|
39
|
+
# In our case we inspect the @method@ parameter and try to find the
|
|
40
|
+
# attribute, simple descendent or collection that it maps to in the XML
|
|
41
|
+
# tree.
|
|
42
|
+
def method_missing(method, *args)
|
|
43
|
+
|
|
44
|
+
# We could remove this check and return nil for any non-recognized tag.
|
|
45
|
+
# The problem would be that it would make tricky to debug problems with
|
|
46
|
+
# typos. For instance: <>.potr would return nil instead of raising an
|
|
47
|
+
# exception
|
|
48
|
+
unless supported_tags.include?(method)
|
|
49
|
+
super
|
|
50
|
+
return
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# First we try the attributes. In Ruby we use snake_case, but in XML
|
|
54
|
+
# CamelCase is used for some attributes
|
|
55
|
+
translations_table = {
|
|
56
|
+
background: 'issueBackground',
|
|
57
|
+
detail: 'issueDetail',
|
|
58
|
+
remediation_background: 'remediationBackground',
|
|
59
|
+
remediation_detail: 'remediationDetail',
|
|
60
|
+
vulnerability_classifications: 'vulnerabilityClassifications',
|
|
61
|
+
serial_number: 'serialNumber'
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
method_name = translations_table.fetch(method, method.to_s)
|
|
65
|
+
|
|
66
|
+
# no attributes in the <issue> node
|
|
67
|
+
# return @xml.attributes[method_name].value if @xml.attributes.key?(method_name)
|
|
68
|
+
|
|
69
|
+
# Then we try simple children tags: name, type, ...
|
|
70
|
+
tag = @xml.xpath("./#{method_name}").first
|
|
71
|
+
if tag && !tag.text.blank?
|
|
72
|
+
if tags_with_html_content.include?(method)
|
|
73
|
+
return cleanup_html(tag.text)
|
|
74
|
+
else
|
|
75
|
+
return tag.text
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
if (['request', 'response'].include?(method_name))
|
|
80
|
+
requestresponse_child(method_name)
|
|
81
|
+
else
|
|
82
|
+
# nothing found, the tag is valid but not present in this ReportItem
|
|
83
|
+
return nil
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
# Some of the values have embedded HTML content that we need to strip
|
|
90
|
+
def tags_with_html_content
|
|
91
|
+
[:background, :detail, :remediation_background, :remediation_detail, :references, :vulnerability_classifications]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def requestresponse_child(field)
|
|
95
|
+
return 'n/a' unless @xml.at('requestresponse') && @xml.at("requestresponse/#{field}")
|
|
96
|
+
|
|
97
|
+
xml_node = @xml.at("requestresponse/#{field}")
|
|
98
|
+
result = "[unprocessable #{field}]"
|
|
99
|
+
|
|
100
|
+
if xml_node['base64'] == 'true'
|
|
101
|
+
result = Base64::strict_decode64(xml_node.text)
|
|
102
|
+
|
|
103
|
+
# don't pass binary data to the DB.
|
|
104
|
+
if result =~ /\0/
|
|
105
|
+
header, _ = result.split("\r\n\r\n")
|
|
106
|
+
result = header << "\r\n\r\n" << '[Binary Data Not Displayed]'
|
|
107
|
+
end
|
|
108
|
+
else
|
|
109
|
+
result = xml_node.text
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Just in case a null byte was left by Burp
|
|
113
|
+
result.gsub!(/\0/,'�')
|
|
114
|
+
|
|
115
|
+
# We truncate the request/response because it can be pretty big.
|
|
116
|
+
# If it is > 1M MySQL will die when trying to INSERT
|
|
117
|
+
#
|
|
118
|
+
# TODO: maybe add a reference to this node's XPATH so the user can go
|
|
119
|
+
# back to the burp scanner file and look up the original request/response
|
|
120
|
+
result.truncate(50000, omission: '... (truncated)')
|
|
121
|
+
|
|
122
|
+
# Encode the string to UTF-8 to catch invalid bytes.
|
|
123
|
+
result.encode('utf-8', invalid: :replace, undef: :replace, replace: ::Burp::INVALID_UTF_REPLACE)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
data/lib/dradis-burp.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Dradis
|
|
2
|
+
module Plugins
|
|
3
|
+
module Burp
|
|
4
|
+
end
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
require 'dradis/plugins/burp/engine'
|
|
9
|
+
require 'dradis/plugins/burp/field_processor'
|
|
10
|
+
require 'dradis/plugins/burp/html/importer'
|
|
11
|
+
require 'dradis/plugins/burp/version'
|
|
12
|
+
require 'dradis/plugins/burp/xml/importer'
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Dradis
|
|
2
|
+
module Plugins
|
|
3
|
+
module Burp
|
|
4
|
+
class Engine < ::Rails::Engine
|
|
5
|
+
isolate_namespace Dradis::Plugins::Burp
|
|
6
|
+
|
|
7
|
+
include ::Dradis::Plugins::Base
|
|
8
|
+
description 'Processes Burp Scanner output'
|
|
9
|
+
provides :upload
|
|
10
|
+
|
|
11
|
+
# Because this plugin provides two export modules, we have to overwrite
|
|
12
|
+
# the default .uploaders() method.
|
|
13
|
+
#
|
|
14
|
+
# See:
|
|
15
|
+
# Dradis::Plugins::Upload::Base in dradis-plugins
|
|
16
|
+
def self.uploaders
|
|
17
|
+
[
|
|
18
|
+
Dradis::Plugins::Burp::Html,
|
|
19
|
+
Dradis::Plugins::Burp::Xml
|
|
20
|
+
]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|