pwn 0.5.398 → 0.5.400
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 +4 -4
- data/CHANGELOG_BETWEEN_TAGS.txt +181 -180
- data/README.md +3 -3
- data/bin/pwn_burp_suite_pro_active_rest_api_scan +16 -24
- data/bin/pwn_burp_suite_pro_active_scan +16 -25
- data/bin/pwn_zaproxy_active_rest_api_scan +159 -0
- data/bin/{pwn_owasp_zap_active_scan → pwn_zaproxy_active_scan} +59 -50
- data/lib/pwn/plugins/burp_suite.rb +22 -18
- data/lib/pwn/plugins/{owasp_zap.rb → zaproxy.rb} +143 -159
- data/lib/pwn/plugins.rb +1 -1
- data/lib/pwn/version.rb +1 -1
- data/spec/lib/pwn/plugins/{owasp_zap_spec.rb → zaproxy_spec.rb} +3 -3
- metadata +7 -5
@@ -14,8 +14,8 @@ OptionParser.new do |options|
|
|
14
14
|
opts[:target_url] = t
|
15
15
|
end
|
16
16
|
|
17
|
-
options.on('-
|
18
|
-
opts[:
|
17
|
+
options.on('-oDIR', '--report_output_dir=DIR', '<Required - Output Directory for Active Scan Report>') do |o|
|
18
|
+
opts[:output_dir] = o
|
19
19
|
end
|
20
20
|
|
21
21
|
options.on('-eLIST', '--exclude_paths=LIST', '<Optional - Comma-delimited list of paths to exlude from scanning (e.g. "/api/login, /api/logout, /api/etc")>') do |e|
|
@@ -30,6 +30,10 @@ OptionParser.new do |options|
|
|
30
30
|
opts[:headless] = h
|
31
31
|
end
|
32
32
|
|
33
|
+
options.on('-bTYPE', '--browser_type=TYPE', '<Optional - Browser Type <firefox|chrome|headless|rest> (Defaults to chrome)>') do |b|
|
34
|
+
opts[:browser_type] = b
|
35
|
+
end
|
36
|
+
|
33
37
|
options.on('-s', '--[no-]spider', '<Optional - Crawl / Spider Target Prior to Scanning (Defaults to false)>') do |s|
|
34
38
|
opts[:spider] = s
|
35
39
|
end
|
@@ -51,20 +55,19 @@ end
|
|
51
55
|
begin
|
52
56
|
logger = PWN::Plugins::PWNLogger.create
|
53
57
|
|
54
|
-
burp_jar_path = opts[:burp_jar_path]
|
55
|
-
headless = opts[:headless] || false
|
56
|
-
spider = opts[:spider] || false
|
57
58
|
target_url = opts[:target_url]
|
58
59
|
raise 'ERROR: --target_url is required.' if target_url.nil?
|
59
60
|
|
60
|
-
|
61
|
-
raise 'ERROR: --
|
61
|
+
output_dir = opts[:output_dir]
|
62
|
+
raise 'ERROR: --report_output_dir is required.' if output_dir.nil?
|
62
63
|
|
63
64
|
exlude_paths = opts[:exclude_paths]
|
64
65
|
exlude_paths = exlude_paths.split(',').map(&:strip) if exlude_paths.is_a?(String)
|
65
|
-
|
66
|
+
burp_jar_path = opts[:burp_jar_path]
|
67
|
+
headless = opts[:headless] || false
|
68
|
+
browser_type = opts[:browser_type] ||= :chrome
|
69
|
+
spider = opts[:spider] || false
|
66
70
|
navigation_instruct = opts[:navigation_instruct]
|
67
|
-
|
68
71
|
in_scope = opts[:in_scope] ||= target_url
|
69
72
|
|
70
73
|
# ------
|
@@ -77,7 +80,7 @@ begin
|
|
77
80
|
else
|
78
81
|
burp_obj = PWN::Plugins::BurpSuite.start(
|
79
82
|
burp_jar_path: burp_jar_path,
|
80
|
-
browser_type:
|
83
|
+
browser_type: browser_type
|
81
84
|
)
|
82
85
|
end
|
83
86
|
|
@@ -101,7 +104,7 @@ begin
|
|
101
104
|
browser = browser_obj[:browser]
|
102
105
|
browser.goto(target_url)
|
103
106
|
|
104
|
-
|
107
|
+
if navigation_instruct
|
105
108
|
File.read(navigation_instruct).each_line do |instruction|
|
106
109
|
# Look for any set method in this instruction and replace its value w/ asterisks
|
107
110
|
redact_regex = /\.set\(['"]([^'"]*)['"]\)/
|
@@ -112,13 +115,7 @@ begin
|
|
112
115
|
end
|
113
116
|
|
114
117
|
PWN::Plugins::BurpSuite.spider(burp_obj: burp_obj, target_url: in_scope) if spider
|
115
|
-
|
116
|
-
duration = 9
|
117
|
-
print "Waiting #{duration} seconds prior to kicking off active scan..."
|
118
|
-
sleep duration # Sleep for now so everything loads the way we expect - blech.
|
119
|
-
print "\n"
|
120
|
-
|
121
|
-
PWN::Plugins::BurpSuite.invoke_active_scan(
|
118
|
+
PWN::Plugins::BurpSuite.active_scan(
|
122
119
|
burp_obj: burp_obj,
|
123
120
|
target_url: in_scope,
|
124
121
|
exclude_paths: exlude_paths
|
@@ -131,17 +128,11 @@ begin
|
|
131
128
|
# Once DefectDojo begins to support XML report results
|
132
129
|
report_types = %i[html xml]
|
133
130
|
report_types.each do |report_type|
|
134
|
-
this_output_path = "#{output_path}.html"
|
135
|
-
# this_output_path = "#{File.dirname(output_path)}/#{File.basename(output_path, File.extname(output_path))}.html"
|
136
|
-
|
137
|
-
this_output_path = "#{output_path}.xml" if report_type == :xml
|
138
|
-
# this_output_path = "#{File.dirname(output_path)}/#{File.basename(output_path, File.extname(output_path))}.xml" if report_type == :xml
|
139
|
-
|
140
131
|
PWN::Plugins::BurpSuite.generate_scan_report(
|
141
132
|
burp_obj: burp_obj,
|
142
133
|
target_url: in_scope,
|
143
134
|
report_type: report_type,
|
144
|
-
|
135
|
+
output_dir: output_dir
|
145
136
|
)
|
146
137
|
end
|
147
138
|
|
@@ -0,0 +1,159 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'fileutils'
|
5
|
+
require 'pwn'
|
6
|
+
require 'optparse'
|
7
|
+
require 'uri'
|
8
|
+
|
9
|
+
opts = {}
|
10
|
+
OptionParser.new do |options|
|
11
|
+
options.banner = "USAGE:
|
12
|
+
#{File.basename($PROGRAM_NAME)} [opts]
|
13
|
+
"
|
14
|
+
|
15
|
+
options.on('-aAPIKEY', '--api_key=APIKEY', '<Required - OWASP Zap API Key (Tools>Options>API)>') do |a|
|
16
|
+
opts[:api_key] = a
|
17
|
+
end
|
18
|
+
|
19
|
+
options.on('-tTARGET', '--target_url=TARGET', '<Required - Target URI to Scan>') do |t|
|
20
|
+
opts[:target_url] = t
|
21
|
+
end
|
22
|
+
|
23
|
+
options.on('-oDIR', '--report_output_dir=DIR', '<Required - Output Directory for Active Scan Report>') do |o|
|
24
|
+
opts[:output_dir] = o
|
25
|
+
end
|
26
|
+
|
27
|
+
options.on('-dSWAGGER', '--swagger_definitions=SWAGGER', '<Required - Comma-delimited list of Swagger JSON/YAML files to import>') do |s|
|
28
|
+
opts[:swagger_definitions] = s
|
29
|
+
end
|
30
|
+
|
31
|
+
options.on('-zZPATH', '--zap_bin_path=ZPATH', '<Optional - Path to zap.sh>') do |z|
|
32
|
+
opts[:zap_bin_path] = z
|
33
|
+
end
|
34
|
+
|
35
|
+
options.on('-h', '--[no-]headless', '<Optional - Run ZAP and Browser Headless>') do |h|
|
36
|
+
opts[:headless] = h
|
37
|
+
end
|
38
|
+
|
39
|
+
options.on('-D', '--[no-]debug', '<Optional - Enable Debug Output and Do Not Delete Temporary OpenAPI Spec>') do |d|
|
40
|
+
opts[:debug] = d
|
41
|
+
end
|
42
|
+
|
43
|
+
options.on('-vVERSION', '--openapi_spec_version=VERSION', '<Optional - OpenAPI/Swagger Specification Version (Defaults to 3.0.3)>') do |o|
|
44
|
+
opts[:openapi_spec_version] = o
|
45
|
+
end
|
46
|
+
|
47
|
+
options.on('-HJSON', '--additional_http_headers=JSON', '<Optional - JSON string of additional HTTP headers to include in requests (e.g. \'{"Header1":"Value1","Header2":"Value2"}\')>') do |h|
|
48
|
+
opts[:additional_http_headers] = h
|
49
|
+
end
|
50
|
+
|
51
|
+
options.on('-eLIST', '--exclude_paths=LIST', '<Optional - Comma-delimited list of paths to exlude from scanning (e.g. "/api/login, /api/logout, /api/etc")>') do |e|
|
52
|
+
opts[:exclude_paths] = e
|
53
|
+
end
|
54
|
+
|
55
|
+
options.on('-iURL', '--in_scope=URL', '<Optional - URL to add include in scope (Defaults to value of --target_url)>') do |s|
|
56
|
+
opts[:in_scope] = s
|
57
|
+
end
|
58
|
+
end.parse!
|
59
|
+
|
60
|
+
if opts.empty?
|
61
|
+
puts `#{File.basename($PROGRAM_NAME)} --help`
|
62
|
+
exit 1
|
63
|
+
end
|
64
|
+
|
65
|
+
begin
|
66
|
+
timestamp = Time.now.strftime('%Y-%m-%d_%H-%M-%S%Z')
|
67
|
+
logger = PWN::Plugins::PWNLogger.create
|
68
|
+
|
69
|
+
api_key = opts[:api_key]
|
70
|
+
raise 'ERROR: --api_key is required.' if api_key.nil?
|
71
|
+
|
72
|
+
target_url = opts[:target_url]
|
73
|
+
raise 'ERROR: --target_url is required.' if target_url.nil?
|
74
|
+
|
75
|
+
output_dir = opts[:output_dir]
|
76
|
+
raise 'ERROR: --report_output_dir is required.' if output_dir.nil?
|
77
|
+
|
78
|
+
swagger_definitions = opts[:swagger_definitions]
|
79
|
+
raise 'ERROR: --swagger_definitions is required.' if swagger_definitions.nil?
|
80
|
+
|
81
|
+
zap_bin_path = opts[:zap_bin_path]
|
82
|
+
headless = opts[:headless] || false
|
83
|
+
debug = opts[:debug] || false
|
84
|
+
|
85
|
+
swagger_defs_arr = swagger_definitions.split(',').map(&:strip)
|
86
|
+
scheme = URI.parse(target_url).scheme
|
87
|
+
target_host = URI.parse(target_url).host
|
88
|
+
base_url = "#{scheme}://#{target_host}"
|
89
|
+
|
90
|
+
openapi_spec_version = opts[:openapi_spec_version]
|
91
|
+
openapi_spec_root = File.dirname(swagger_defs_arr.first)
|
92
|
+
openapi_spec = "#{openapi_spec_root}/openapi_spec-#{target_host}-#{timestamp}.json"
|
93
|
+
|
94
|
+
PWN::Plugins::OpenAPI.generate_spec(
|
95
|
+
spec_paths: swagger_defs_arr,
|
96
|
+
base_url: base_url,
|
97
|
+
output_json_path: openapi_spec,
|
98
|
+
target_version: openapi_spec_version,
|
99
|
+
debug: debug
|
100
|
+
)
|
101
|
+
|
102
|
+
additional_http_headers = opts[:additional_http_headers]
|
103
|
+
additional_http_headers = JSON.parse(additional_http_headers, symbolize_names: true) if additional_http_headers.is_a?(String)
|
104
|
+
|
105
|
+
exlude_paths = opts[:exclude_paths]
|
106
|
+
exlude_paths = exlude_paths.split(',').map(&:strip) if exlude_paths.is_a?(String)
|
107
|
+
|
108
|
+
in_scope = opts[:in_scope] ||= target_url
|
109
|
+
|
110
|
+
# ------
|
111
|
+
# Open ZAP
|
112
|
+
if headless
|
113
|
+
zap_obj = PWN::Plugins::Zaproxy.start(
|
114
|
+
zap_bin_path: zap_bin_path,
|
115
|
+
headless: headless
|
116
|
+
)
|
117
|
+
else
|
118
|
+
zap_obj = PWN::Plugins::Zaproxy.start(
|
119
|
+
zap_bin_path: zap_bin_path,
|
120
|
+
browser_type: :chrome
|
121
|
+
)
|
122
|
+
end
|
123
|
+
|
124
|
+
logger.info(zap_obj)
|
125
|
+
|
126
|
+
json_sitemap = PWN::Plugins::Zaproxy.import_openapi_to_sitemap(
|
127
|
+
zap_obj: zap_obj,
|
128
|
+
openapi_spec: openapi_spec
|
129
|
+
)
|
130
|
+
|
131
|
+
raise "ERROR: Failed to import OpenAPI/Swagger spec #{openapi_spec} into ZAP's Sitemap." if json_sitemap.nil? || json_sitemap.empty?
|
132
|
+
|
133
|
+
PWN::Plugins::Zaproxy.active_scan(
|
134
|
+
zap_obj: zap_obj,
|
135
|
+
target_url: target_url,
|
136
|
+
exclude_paths: exlude_paths
|
137
|
+
)
|
138
|
+
|
139
|
+
# Dump a list of scan issues from Active Scan result
|
140
|
+
# scan_issues = PWN::Plugins::Zaproxy.get_scan_issues(zap_obj: zap_obj)
|
141
|
+
# puts scan_issues
|
142
|
+
|
143
|
+
# Once DefectDojo begins to support XML report results
|
144
|
+
report_types = %i[html markdown xml]
|
145
|
+
report_types.each do |report_type|
|
146
|
+
PWN::Plugins::Zaproxy.generate_scan_report(
|
147
|
+
zap_obj: zap_obj,
|
148
|
+
target_url: in_scope,
|
149
|
+
report_type: report_type,
|
150
|
+
output_dir: output_dir
|
151
|
+
)
|
152
|
+
end
|
153
|
+
|
154
|
+
zap_obj = PWN::Plugins::Zaproxy.stop(zap_obj: zap_obj)
|
155
|
+
rescue StandardError => e
|
156
|
+
raise e
|
157
|
+
ensure
|
158
|
+
zap_obj = PWN::Plugins::Zaproxy.stop(zap_obj: zap_obj) unless zap_obj.nil?
|
159
|
+
end
|
@@ -22,12 +22,8 @@ OptionParser.new do |options|
|
|
22
22
|
opts[:output_dir] = o
|
23
23
|
end
|
24
24
|
|
25
|
-
options.on('-
|
26
|
-
opts[:
|
27
|
-
end
|
28
|
-
|
29
|
-
options.on('-IINST', '--navigation_instruct=INST', '<Optional - Path to Navigation Instructions (e.g. Auth w/ Target - see /pwn/etc/owasp_zap/navigation.instruct.EXAMPLE)>') do |i|
|
30
|
-
opts[:navigation_instruct] = i
|
25
|
+
options.on('-eLIST', '--exclude_paths=LIST', '<Optional - Comma-delimited list of paths to exlude from scanning (e.g. "/api/login, /api/logout, /api/etc")>') do |e|
|
26
|
+
opts[:exclude_paths] = e
|
31
27
|
end
|
32
28
|
|
33
29
|
options.on('-zZPATH', '--zap_bin_path=ZPATH', '<Optional - Path to zap.sh>') do |z|
|
@@ -38,8 +34,20 @@ OptionParser.new do |options|
|
|
38
34
|
opts[:headless] = h
|
39
35
|
end
|
40
36
|
|
41
|
-
options.on('-
|
42
|
-
opts[:
|
37
|
+
options.on('-bTYPE', '--browser_type=TYPE', '<Optional - Browser Type <firefox|chrome|headless|rest> (Defaults to chrome)>') do |b|
|
38
|
+
opts[:browser_type] = b
|
39
|
+
end
|
40
|
+
|
41
|
+
options.on('-s', '--[no-]spider', '<Optional - Crawl / Spider Target Prior to Scanning (Defaults to false)>') do |s|
|
42
|
+
opts[:spider] = s
|
43
|
+
end
|
44
|
+
|
45
|
+
options.on('-IINST', '--navigation_instruct=INST', '<Optional - Path to Navigation Instructions (e.g. Auth w/ Target - see /pwn/etc/owasp_zap/navigation.instruct.EXAMPLE)>') do |i|
|
46
|
+
opts[:navigation_instruct] = i
|
47
|
+
end
|
48
|
+
|
49
|
+
options.on('-iURL', '--in_scope=URL', '<Optional - URL to add include in scope (Defaults to value of --target_url)>') do |s|
|
50
|
+
opts[:in_scope] = s
|
43
51
|
end
|
44
52
|
end.parse!
|
45
53
|
|
@@ -51,7 +59,8 @@ end
|
|
51
59
|
begin
|
52
60
|
logger = PWN::Plugins::PWNLogger.create
|
53
61
|
|
54
|
-
api_key = opts[:api_key]
|
62
|
+
api_key = opts[:api_key]
|
63
|
+
raise 'ERROR: --api_key is required.' if api_key.nil?
|
55
64
|
|
56
65
|
if opts[:browser_type].nil?
|
57
66
|
browser_type = :chrome
|
@@ -59,64 +68,64 @@ begin
|
|
59
68
|
browser_type = opts[:browser_type].to_s.strip.chomp.scrub.to_sym
|
60
69
|
end
|
61
70
|
|
62
|
-
target_url = opts[:target_url]
|
63
|
-
|
64
|
-
|
71
|
+
target_url = opts[:target_url]
|
72
|
+
raise 'ERROR: --target_url is required.' if target_url.nil?
|
73
|
+
|
74
|
+
output_dir = opts[:output_dir]
|
75
|
+
raise 'ERROR: --report_output_dir is required.' if output_dir.nil?
|
76
|
+
|
77
|
+
exlude_paths = opts[:exclude_paths]
|
78
|
+
exlude_paths = exlude_paths.split(',').map(&:strip) if exlude_paths.is_a?(String)
|
65
79
|
zap_bin_path = opts[:zap_bin_path].to_s.strip.chomp.scrub if File.exist?(opts[:zap_bin_path].to_s.strip.chomp.scrub)
|
66
|
-
headless = opts[:headless]
|
67
|
-
|
80
|
+
headless = opts[:headless] || false
|
81
|
+
browser_type = opts[:browser_type] ||= :chrome
|
82
|
+
spider = opts[:spider] || false
|
83
|
+
navigation_instruct = opts[:navigation_instruct]
|
84
|
+
in_scope = opts[:in_scope] ||= target_url
|
68
85
|
|
69
86
|
# ------
|
70
87
|
# Dynamically build arguments hash based on flags passed and Open Zap
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
88
|
+
if headless
|
89
|
+
zap_obj = PWN::Plugins::Zaproxy.start(
|
90
|
+
zap_bin_path: zap_bin_path,
|
91
|
+
api_key: api_key,
|
92
|
+
headless: headless,
|
93
|
+
browser_type: :headless
|
94
|
+
)
|
95
|
+
else
|
96
|
+
zap_obj = PWN::Plugins::Zaproxy.start(
|
97
|
+
zap_bin_path: zap_bin_path,
|
98
|
+
api_key: api_key,
|
99
|
+
browser_type: browser_type
|
100
|
+
)
|
101
|
+
end
|
77
102
|
|
78
103
|
logger.info(zap_obj)
|
79
104
|
|
80
|
-
browser_obj =
|
81
|
-
browser_type: browser_type,
|
82
|
-
proxy: proxy
|
83
|
-
)
|
105
|
+
browser_obj = zap_obj[:zap_browser]
|
84
106
|
browser = browser_obj[:browser]
|
85
|
-
|
86
|
-
if browser_type == :rest
|
87
|
-
browser.get(target_url)
|
88
|
-
else
|
89
|
-
browser.goto(target_url)
|
90
|
-
end
|
107
|
+
browser.goto(target_url)
|
91
108
|
|
92
109
|
if navigation_instruct
|
93
110
|
File.read(navigation_instruct).each_line do |instruction|
|
111
|
+
# Look for any set method in this instruction and replace its value w/ asterisks
|
112
|
+
redact_regex = /\.set\(['"]([^'"]*)['"]\)/
|
113
|
+
redacted_instruction = instruction.gsub(redact_regex, ".set('********')")
|
114
|
+
print "\nExecuting Instruction: #{redacted_instruction}"
|
94
115
|
browser.instance_eval(instruction.to_s.scrub.strip.chomp)
|
95
116
|
end
|
96
117
|
end
|
97
118
|
|
98
|
-
PWN::Plugins::
|
119
|
+
PWN::Plugins::Zaproxy.spider(zap_obj: zap_obj, target_url: target_url) if spider
|
120
|
+
PWN::Plugins::Zaproxy.active_scan(
|
99
121
|
zap_obj: zap_obj,
|
100
|
-
|
101
|
-
)
|
102
|
-
|
103
|
-
PWN::Plugins::OwaspZap.active_scan(
|
104
|
-
zap_obj: zap_obj,
|
105
|
-
target: target_url
|
122
|
+
target_url: target_url
|
106
123
|
)
|
107
124
|
|
108
125
|
# Generate all Report Types
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
report_type = 'html'
|
113
|
-
when 2
|
114
|
-
report_type = 'markdown'
|
115
|
-
when 3
|
116
|
-
report_type = 'xml'
|
117
|
-
end
|
118
|
-
|
119
|
-
report_path = PWN::Plugins::OwaspZap.generate_report(
|
126
|
+
report_types = %i[html markdown xml]
|
127
|
+
report_types.each do |report_type|
|
128
|
+
report_path = PWN::Plugins::Zaproxy.generate_scan_report(
|
120
129
|
zap_obj: zap_obj,
|
121
130
|
output_dir: output_dir,
|
122
131
|
report_type: report_type
|
@@ -125,10 +134,10 @@ begin
|
|
125
134
|
logger.info("Report can be found here: #{report_path}")
|
126
135
|
end
|
127
136
|
|
128
|
-
PWN::Plugins::
|
137
|
+
PWN::Plugins::Zaproxy.stop(zap_obj: zap_obj)
|
129
138
|
rescue StandardError => e
|
130
139
|
raise e
|
131
140
|
ensure
|
132
|
-
PWN::Plugins::
|
141
|
+
PWN::Plugins::Zaproxy.stop(zap_obj: zap_obj) unless zap_obj.nil?
|
133
142
|
browser_obj = PWN::Plugins::TransparentBrowser.close(browser_obj: browser_obj) unless browser_obj.nil?
|
134
143
|
end
|
@@ -56,7 +56,7 @@ module PWN
|
|
56
56
|
|
57
57
|
public_class_method def self.start(opts = {})
|
58
58
|
burp_jar_path = opts[:burp_jar_path] ||= '/opt/burpsuite/burpsuite-pro.jar'
|
59
|
-
raise
|
59
|
+
raise "ERROR: #{burp_jar_path} not found." unless File.exist?(burp_jar_path)
|
60
60
|
|
61
61
|
raise 'ERROR: /opt/burpsuite/pwn-burp.jar not found. For more details about installing this extension, checkout https://github.com/0dayinc/pwn_burp' unless File.exist?('/opt/burpsuite/pwn-burp.jar')
|
62
62
|
|
@@ -879,13 +879,13 @@ module PWN
|
|
879
879
|
end
|
880
880
|
|
881
881
|
# Supported Method Parameters::
|
882
|
-
# active_scan_url_arr = PWN::Plugins::BurpSuite.
|
882
|
+
# active_scan_url_arr = PWN::Plugins::BurpSuite.active_scan(
|
883
883
|
# burp_obj: 'required - burp_obj returned by #start method',
|
884
884
|
# target_url: 'required - target url to scan in sitemap (should be loaded & authenticated w/ burp_obj[:burp_browser])',
|
885
885
|
# exclude_paths: 'optional - array of paths to exclude from active scan (default: [])'
|
886
886
|
# )
|
887
887
|
|
888
|
-
public_class_method def self.
|
888
|
+
public_class_method def self.active_scan(opts = {})
|
889
889
|
burp_obj = opts[:burp_obj]
|
890
890
|
rest_browser = burp_obj[:rest_browser]
|
891
891
|
pwn_burp_api = burp_obj[:pwn_burp_api]
|
@@ -1016,9 +1016,9 @@ module PWN
|
|
1016
1016
|
# Supported Method Parameters::
|
1017
1017
|
# PWN::Plugins::BurpSuite.generate_scan_report(
|
1018
1018
|
# burp_obj: 'required - burp_obj returned by #start method',
|
1019
|
-
# target_url: 'required - target_url passed to #
|
1020
|
-
#
|
1021
|
-
#
|
1019
|
+
# target_url: 'required - target_url passed to #active_scan method',
|
1020
|
+
# output_dir: 'required - directory to save the report',
|
1021
|
+
# report_type: required - <:html|:xml>'
|
1022
1022
|
# )
|
1023
1023
|
|
1024
1024
|
public_class_method def self.generate_scan_report(opts = {})
|
@@ -1026,16 +1026,20 @@ module PWN
|
|
1026
1026
|
target_url = opts[:target_url]
|
1027
1027
|
rest_browser = burp_obj[:rest_browser]
|
1028
1028
|
pwn_burp_api = burp_obj[:pwn_burp_api]
|
1029
|
+
output_dir = opts[:output_dir]
|
1030
|
+
raise "ERROR: #{output_dir} does not exist." unless Dir.exist?(output_dir)
|
1031
|
+
|
1029
1032
|
report_type = opts[:report_type]
|
1030
|
-
# When pwn_burp begins to support XML report generation
|
1031
|
-
valid_report_types_arr = %i[
|
1032
|
-
html
|
1033
|
-
xml
|
1034
|
-
]
|
1035
1033
|
|
1036
|
-
|
1034
|
+
valid_report_types_arr = %i[html xml]
|
1035
|
+
raise "ERROR: INVALID Report Type => #{report_type}" unless valid_report_types_arr.include?(report_type)
|
1037
1036
|
|
1038
|
-
|
1037
|
+
case report_type
|
1038
|
+
when :html
|
1039
|
+
report_path = "#{output_dir}/burp_active_scan_results.html"
|
1040
|
+
when :xml
|
1041
|
+
report_path = "#{output_dir}/burp_active_scan_results.xml"
|
1042
|
+
end
|
1039
1043
|
|
1040
1044
|
scheme = URI.parse(target_url).scheme
|
1041
1045
|
host = URI.parse(target_url).host
|
@@ -1058,7 +1062,7 @@ module PWN
|
|
1058
1062
|
"http://#{pwn_burp_api}/scanreport/#{report_type.to_s.upcase}/#{report_url}"
|
1059
1063
|
)
|
1060
1064
|
|
1061
|
-
File.open(
|
1065
|
+
File.open(report_path, 'w') do |f|
|
1062
1066
|
f.puts(report_resp.body.gsub("\r\n", "\n"))
|
1063
1067
|
end
|
1064
1068
|
rescue RestClient::BadRequest => e
|
@@ -1198,7 +1202,7 @@ module PWN
|
|
1198
1202
|
comment: 'optional - comment for the sitemap entry (default: \"\")',
|
1199
1203
|
)
|
1200
1204
|
|
1201
|
-
active_scan_url_arr = #{self}.
|
1205
|
+
active_scan_url_arr = #{self}.active_scan(
|
1202
1206
|
burp_obj: 'required - burp_obj returned by #start method',
|
1203
1207
|
target_url: 'required - target url to scan in sitemap (should be loaded & authenticated w/ burp_obj[:burp_browser])',
|
1204
1208
|
exclude_paths: 'optional - array of paths to exclude from active scan (default: [])'
|
@@ -1210,9 +1214,9 @@ module PWN
|
|
1210
1214
|
|
1211
1215
|
#{self}.generate_scan_report(
|
1212
1216
|
burp_obj: 'required - burp_obj returned by #start method',
|
1213
|
-
target_url: 'required - target_url passed to #
|
1214
|
-
|
1215
|
-
|
1217
|
+
target_url: 'required - target_url passed to #active_scan method',
|
1218
|
+
output_dir: 'required - directory to save the report',
|
1219
|
+
report_type: 'required - <:html|:xml>'
|
1216
1220
|
)
|
1217
1221
|
|
1218
1222
|
#{self}.stop(
|