pwn 0.5.401 → 0.5.402
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/README.md +3 -3
- data/bin/pwn_burp_suite_pro_active_rest_api_scan +9 -5
- data/bin/pwn_burp_suite_pro_active_scan +6 -7
- data/bin/pwn_zaproxy_active_rest_api_scan +18 -7
- data/bin/pwn_zaproxy_active_scan +14 -15
- data/lib/pwn/plugins/burp_suite.rb +51 -51
- data/lib/pwn/plugins/transparent_browser.rb +2 -1
- data/lib/pwn/plugins/zaproxy.rb +86 -82
- data/lib/pwn/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13bfbc8e974f5f40d0e78a9081d9ade50ecbbcedbde8f7d6df60e43535e7a3ef
|
4
|
+
data.tar.gz: 275421f89482553cc5887d6806d84907230636db4b7a0a48c620fc69df7d3e68
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c147247d6cc1214be92cf53af46318c63a5678183db2c743c247f9f1ae70ffb7c2719cb585e6074b55ce239a17c9167a88d00cc0823accb26feb5b517b645553
|
7
|
+
data.tar.gz: 6be749ad84718f956de12db9f47729eff67746177ffb3c568d7c17bebdcd948e2f97830e9c9c8ff3c2fb5dcea1c367ae27282843bd07ef02e9ad429cce3bfba8
|
data/README.md
CHANGED
@@ -37,7 +37,7 @@ $ cd /opt/pwn
|
|
37
37
|
$ ./install.sh
|
38
38
|
$ ./install.sh ruby-gem
|
39
39
|
$ pwn
|
40
|
-
pwn[v0.5.
|
40
|
+
pwn[v0.5.402]:001 >>> PWN.help
|
41
41
|
```
|
42
42
|
|
43
43
|
[](https://youtu.be/G7iLUY4FzsI)
|
@@ -52,7 +52,7 @@ $ rvm use ruby-3.4.4@pwn
|
|
52
52
|
$ gem uninstall --all --executables pwn
|
53
53
|
$ gem install --verbose pwn
|
54
54
|
$ pwn
|
55
|
-
pwn[v0.5.
|
55
|
+
pwn[v0.5.402]:001 >>> PWN.help
|
56
56
|
```
|
57
57
|
|
58
58
|
If you're using a multi-user install of RVM do:
|
@@ -62,7 +62,7 @@ $ rvm use ruby-3.4.4@pwn
|
|
62
62
|
$ rvmsudo gem uninstall --all --executables pwn
|
63
63
|
$ rvmsudo gem install --verbose pwn
|
64
64
|
$ pwn
|
65
|
-
pwn[v0.5.
|
65
|
+
pwn[v0.5.402]:001 >>> PWN.help
|
66
66
|
```
|
67
67
|
|
68
68
|
PWN periodically upgrades to the latest version of Ruby which is reflected in `/opt/pwn/.ruby-version`. The easiest way to upgrade to the latest version of Ruby from a previous PWN installation is to run the following script:
|
@@ -31,6 +31,10 @@ OptionParser.new do |options|
|
|
31
31
|
opts[:headless] = h
|
32
32
|
end
|
33
33
|
|
34
|
+
options.on('-bTYPE', '--browser_type=TYPE', '<Optional - Browser Type <firefox|chrome|headless|rest> (Defaults to firefox)>') do |b|
|
35
|
+
opts[:browser_type] = b
|
36
|
+
end
|
37
|
+
|
34
38
|
options.on('-D', '--[no-]debug', '<Optional - Enable Debug Output and Do Not Delete Temporary OpenAPI Spec>') do |d|
|
35
39
|
opts[:debug] = d
|
36
40
|
end
|
@@ -55,7 +59,7 @@ OptionParser.new do |options|
|
|
55
59
|
opts[:exclude_paths] = e
|
56
60
|
end
|
57
61
|
|
58
|
-
options.on('-iURL', '--in_scope=URL', '<Optional - URL to
|
62
|
+
options.on('-iURL', '--in_scope=URL', '<Optional - URL to include in scope (Defaults to value of --target_url)>') do |s|
|
59
63
|
opts[:in_scope] = s
|
60
64
|
end
|
61
65
|
end.parse!
|
@@ -80,6 +84,8 @@ begin
|
|
80
84
|
|
81
85
|
burp_jar_path = opts[:burp_jar_path]
|
82
86
|
headless = opts[:headless] || false
|
87
|
+
browser_type = opts[:browser_type] ||= :firefox
|
88
|
+
browser_type = browser_type.to_s.downcase.to_sym unless browser_type.is_a?(Symbol)
|
83
89
|
debug = opts[:debug] || false
|
84
90
|
|
85
91
|
swagger_defs_arr = swagger_definitions.split(',').map(&:strip)
|
@@ -120,7 +126,7 @@ begin
|
|
120
126
|
else
|
121
127
|
burp_obj = PWN::Plugins::BurpSuite.start(
|
122
128
|
burp_jar_path: burp_jar_path,
|
123
|
-
browser_type:
|
129
|
+
browser_type: browser_type
|
124
130
|
)
|
125
131
|
end
|
126
132
|
|
@@ -165,10 +171,8 @@ begin
|
|
165
171
|
output_dir: output_dir
|
166
172
|
)
|
167
173
|
end
|
168
|
-
|
169
|
-
burp_obj = PWN::Plugins::BurpSuite.stop(burp_obj: burp_obj)
|
170
174
|
rescue StandardError => e
|
171
175
|
raise e
|
172
176
|
ensure
|
173
|
-
|
177
|
+
PWN::Plugins::BurpSuite.stop(burp_obj: burp_obj) unless burp_obj.nil?
|
174
178
|
end
|
@@ -30,7 +30,7 @@ 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
|
33
|
+
options.on('-bTYPE', '--browser_type=TYPE', '<Optional - Browser Type <firefox|chrome|headless|rest> (Defaults to firefox)>') do |b|
|
34
34
|
opts[:browser_type] = b
|
35
35
|
end
|
36
36
|
|
@@ -42,7 +42,7 @@ OptionParser.new do |options|
|
|
42
42
|
opts[:navigation_instruct] = i
|
43
43
|
end
|
44
44
|
|
45
|
-
options.on('-iURL', '--in_scope=URL', '<Optional - URL to
|
45
|
+
options.on('-iURL', '--in_scope=URL', '<Optional - URL to include in scope (Defaults to value of --target_url)>') do |s|
|
46
46
|
opts[:in_scope] = s
|
47
47
|
end
|
48
48
|
end.parse!
|
@@ -65,7 +65,8 @@ begin
|
|
65
65
|
exlude_paths = exlude_paths.split(',').map(&:strip) if exlude_paths.is_a?(String)
|
66
66
|
burp_jar_path = opts[:burp_jar_path]
|
67
67
|
headless = opts[:headless] || false
|
68
|
-
browser_type = opts[:browser_type] ||= :
|
68
|
+
browser_type = opts[:browser_type] ||= :firefox
|
69
|
+
browser_type = browser_type.to_s.downcase.to_sym unless browser_type.is_a?(Symbol)
|
69
70
|
spider = opts[:spider] || false
|
70
71
|
navigation_instruct = opts[:navigation_instruct]
|
71
72
|
in_scope = opts[:in_scope] ||= target_url
|
@@ -100,7 +101,7 @@ begin
|
|
100
101
|
# support JavaScript, DOM-based XSS vuln attempts are
|
101
102
|
# possible as well since we have a DOM to interact w/
|
102
103
|
# (Burp's DOM-XSS checks are based on static code analysis)
|
103
|
-
browser_obj = burp_obj[:
|
104
|
+
browser_obj = burp_obj[:mitm_browser]
|
104
105
|
browser = browser_obj[:browser]
|
105
106
|
browser.goto(target_url)
|
106
107
|
|
@@ -135,10 +136,8 @@ begin
|
|
135
136
|
output_dir: output_dir
|
136
137
|
)
|
137
138
|
end
|
138
|
-
|
139
|
-
burp_obj = PWN::Plugins::BurpSuite.stop(burp_obj: burp_obj)
|
140
139
|
rescue StandardError => e
|
141
140
|
raise e
|
142
141
|
ensure
|
143
|
-
|
142
|
+
PWN::Plugins::BurpSuite.stop(burp_obj: burp_obj) unless burp_obj.nil?
|
144
143
|
end
|
@@ -36,6 +36,10 @@ OptionParser.new do |options|
|
|
36
36
|
opts[:headless] = h
|
37
37
|
end
|
38
38
|
|
39
|
+
options.on('-bTYPE', '--browser_type=TYPE', '<Optional - Browser Type <firefox|chrome|headless|rest> (Defaults to firefox)>') do |b|
|
40
|
+
opts[:browser_type] = b
|
41
|
+
end
|
42
|
+
|
39
43
|
options.on('-D', '--[no-]debug', '<Optional - Enable Debug Output and Do Not Delete Temporary OpenAPI Spec>') do |d|
|
40
44
|
opts[:debug] = d
|
41
45
|
end
|
@@ -52,7 +56,7 @@ OptionParser.new do |options|
|
|
52
56
|
opts[:exclude_paths] = e
|
53
57
|
end
|
54
58
|
|
55
|
-
options.on('-iURL', '--in_scope=URL', '<Optional - URL to
|
59
|
+
options.on('-iURL', '--in_scope=URL', '<Optional - URL regex to include in scope (Defaults to "<target_url>.*")>') do |s|
|
56
60
|
opts[:in_scope] = s
|
57
61
|
end
|
58
62
|
end.parse!
|
@@ -80,6 +84,8 @@ begin
|
|
80
84
|
|
81
85
|
zap_bin_path = opts[:zap_bin_path]
|
82
86
|
headless = opts[:headless] || false
|
87
|
+
browser_type = opts[:browser_type] ||= :firefox
|
88
|
+
browser_type = browser_type.to_s.downcase.to_sym unless browser_type.is_a?(Symbol)
|
83
89
|
debug = opts[:debug] || false
|
84
90
|
|
85
91
|
swagger_defs_arr = swagger_definitions.split(',').map(&:strip)
|
@@ -105,7 +111,7 @@ begin
|
|
105
111
|
exlude_paths = opts[:exclude_paths]
|
106
112
|
exlude_paths = exlude_paths.split(',').map(&:strip) if exlude_paths.is_a?(String)
|
107
113
|
|
108
|
-
in_scope = opts[:in_scope] ||= target_url
|
114
|
+
in_scope = opts[:in_scope] ||= "#{target_url}.*"
|
109
115
|
|
110
116
|
# ------
|
111
117
|
# Open ZAP
|
@@ -117,7 +123,7 @@ begin
|
|
117
123
|
else
|
118
124
|
zap_obj = PWN::Plugins::Zaproxy.start(
|
119
125
|
zap_bin_path: zap_bin_path,
|
120
|
-
browser_type:
|
126
|
+
browser_type: browser_type
|
121
127
|
)
|
122
128
|
end
|
123
129
|
|
@@ -128,11 +134,18 @@ begin
|
|
128
134
|
openapi_spec: openapi_spec
|
129
135
|
)
|
130
136
|
|
137
|
+
# TODO: Initialize authorization header if required by API
|
138
|
+
|
131
139
|
raise "ERROR: Failed to import OpenAPI/Swagger spec #{openapi_spec} into ZAP's Sitemap." if json_sitemap.nil? || json_sitemap.empty?
|
132
140
|
|
141
|
+
PWN::Plugins::Zaproxy.add_to_scope(
|
142
|
+
zap_obj: zap_obj,
|
143
|
+
target_regex: in_scope
|
144
|
+
)
|
145
|
+
|
133
146
|
PWN::Plugins::Zaproxy.active_scan(
|
134
147
|
zap_obj: zap_obj,
|
135
|
-
target_url:
|
148
|
+
target_url: in_scope,
|
136
149
|
exclude_paths: exlude_paths
|
137
150
|
)
|
138
151
|
|
@@ -150,10 +163,8 @@ begin
|
|
150
163
|
output_dir: output_dir
|
151
164
|
)
|
152
165
|
end
|
153
|
-
|
154
|
-
zap_obj = PWN::Plugins::Zaproxy.stop(zap_obj: zap_obj)
|
155
166
|
rescue StandardError => e
|
156
167
|
raise e
|
157
168
|
ensure
|
158
|
-
|
169
|
+
PWN::Plugins::Zaproxy.stop(zap_obj: zap_obj) unless zap_obj.nil?
|
159
170
|
end
|
data/bin/pwn_zaproxy_active_scan
CHANGED
@@ -34,7 +34,7 @@ OptionParser.new do |options|
|
|
34
34
|
opts[:headless] = h
|
35
35
|
end
|
36
36
|
|
37
|
-
options.on('-bTYPE', '--browser_type=TYPE', '<Optional - Browser Type <firefox|chrome|headless|rest> (Defaults to
|
37
|
+
options.on('-bTYPE', '--browser_type=TYPE', '<Optional - Browser Type <firefox|chrome|headless|rest> (Defaults to firefox)>') do |b|
|
38
38
|
opts[:browser_type] = b
|
39
39
|
end
|
40
40
|
|
@@ -46,7 +46,7 @@ OptionParser.new do |options|
|
|
46
46
|
opts[:navigation_instruct] = i
|
47
47
|
end
|
48
48
|
|
49
|
-
options.on('-iURL', '--in_scope=URL', '<Optional - URL to
|
49
|
+
options.on('-iURL', '--in_scope=URL', '<Optional - URL regex to include in scope (Defaults to "<target_url>.*")>') do |s|
|
50
50
|
opts[:in_scope] = s
|
51
51
|
end
|
52
52
|
end.parse!
|
@@ -62,12 +62,6 @@ begin
|
|
62
62
|
api_key = opts[:api_key]
|
63
63
|
raise 'ERROR: --api_key is required.' if api_key.nil?
|
64
64
|
|
65
|
-
if opts[:browser_type].nil?
|
66
|
-
browser_type = :chrome
|
67
|
-
else
|
68
|
-
browser_type = opts[:browser_type].to_s.strip.chomp.scrub.to_sym
|
69
|
-
end
|
70
|
-
|
71
65
|
target_url = opts[:target_url]
|
72
66
|
raise 'ERROR: --target_url is required.' if target_url.nil?
|
73
67
|
|
@@ -78,10 +72,11 @@ begin
|
|
78
72
|
exlude_paths = exlude_paths.split(',').map(&:strip) if exlude_paths.is_a?(String)
|
79
73
|
zap_bin_path = opts[:zap_bin_path].to_s.strip.chomp.scrub if File.exist?(opts[:zap_bin_path].to_s.strip.chomp.scrub)
|
80
74
|
headless = opts[:headless] || false
|
81
|
-
browser_type = opts[:browser_type] ||= :
|
75
|
+
browser_type = opts[:browser_type] ||= :firefox
|
76
|
+
browser_type = browser_type.to_s.downcase.to_sym unless browser_type.is_a?(Symbol)
|
82
77
|
spider = opts[:spider] || false
|
83
78
|
navigation_instruct = opts[:navigation_instruct]
|
84
|
-
in_scope = opts[:in_scope] ||= target_url
|
79
|
+
in_scope = opts[:in_scope] ||= "#{target_url}.*"
|
85
80
|
|
86
81
|
# ------
|
87
82
|
# Dynamically build arguments hash based on flags passed and Open Zap
|
@@ -102,7 +97,7 @@ begin
|
|
102
97
|
|
103
98
|
logger.info(zap_obj)
|
104
99
|
|
105
|
-
browser_obj = zap_obj[:
|
100
|
+
browser_obj = zap_obj[:mitm_browser]
|
106
101
|
browser = browser_obj[:browser]
|
107
102
|
browser.goto(target_url)
|
108
103
|
|
@@ -117,9 +112,16 @@ begin
|
|
117
112
|
end
|
118
113
|
|
119
114
|
PWN::Plugins::Zaproxy.spider(zap_obj: zap_obj, target_url: target_url) if spider
|
115
|
+
|
116
|
+
PWN::Plugins::Zaproxy.add_to_scope(
|
117
|
+
zap_obj: zap_obj,
|
118
|
+
target_regex: in_scope
|
119
|
+
)
|
120
|
+
|
120
121
|
PWN::Plugins::Zaproxy.active_scan(
|
121
122
|
zap_obj: zap_obj,
|
122
|
-
target_url:
|
123
|
+
target_url: in_scope,
|
124
|
+
exclude_paths: exlude_paths
|
123
125
|
)
|
124
126
|
|
125
127
|
# Generate all Report Types
|
@@ -133,11 +135,8 @@ begin
|
|
133
135
|
|
134
136
|
logger.info("Report can be found here: #{report_path}")
|
135
137
|
end
|
136
|
-
|
137
|
-
PWN::Plugins::Zaproxy.stop(zap_obj: zap_obj)
|
138
138
|
rescue StandardError => e
|
139
139
|
raise e
|
140
140
|
ensure
|
141
141
|
PWN::Plugins::Zaproxy.stop(zap_obj: zap_obj) unless zap_obj.nil?
|
142
|
-
browser_obj = PWN::Plugins::TransparentBrowser.close(browser_obj: browser_obj) unless browser_obj.nil?
|
143
142
|
end
|
@@ -82,7 +82,7 @@ module PWN
|
|
82
82
|
rest_browser = browser_obj1[:browser]
|
83
83
|
|
84
84
|
burp_obj[:mitm_proxy] = "#{burp_ip}:#{burp_port}"
|
85
|
-
burp_obj[:
|
85
|
+
burp_obj[:mitm_rest_api] = "#{pwn_burp_ip}:#{pwn_burp_port}"
|
86
86
|
burp_obj[:rest_browser] = rest_browser
|
87
87
|
|
88
88
|
# Proxy always listens on localhost...use SSH tunneling if remote access is required
|
@@ -92,7 +92,7 @@ module PWN
|
|
92
92
|
devtools: true
|
93
93
|
)
|
94
94
|
|
95
|
-
burp_obj[:
|
95
|
+
burp_obj[:mitm_browser] = browser_obj2
|
96
96
|
|
97
97
|
# Wait for pwn_burp_port to open prior to returning burp_obj
|
98
98
|
loop do
|
@@ -133,11 +133,11 @@ module PWN
|
|
133
133
|
raise 'ERROR: uri parameter is required' if uri.nil?
|
134
134
|
|
135
135
|
rest_browser = burp_obj[:rest_browser]
|
136
|
-
|
136
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
137
137
|
base64_encoded_uri = Base64.strict_encode64(uri.to_s.scrub.strip.chomp)
|
138
138
|
|
139
139
|
in_scope_resp = rest_browser.get(
|
140
|
-
"http://#{
|
140
|
+
"http://#{mitm_rest_api}/scope/#{base64_encoded_uri}",
|
141
141
|
content_type: 'application/json; charset=UTF8'
|
142
142
|
)
|
143
143
|
json_in_scope = JSON.parse(in_scope_resp, symbolize_names: true)
|
@@ -156,11 +156,11 @@ module PWN
|
|
156
156
|
burp_obj = opts[:burp_obj]
|
157
157
|
target_url = opts[:target_url]
|
158
158
|
rest_browser = burp_obj[:rest_browser]
|
159
|
-
|
159
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
160
160
|
|
161
161
|
post_body = { url: target_url }.to_json
|
162
162
|
|
163
|
-
in_scope = rest_browser.post("http://#{
|
163
|
+
in_scope = rest_browser.post("http://#{mitm_rest_api}/scope", post_body, content_type: 'application/json; charset=UTF8')
|
164
164
|
JSON.parse(in_scope, symbolize_names: true)
|
165
165
|
rescue StandardError => e
|
166
166
|
stop(burp_obj: burp_obj) unless burp_obj.nil?
|
@@ -177,12 +177,12 @@ module PWN
|
|
177
177
|
burp_obj = opts[:burp_obj]
|
178
178
|
target_url = opts[:target_url]
|
179
179
|
rest_browser = burp_obj[:rest_browser]
|
180
|
-
|
180
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
181
181
|
|
182
182
|
post_body = { url: target_url }.to_json
|
183
183
|
|
184
184
|
in_scope = rest_browser.post(
|
185
|
-
"http://#{
|
185
|
+
"http://#{mitm_rest_api}/spider",
|
186
186
|
post_body,
|
187
187
|
content_type: 'application/json; charset=UTF8'
|
188
188
|
)
|
@@ -192,7 +192,7 @@ module PWN
|
|
192
192
|
spider_status_json = {}
|
193
193
|
loop do
|
194
194
|
print '.'
|
195
|
-
spider_status_resp = rest_browser.get("http://#{
|
195
|
+
spider_status_resp = rest_browser.get("http://#{mitm_rest_api}/spider/#{spider_id}")
|
196
196
|
spider_status_json = JSON.parse(spider_status_resp, symbolize_names: true)
|
197
197
|
spider_status = spider_status_json[:status]
|
198
198
|
case spider_status
|
@@ -221,9 +221,9 @@ module PWN
|
|
221
221
|
public_class_method def self.enable_proxy(opts = {})
|
222
222
|
burp_obj = opts[:burp_obj]
|
223
223
|
rest_browser = burp_obj[:rest_browser]
|
224
|
-
|
224
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
225
225
|
|
226
|
-
enable_resp = rest_browser.post("http://#{
|
226
|
+
enable_resp = rest_browser.post("http://#{mitm_rest_api}/proxy/intercept/enable", nil)
|
227
227
|
JSON.parse(enable_resp, symbolize_names: true)
|
228
228
|
rescue StandardError => e
|
229
229
|
stop(burp_obj: burp_obj) unless burp_obj.nil?
|
@@ -238,9 +238,9 @@ module PWN
|
|
238
238
|
public_class_method def self.disable_proxy(opts = {})
|
239
239
|
burp_obj = opts[:burp_obj]
|
240
240
|
rest_browser = burp_obj[:rest_browser]
|
241
|
-
|
241
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
242
242
|
|
243
|
-
disable_resp = rest_browser.post("http://#{
|
243
|
+
disable_resp = rest_browser.post("http://#{mitm_rest_api}/proxy/intercept/disable", nil)
|
244
244
|
JSON.parse(disable_resp, symbolize_names: true)
|
245
245
|
rescue StandardError => e
|
246
246
|
stop(burp_obj: burp_obj) unless burp_obj.nil?
|
@@ -255,9 +255,9 @@ module PWN
|
|
255
255
|
public_class_method def self.get_proxy_listeners(opts = {})
|
256
256
|
burp_obj = opts[:burp_obj]
|
257
257
|
rest_browser = burp_obj[:rest_browser]
|
258
|
-
|
258
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
259
259
|
|
260
|
-
listeners = rest_browser.get("http://#{
|
260
|
+
listeners = rest_browser.get("http://#{mitm_rest_api}/proxy/listeners", content_type: 'application/json; charset=UTF8')
|
261
261
|
JSON.parse(listeners, symbolize_names: true)
|
262
262
|
rescue StandardError => e
|
263
263
|
stop(burp_obj: burp_obj) unless burp_obj.nil?
|
@@ -275,7 +275,7 @@ module PWN
|
|
275
275
|
public_class_method def self.add_proxy_listener(opts = {})
|
276
276
|
burp_obj = opts[:burp_obj]
|
277
277
|
rest_browser = burp_obj[:rest_browser]
|
278
|
-
|
278
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
279
279
|
bind_address = opts[:bind_address]
|
280
280
|
raise 'ERROR: bind_address parameter is required' if bind_address.nil?
|
281
281
|
|
@@ -295,7 +295,7 @@ module PWN
|
|
295
295
|
enabled: enabled
|
296
296
|
}.to_json
|
297
297
|
|
298
|
-
listener = rest_browser.post("http://#{
|
298
|
+
listener = rest_browser.post("http://#{mitm_rest_api}/proxy/listeners", post_body, content_type: 'application/json; charset=UTF8')
|
299
299
|
JSON.parse(listener, symbolize_names: true)
|
300
300
|
rescue StandardError => e
|
301
301
|
stop(burp_obj: burp_obj) unless burp_obj.nil?
|
@@ -314,7 +314,7 @@ module PWN
|
|
314
314
|
public_class_method def self.update_proxy_listener(opts = {})
|
315
315
|
burp_obj = opts[:burp_obj]
|
316
316
|
rest_browser = burp_obj[:rest_browser]
|
317
|
-
|
317
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
318
318
|
id = opts[:id] ||= '0'
|
319
319
|
bind_address = opts[:bind_address] ||= '127.0.0.1'
|
320
320
|
port = opts[:port] ||= 8080
|
@@ -327,7 +327,7 @@ module PWN
|
|
327
327
|
enabled: enabled
|
328
328
|
}.to_json
|
329
329
|
|
330
|
-
listener = rest_browser.put("http://#{
|
330
|
+
listener = rest_browser.put("http://#{mitm_rest_api}/proxy/listeners/#{id}", post_body, content_type: 'application/json; charset=UTF8')
|
331
331
|
JSON.parse(listener, symbolize_names: true)
|
332
332
|
rescue StandardError => e
|
333
333
|
stop(burp_obj: burp_obj) unless burp_obj.nil?
|
@@ -343,11 +343,11 @@ module PWN
|
|
343
343
|
public_class_method def self.delete_proxy_listener(opts = {})
|
344
344
|
burp_obj = opts[:burp_obj]
|
345
345
|
rest_browser = burp_obj[:rest_browser]
|
346
|
-
|
346
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
347
347
|
id = opts[:id] ||= '0'
|
348
348
|
raise 'ERROR: id parameter is required' if id.nil?
|
349
349
|
|
350
|
-
rest_browser.delete("http://#{
|
350
|
+
rest_browser.delete("http://#{mitm_rest_api}/proxy/listeners/#{id}")
|
351
351
|
true # Return true to indicate successful deletion (or error if API fails)
|
352
352
|
rescue StandardError => e
|
353
353
|
stop(burp_obj: burp_obj) unless burp_obj.nil?
|
@@ -363,12 +363,12 @@ module PWN
|
|
363
363
|
public_class_method def self.get_sitemap(opts = {})
|
364
364
|
burp_obj = opts[:burp_obj]
|
365
365
|
rest_browser = burp_obj[:rest_browser]
|
366
|
-
|
366
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
367
367
|
target_url = opts[:target_url]
|
368
368
|
|
369
369
|
base64_encoded_target_url = Base64.strict_encode64(target_url.to_s.scrub.strip.chomp) if target_url
|
370
370
|
|
371
|
-
rest_call = "http://#{
|
371
|
+
rest_call = "http://#{mitm_rest_api}/sitemap"
|
372
372
|
rest_call = "#{rest_call}/#{base64_encoded_target_url}" if target_url
|
373
373
|
|
374
374
|
sitemap = rest_browser.get(
|
@@ -407,14 +407,14 @@ module PWN
|
|
407
407
|
public_class_method def self.add_to_sitemap(opts = {})
|
408
408
|
burp_obj = opts[:burp_obj]
|
409
409
|
rest_browser = burp_obj[:rest_browser]
|
410
|
-
|
410
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
411
411
|
sitemap = opts[:sitemap] ||= {}
|
412
412
|
debug = opts[:debug] || false
|
413
413
|
|
414
414
|
rest_client = rest_browser::Request
|
415
415
|
response = rest_client.execute(
|
416
416
|
method: :post,
|
417
|
-
url: "http://#{
|
417
|
+
url: "http://#{mitm_rest_api}/sitemap",
|
418
418
|
payload: sitemap.to_json,
|
419
419
|
headers: { content_type: 'application/json; charset=UTF-8' },
|
420
420
|
timeout: 10
|
@@ -881,14 +881,14 @@ module PWN
|
|
881
881
|
# Supported Method Parameters::
|
882
882
|
# active_scan_url_arr = PWN::Plugins::BurpSuite.active_scan(
|
883
883
|
# burp_obj: 'required - burp_obj returned by #start method',
|
884
|
-
# target_url: 'required - target url to scan in sitemap (should be loaded & authenticated w/ burp_obj[:
|
884
|
+
# target_url: 'required - target url to scan in sitemap (should be loaded & authenticated w/ burp_obj[:mitm_browser])',
|
885
885
|
# exclude_paths: 'optional - array of paths to exclude from active scan (default: [])'
|
886
886
|
# )
|
887
887
|
|
888
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
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
892
892
|
target_url = opts[:target_url].to_s.scrub.strip.chomp
|
893
893
|
raise 'ERROR: target_url parameter is required' if target_url.empty?
|
894
894
|
|
@@ -947,7 +947,7 @@ module PWN
|
|
947
947
|
}.to_json
|
948
948
|
# Kick off an active scan for each given page in the json_sitemap results
|
949
949
|
resp = rest_browser.post(
|
950
|
-
"http://#{
|
950
|
+
"http://#{mitm_rest_api}/scan/active",
|
951
951
|
post_body,
|
952
952
|
content_type: 'application/json'
|
953
953
|
)
|
@@ -959,7 +959,7 @@ module PWN
|
|
959
959
|
|
960
960
|
# Wait for scan completion
|
961
961
|
loop do
|
962
|
-
scan_queue = rest_browser.get("http://#{
|
962
|
+
scan_queue = rest_browser.get("http://#{mitm_rest_api}/scan/active")
|
963
963
|
json_scan_queue = JSON.parse(scan_queue, symbolize_names: true)
|
964
964
|
break if json_scan_queue.all? { |scan| scan[:status] == 'finished' }
|
965
965
|
|
@@ -975,7 +975,7 @@ module PWN
|
|
975
975
|
# json_scan_queue.each do |scan_item|
|
976
976
|
# this_scan_item_id = scan_item[:id]
|
977
977
|
# until scan_item[:status] == 'finished'
|
978
|
-
# scan_item_resp = rest_browser.get("http://#{
|
978
|
+
# scan_item_resp = rest_browser.get("http://#{mitm_rest_api}/scan/active/#{this_scan_item_id}")
|
979
979
|
# scan_item = JSON.parse(scan_item_resp, symbolize_names: true)
|
980
980
|
# scan_status = scan_item[:status]
|
981
981
|
# puts "Target ID ##{this_scan_item_id} of ##{scan_queue_total}| #{scan_status}"
|
@@ -999,12 +999,12 @@ module PWN
|
|
999
999
|
public_class_method def self.get_scan_issues(opts = {})
|
1000
1000
|
burp_obj = opts[:burp_obj]
|
1001
1001
|
rest_browser = burp_obj[:rest_browser]
|
1002
|
-
|
1002
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
1003
1003
|
|
1004
1004
|
rest_client = rest_browser::Request
|
1005
1005
|
scan_issues = rest_client.execute(
|
1006
1006
|
method: :get,
|
1007
|
-
url: "http://#{
|
1007
|
+
url: "http://#{mitm_rest_api}/scanissues",
|
1008
1008
|
timeout: 540
|
1009
1009
|
)
|
1010
1010
|
JSON.parse(scan_issues, symbolize_names: true)
|
@@ -1031,7 +1031,7 @@ module PWN
|
|
1031
1031
|
raise 'ERROR: request parameter is required' if request.nil?
|
1032
1032
|
|
1033
1033
|
rest_browser = burp_obj[:rest_browser]
|
1034
|
-
|
1034
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
1035
1035
|
|
1036
1036
|
post_body = {
|
1037
1037
|
name: name[0..29],
|
@@ -1039,7 +1039,7 @@ module PWN
|
|
1039
1039
|
}.to_json
|
1040
1040
|
|
1041
1041
|
repeater_resp = rest_browser.post(
|
1042
|
-
"http://#{
|
1042
|
+
"http://#{mitm_rest_api}/repeater",
|
1043
1043
|
post_body,
|
1044
1044
|
content_type: 'application/json; charset=UTF8'
|
1045
1045
|
)
|
@@ -1060,10 +1060,10 @@ module PWN
|
|
1060
1060
|
raise 'ERROR: burp_obj parameter is required' unless burp_obj.is_a?(Hash)
|
1061
1061
|
|
1062
1062
|
rest_browser = burp_obj[:rest_browser]
|
1063
|
-
|
1063
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
1064
1064
|
|
1065
1065
|
repeater_resp = rest_browser.get(
|
1066
|
-
"http://#{
|
1066
|
+
"http://#{mitm_rest_api}/repeater",
|
1067
1067
|
content_type: 'application/json; charset=UTF8'
|
1068
1068
|
)
|
1069
1069
|
|
@@ -1086,10 +1086,10 @@ module PWN
|
|
1086
1086
|
raise 'ERROR: id parameter is required' if id.nil?
|
1087
1087
|
|
1088
1088
|
rest_browser = burp_obj[:rest_browser]
|
1089
|
-
|
1089
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
1090
1090
|
|
1091
1091
|
repeater_resp = rest_browser.get(
|
1092
|
-
"http://#{
|
1092
|
+
"http://#{mitm_rest_api}/repeater/#{id}",
|
1093
1093
|
content_type: 'application/json; charset=UTF8'
|
1094
1094
|
)
|
1095
1095
|
|
@@ -1112,10 +1112,10 @@ module PWN
|
|
1112
1112
|
raise 'ERROR: id parameter is required' if id.nil?
|
1113
1113
|
|
1114
1114
|
rest_browser = burp_obj[:rest_browser]
|
1115
|
-
|
1115
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
1116
1116
|
|
1117
1117
|
repeater_resp = rest_browser.post(
|
1118
|
-
"http://#{
|
1118
|
+
"http://#{mitm_rest_api}/repeater/#{id}/send",
|
1119
1119
|
content_type: 'application/json; charset=UTF8'
|
1120
1120
|
)
|
1121
1121
|
|
@@ -1146,7 +1146,7 @@ module PWN
|
|
1146
1146
|
raise 'ERROR: request parameter is required' if request.nil?
|
1147
1147
|
|
1148
1148
|
rest_browser = burp_obj[:rest_browser]
|
1149
|
-
|
1149
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
1150
1150
|
|
1151
1151
|
put_body = {
|
1152
1152
|
name: name[0..29],
|
@@ -1154,7 +1154,7 @@ module PWN
|
|
1154
1154
|
}.to_json
|
1155
1155
|
|
1156
1156
|
repeater_resp = rest_browser.put(
|
1157
|
-
"http://#{
|
1157
|
+
"http://#{mitm_rest_api}/repeater/#{id}",
|
1158
1158
|
put_body,
|
1159
1159
|
content_type: 'application/json; charset=UTF8'
|
1160
1160
|
)
|
@@ -1178,10 +1178,10 @@ module PWN
|
|
1178
1178
|
raise 'ERROR: id parameter is required' if id.nil?
|
1179
1179
|
|
1180
1180
|
rest_browser = burp_obj[:rest_browser]
|
1181
|
-
|
1181
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
1182
1182
|
|
1183
1183
|
rest_browser.delete(
|
1184
|
-
"http://#{
|
1184
|
+
"http://#{mitm_rest_api}/repeater/#{id}",
|
1185
1185
|
content_type: 'application/json; charset=UTF8'
|
1186
1186
|
)
|
1187
1187
|
|
@@ -1202,7 +1202,7 @@ module PWN
|
|
1202
1202
|
burp_obj = opts[:burp_obj]
|
1203
1203
|
target_url = opts[:target_url]
|
1204
1204
|
rest_browser = burp_obj[:rest_browser]
|
1205
|
-
|
1205
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
1206
1206
|
output_dir = opts[:output_dir]
|
1207
1207
|
raise "ERROR: #{output_dir} does not exist." unless Dir.exist?(output_dir)
|
1208
1208
|
|
@@ -1236,7 +1236,7 @@ module PWN
|
|
1236
1236
|
report_url = Base64.strict_encode64(target_domain)
|
1237
1237
|
# Ready scanreport API call in pwn_burp to support HTML & XML report generation
|
1238
1238
|
report_resp = rest_browser.get(
|
1239
|
-
"http://#{
|
1239
|
+
"http://#{mitm_rest_api}/scanreport/#{report_type.to_s.upcase}/#{report_url}"
|
1240
1240
|
)
|
1241
1241
|
|
1242
1242
|
File.open(report_path, 'w') do |f|
|
@@ -1264,13 +1264,13 @@ module PWN
|
|
1264
1264
|
|
1265
1265
|
public_class_method def self.stop(opts = {})
|
1266
1266
|
burp_obj = opts[:burp_obj]
|
1267
|
-
browser_obj = burp_obj[:
|
1267
|
+
browser_obj = burp_obj[:mitm_browser]
|
1268
1268
|
rest_browser = burp_obj[:rest_browser]
|
1269
|
-
|
1269
|
+
mitm_rest_api = burp_obj[:mitm_rest_api]
|
1270
1270
|
# burp_pid = burp_obj[:pid]
|
1271
1271
|
|
1272
|
-
|
1273
|
-
rest_browser.post("http://#{
|
1272
|
+
PWN::Plugins::TransparentBrowser.close(browser_obj: browser_obj)
|
1273
|
+
rest_browser.post("http://#{mitm_rest_api}/shutdown", '')
|
1274
1274
|
# Process.kill('TERM', burp_pid)
|
1275
1275
|
|
1276
1276
|
burp_obj = nil
|
@@ -1381,7 +1381,7 @@ module PWN
|
|
1381
1381
|
|
1382
1382
|
active_scan_url_arr = #{self}.active_scan(
|
1383
1383
|
burp_obj: 'required - burp_obj returned by #start method',
|
1384
|
-
target_url: 'required - target url to scan in sitemap (should be loaded & authenticated w/ burp_obj[:
|
1384
|
+
target_url: 'required - target url to scan in sitemap (should be loaded & authenticated w/ burp_obj[:mitm_browser])',
|
1385
1385
|
exclude_paths: 'optional - array of paths to exclude from active scan (default: [])'
|
1386
1386
|
)
|
1387
1387
|
|
@@ -1225,7 +1225,8 @@ module PWN
|
|
1225
1225
|
PWN::Plugins::Tor.stop(tor_obj: browser_obj[:tor_obj]) if tor_obj
|
1226
1226
|
|
1227
1227
|
# Close the browser unless browser.nil? (thus the &)
|
1228
|
-
browser&.close unless browser.to_s == 'RestClient'
|
1228
|
+
# browser&.close unless browser.to_s == 'RestClient'
|
1229
|
+
browser&.close unless browser.is_a?(RestClient)
|
1229
1230
|
|
1230
1231
|
nil
|
1231
1232
|
rescue StandardError => e
|
data/lib/pwn/plugins/zaproxy.rb
CHANGED
@@ -24,17 +24,15 @@ module PWN
|
|
24
24
|
private_class_method def self.zap_rest_call(opts = {})
|
25
25
|
zap_obj = opts[:zap_obj]
|
26
26
|
rest_call = opts[:rest_call].to_s.scrub
|
27
|
-
http_method =
|
28
|
-
|
29
|
-
else
|
30
|
-
opts[:http_method].to_s.scrub.to_sym
|
31
|
-
end
|
27
|
+
http_method = opts[:http_method] ||= :get
|
28
|
+
http_method = http_method.to_s.downcase.to_sym unless http_method.is_a?(Symbol)
|
32
29
|
params = opts[:params]
|
33
30
|
http_body = opts[:http_body].to_s.scrub
|
34
|
-
zap_rest_api = zap_obj[:zap_rest_api]
|
35
|
-
base_zap_api_uri = "http://#{zap_rest_api}"
|
36
31
|
|
37
32
|
rest_client = zap_obj[:rest_browser]::Request
|
33
|
+
mitm_rest_api = zap_obj[:mitm_rest_api]
|
34
|
+
|
35
|
+
base_zap_api_uri = "http://#{mitm_rest_api}"
|
38
36
|
|
39
37
|
case http_method
|
40
38
|
when :get
|
@@ -66,7 +64,7 @@ module PWN
|
|
66
64
|
|
67
65
|
response
|
68
66
|
rescue StandardError, SystemExit, Interrupt => e
|
69
|
-
stop(zap_obj) unless zap_obj.nil?
|
67
|
+
stop(zap_obj: zap_obj) unless zap_obj.nil?
|
70
68
|
raise e
|
71
69
|
end
|
72
70
|
|
@@ -100,20 +98,11 @@ module PWN
|
|
100
98
|
zap_rest_ip = zap_ip
|
101
99
|
zap_rest_port = zap_port
|
102
100
|
|
103
|
-
if headless
|
104
|
-
zaproxy_cmd = "cd #{zap_root} && ./#{zap_bin} -daemon"
|
105
|
-
else
|
106
|
-
zaproxy_cmd = "cd #{zap_root} && ./#{zap_bin}"
|
107
|
-
end
|
108
|
-
|
109
|
-
zaproxy_cmd = "#{zaproxy_cmd} -host #{zap_ip} -port #{zap_port}"
|
110
|
-
|
111
|
-
zap_obj[:pid] = Process.spawn(zaproxy_cmd)
|
112
101
|
browser_obj1 = PWN::Plugins::TransparentBrowser.open(browser_type: :rest)
|
113
102
|
rest_browser = browser_obj1[:browser]
|
114
103
|
|
115
104
|
zap_obj[:mitm_proxy] = "#{zap_ip}:#{zap_port}"
|
116
|
-
zap_obj[:
|
105
|
+
zap_obj[:mitm_rest_api] = zap_obj[:mitm_proxy]
|
117
106
|
zap_obj[:rest_browser] = rest_browser
|
118
107
|
|
119
108
|
browser_obj2 = PWN::Plugins::TransparentBrowser.open(
|
@@ -122,8 +111,17 @@ module PWN
|
|
122
111
|
devtools: true
|
123
112
|
)
|
124
113
|
|
125
|
-
zap_obj[:
|
114
|
+
zap_obj[:mitm_browser] = browser_obj2
|
115
|
+
|
116
|
+
if headless
|
117
|
+
zaproxy_cmd = "cd #{zap_root} && ./#{zap_bin} -daemon"
|
118
|
+
else
|
119
|
+
zaproxy_cmd = "cd #{zap_root} && ./#{zap_bin}"
|
120
|
+
end
|
121
|
+
|
122
|
+
zaproxy_cmd = "#{zaproxy_cmd} -host #{zap_ip} -port #{zap_port}"
|
126
123
|
|
124
|
+
zap_obj[:pid] = Process.spawn(zaproxy_cmd)
|
127
125
|
# Wait for pwn_burp_port to open prior to returning burp_obj
|
128
126
|
loop do
|
129
127
|
s = TCPSocket.new(zap_rest_ip, zap_rest_port)
|
@@ -136,8 +134,8 @@ module PWN
|
|
136
134
|
end
|
137
135
|
|
138
136
|
zap_obj
|
139
|
-
rescue StandardError, SystemExit, Interrupt => e
|
140
|
-
stop(zap_obj) unless zap_obj.nil?
|
137
|
+
rescue Selenium::WebDriver::Error::SessionNotCreatedError, StandardError, SystemExit, Interrupt => e
|
138
|
+
stop(zap_obj: zap_obj) unless zap_obj.nil?
|
141
139
|
raise e
|
142
140
|
end
|
143
141
|
|
@@ -169,7 +167,40 @@ module PWN
|
|
169
167
|
|
170
168
|
JSON.parse(response.body, symbolize_names: true)
|
171
169
|
rescue StandardError, SystemExit, Interrupt => e
|
172
|
-
stop(zap_obj) unless zap_obj.nil?
|
170
|
+
stop(zap_obj: zap_obj) unless zap_obj.nil?
|
171
|
+
raise e
|
172
|
+
end
|
173
|
+
|
174
|
+
# Supported Method Parameters::
|
175
|
+
# PWN::Plugins::Zaproxy.add_to_scope(
|
176
|
+
# zap_obj: 'required - zap_obj returned from #open method',
|
177
|
+
# target_regex: 'required - url regex to add to scope (e.g. https://test.domain.local.*)',
|
178
|
+
# context_name: 'optional - context name to add target_regex to (defaults to Default Context)'
|
179
|
+
# )
|
180
|
+
|
181
|
+
public_class_method def self.add_to_scope(opts = {})
|
182
|
+
zap_obj = opts[:zap_obj]
|
183
|
+
api_key = zap_obj[:api_key].to_s.scrub
|
184
|
+
target_regex = opts[:target_regex]
|
185
|
+
raise 'ERROR: target_url must be provided' if target_regex.nil?
|
186
|
+
|
187
|
+
context_name = opts[:context_name] ||= 'Default Context'
|
188
|
+
|
189
|
+
params = {
|
190
|
+
apikey: api_key,
|
191
|
+
contextName: context_name,
|
192
|
+
regex: target_regex
|
193
|
+
}
|
194
|
+
|
195
|
+
response = zap_rest_call(
|
196
|
+
zap_obj: zap_obj,
|
197
|
+
rest_call: 'JSON/context/action/includeInContext/',
|
198
|
+
params: params
|
199
|
+
)
|
200
|
+
|
201
|
+
JSON.parse(response.body, symbolize_names: true)
|
202
|
+
rescue StandardError, SystemExit, Interrupt => e
|
203
|
+
stop(zap_obj: zap_obj) unless zap_obj.nil?
|
173
204
|
raise e
|
174
205
|
end
|
175
206
|
|
@@ -222,7 +253,7 @@ module PWN
|
|
222
253
|
break if status == 100
|
223
254
|
end
|
224
255
|
rescue StandardError, SystemExit, Interrupt => e
|
225
|
-
stop(zap_obj) unless zap_obj.nil?
|
256
|
+
stop(zap_obj: zap_obj) unless zap_obj.nil?
|
226
257
|
raise e
|
227
258
|
end
|
228
259
|
|
@@ -230,6 +261,7 @@ module PWN
|
|
230
261
|
# PWN::Plugins::Zaproxy.active_scan(
|
231
262
|
# zap_obj: 'required - zap_obj returned from #open method',
|
232
263
|
# target_url: 'required - url to scan',
|
264
|
+
# exclude_paths: 'optional - array of paths to exclude from scan (default: [])',
|
233
265
|
# scan_policy: 'optional - scan policy to use (defaults to Default Policy)'
|
234
266
|
# )
|
235
267
|
|
@@ -237,10 +269,23 @@ module PWN
|
|
237
269
|
zap_obj = opts[:zap_obj]
|
238
270
|
api_key = zap_obj[:api_key].to_s.scrub
|
239
271
|
target_url = opts[:target_url]
|
240
|
-
if
|
241
|
-
|
242
|
-
|
243
|
-
|
272
|
+
raise 'ERROR: target_url must be provided' if target_url.nil?
|
273
|
+
|
274
|
+
exclude_paths = opts[:exclude_paths] ||= []
|
275
|
+
scan_policy = opts[:scan_policy] ||= 'Default Policy'
|
276
|
+
|
277
|
+
exclude_paths.each do |exclude_path|
|
278
|
+
exclude_path_regex = "#{target_url}#{exclude_path}.*"
|
279
|
+
params = {
|
280
|
+
apikey: api_key,
|
281
|
+
regex: exclude_path_regex
|
282
|
+
}
|
283
|
+
zap_rest_call(
|
284
|
+
zap_obj: zap_obj,
|
285
|
+
rest_call: 'JSON/ascan/action/excludeFromScan/',
|
286
|
+
params: params
|
287
|
+
)
|
288
|
+
puts "Excluding #{exclude_path_regex} from Active Scan"
|
244
289
|
end
|
245
290
|
|
246
291
|
# TODO: Implement adding target_url to scope so that inScopeOnly can be changed to true
|
@@ -279,17 +324,17 @@ module PWN
|
|
279
324
|
break if status == 100
|
280
325
|
end
|
281
326
|
rescue StandardError, SystemExit, Interrupt => e
|
282
|
-
stop(zap_obj) unless zap_obj.nil?
|
327
|
+
stop(zap_obj: zap_obj) unless zap_obj.nil?
|
283
328
|
raise e
|
284
329
|
end
|
285
330
|
|
286
331
|
# Supported Method Parameters::
|
287
|
-
# PWN::Plugins::Zaproxy.
|
332
|
+
# PWN::Plugins::Zaproxy.get_alerts(
|
288
333
|
# zap_obj: 'required - zap_obj returned from #open method',
|
289
334
|
# target_url: 'required - base url to return alerts'
|
290
335
|
# )
|
291
336
|
|
292
|
-
public_class_method def self.
|
337
|
+
public_class_method def self.get_alerts(opts = {})
|
293
338
|
zap_obj = opts[:zap_obj]
|
294
339
|
api_key = zap_obj[:api_key].to_s.scrub
|
295
340
|
target_url = opts[:target_url]
|
@@ -307,7 +352,7 @@ module PWN
|
|
307
352
|
|
308
353
|
JSON.parse(response.body, symbolize_names: true)
|
309
354
|
rescue StandardError, SystemExit, Interrupt => e
|
310
|
-
stop(zap_obj) unless zap_obj.nil?
|
355
|
+
stop(zap_obj: zap_obj) unless zap_obj.nil?
|
311
356
|
raise e
|
312
357
|
end
|
313
358
|
|
@@ -357,7 +402,7 @@ module PWN
|
|
357
402
|
|
358
403
|
report_path
|
359
404
|
rescue StandardError, SystemExit, Interrupt => e
|
360
|
-
stop(zap_obj) unless zap_obj.nil?
|
405
|
+
stop(zap_obj: zap_obj) unless zap_obj.nil?
|
361
406
|
raise e
|
362
407
|
end
|
363
408
|
|
@@ -391,7 +436,7 @@ module PWN
|
|
391
436
|
http_method: :get
|
392
437
|
)
|
393
438
|
rescue StandardError, SystemExit, Interrupt => e
|
394
|
-
stop(zap_obj) unless zap_obj.nil?
|
439
|
+
stop(zap_obj: zap_obj) unless zap_obj.nil?
|
395
440
|
raise e
|
396
441
|
end
|
397
442
|
|
@@ -423,47 +468,7 @@ module PWN
|
|
423
468
|
http_method: :get
|
424
469
|
)
|
425
470
|
rescue StandardError, SystemExit, Interrupt => e
|
426
|
-
stop(zap_obj) unless zap_obj.nil?
|
427
|
-
raise e
|
428
|
-
end
|
429
|
-
|
430
|
-
# Supported Method Parameters::
|
431
|
-
# watir_resp = PWN::Plugins::Zaproxy.request(
|
432
|
-
# zap_obj: 'required - zap_obj returned from #open method',
|
433
|
-
# browser_obj: 'required - browser_obj w/ browser_type: :firefox||:headless returned from #open method',
|
434
|
-
# instruction: 'required - watir instruction to make (e.g. button(text: "Google Search").click)'
|
435
|
-
# )
|
436
|
-
|
437
|
-
public_class_method def self.request(opts = {})
|
438
|
-
zap_obj = opts[:zap_obj]
|
439
|
-
api_key = zap_obj[:api_key].to_s.scrub
|
440
|
-
this_browser_obj = opts[:browser_obj]
|
441
|
-
instruction = opts[:instruction].to_s.strip.chomp.scrub
|
442
|
-
|
443
|
-
raise "\nbrowser_obj.class == #{this_browser_obj.class} browser_obj == #{this_browser_obj}\n#{self}.nonblocking_goto only supports browser_obj.class == Watir::Browser" unless this_browser_obj.is_a?(Watir::Browser)
|
444
|
-
raise "\nthis_browser_obj.driver.browser == #{this_browser_obj.driver.browser}\n#{self}.nonblocking_goto only supports this_browser_obj.driver.browser == :firefox" unless this_browser_obj.driver.browser == :firefox
|
445
|
-
|
446
|
-
timeout = 0
|
447
|
-
# this_browser_obj.driver.manage.timeouts.implicit_wait = timeout
|
448
|
-
this_browser_obj.driver.manage.timeouts.page_load = timeout
|
449
|
-
# this_browser_obj.driver.manage.timeouts.script_timeout = timeout
|
450
|
-
|
451
|
-
watir_resp = this_browser_obj.instance_eval(instruction)
|
452
|
-
rescue Timeout::Error
|
453
|
-
sleep 0.9
|
454
|
-
request_content = zap_rest_call(
|
455
|
-
zap_obj: zap_obj,
|
456
|
-
rest_call: "JSON/break/view/httpMessage/?zapapiformat=JSON&apikey=#{api_key}",
|
457
|
-
http_method: :get
|
458
|
-
).body
|
459
|
-
|
460
|
-
# Now set all the timeouts back to default:
|
461
|
-
# this_browser_obj.driver.manage.timeouts.implicit_wait = b.driver.capabilities[:implicit_timeout]
|
462
|
-
this_browser_obj.driver.manage.timeouts.page_load = this_browser_obj.driver.capabilities[:page_load_timeout]
|
463
|
-
# this_browser_obj.driver.manage.timeouts.script_timeout = b.driver.capabilities[:script_timeout]
|
464
|
-
|
465
|
-
request_content
|
466
|
-
rescue StandardError => e
|
471
|
+
stop(zap_obj: zap_obj) unless zap_obj.nil?
|
467
472
|
raise e
|
468
473
|
end
|
469
474
|
|
@@ -475,10 +480,9 @@ module PWN
|
|
475
480
|
public_class_method def self.stop(opts = {})
|
476
481
|
zap_obj = opts[:zap_obj]
|
477
482
|
api_key = zap_obj[:api_key]
|
478
|
-
browser_obj = zap_obj[:
|
479
|
-
rest_browser = zap_obj[:rest_browser]
|
483
|
+
browser_obj = zap_obj[:mitm_browser]
|
480
484
|
|
481
|
-
|
485
|
+
PWN::Plugins::TransparentBrowser.close(browser_obj: browser_obj)
|
482
486
|
|
483
487
|
params = { apikey: api_key }
|
484
488
|
zap_rest_call(
|
@@ -489,7 +493,6 @@ module PWN
|
|
489
493
|
|
490
494
|
zap_obj = nil
|
491
495
|
rescue StandardError, SystemExit, Interrupt => e
|
492
|
-
stop(zap_obj) unless zap_obj.nil?
|
493
496
|
raise e
|
494
497
|
end
|
495
498
|
|
@@ -525,10 +528,11 @@ module PWN
|
|
525
528
|
#{self}.active_scan(
|
526
529
|
zap_obj: 'required - zap_obj returned from #open method'
|
527
530
|
target_url: 'required - url to scan',
|
531
|
+
exclude_paths: 'optional - array of paths to exclude from scan (default: [])',
|
528
532
|
scan_policy: 'optional - scan policy to use (defaults to Default Policy)'
|
529
533
|
)
|
530
534
|
|
531
|
-
json_alerts = #{self}.
|
535
|
+
json_alerts = #{self}.get_alerts(
|
532
536
|
zap_obj: 'required - zap_obj returned from #open method'
|
533
537
|
target_url: 'required - base url to return alerts'
|
534
538
|
)
|
@@ -546,10 +550,10 @@ module PWN
|
|
546
550
|
enabled: 'optional - boolean (defaults to true)'
|
547
551
|
)
|
548
552
|
|
549
|
-
|
553
|
+
#{self}.tamper(
|
550
554
|
zap_obj: 'required - zap_obj returned from #open method',
|
551
|
-
|
552
|
-
|
555
|
+
domain: 'required - FQDN to tamper (e.g. test.domain.local)',
|
556
|
+
enabled: 'optional - boolean (defaults to true)'
|
553
557
|
)
|
554
558
|
|
555
559
|
#{self}.stop(
|
data/lib/pwn/version.rb
CHANGED