pwn 0.5.327 → 0.5.330
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/Gemfile +3 -3
- data/README.md +3 -3
- data/bin/pwn_burp_suite_pro_active_scan +2 -9
- data/lib/pwn/plugins/burp_suite.rb +221 -73
- data/lib/pwn/plugins/owasp_zap.rb +35 -0
- data/lib/pwn/version.rb +1 -1
- data/third_party/pwn_rdoc.jsonl +2 -1
- metadata +7 -8
- data/third_party/burpbuddy-3.1.1-SNAPSHOT-all.jar +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c2402a13b3e2cd7cbbdd21760049fce61980dc14871236a6345d51c50dae439b
|
4
|
+
data.tar.gz: e31a43da568d89bea803c9de5985edd089f7fea80db82fd9fa871fcfb524fe73
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f3e8e3aa9d1b1717768a20531f4e63044587fec15c9952fc406f4a8fd0992432899d3ef77420bbed3f82970da5197916b970bdf5c89fb39489afdd73b5ade671
|
7
|
+
data.tar.gz: f86b6c3356a6f1140ece443001b323062d11cbc2e2e1d2cac544a4a921fe2691ab022d7123aa3c36ad06ec089b7db9e1ab3ca2c72964e10f16e39ff6734d94dc
|
data/Gemfile
CHANGED
@@ -35,13 +35,13 @@ gem 'gdb', '1.0.0'
|
|
35
35
|
gem 'gem-wrappers', '1.4.0'
|
36
36
|
gem 'geocoder', '1.8.5'
|
37
37
|
gem 'gist', '6.0.0'
|
38
|
-
gem 'gruff', '0.
|
38
|
+
gem 'gruff', '0.29.0'
|
39
39
|
# gem 'hidapi', '0.1.9'
|
40
40
|
gem 'htmlentities', '4.3.4'
|
41
41
|
gem 'ipaddress', '0.8.3'
|
42
42
|
gem 'jenkins_api_client2', '1.9.0'
|
43
43
|
gem 'js-beautify', '0.1.8'
|
44
|
-
gem 'json', '2.13.
|
44
|
+
gem 'json', '2.13.1'
|
45
45
|
gem 'jsonpath', '1.1.5'
|
46
46
|
gem 'jwt', '3.1.2'
|
47
47
|
gem 'libusb', '0.7.2'
|
@@ -81,7 +81,7 @@ gem 'rmagick', '6.1.2'
|
|
81
81
|
gem 'rqrcode', '3.1.0'
|
82
82
|
gem 'rspec', '3.13.1'
|
83
83
|
gem 'rtesseract', '3.1.4'
|
84
|
-
gem 'rubocop', '1.
|
84
|
+
gem 'rubocop', '1.79.0'
|
85
85
|
gem 'rubocop-rake', '0.7.1'
|
86
86
|
gem 'rubocop-rspec', '3.6.0'
|
87
87
|
gem 'ruby-audio', '1.6.1'
|
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.330]: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.330]: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.330]: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:
|
@@ -33,10 +33,6 @@ OptionParser.new do |options|
|
|
33
33
|
options.on('-iURL', '---in_scope=URL', '<Optional - URL to add include in scope (Defaults to value of --target_url)>') do |s|
|
34
34
|
opts[:in_scope] = s
|
35
35
|
end
|
36
|
-
|
37
|
-
options.on('-cFILE', '--target-config=FILE', '<Optional - Path to Target Config JSON File>') do |c|
|
38
|
-
opts[:target_config] = c
|
39
|
-
end
|
40
36
|
end.parse!
|
41
37
|
|
42
38
|
if opts.empty?
|
@@ -56,7 +52,6 @@ begin
|
|
56
52
|
raise 'Invalid path to browser instructions. Please check your spelling and try again.' unless File.exist?(navigation_instruct)
|
57
53
|
|
58
54
|
in_scope = opts[:in_scope] ||= target_url
|
59
|
-
target_config = opts[:target_config]
|
60
55
|
|
61
56
|
# ------
|
62
57
|
# Open Burp
|
@@ -64,14 +59,12 @@ begin
|
|
64
59
|
burp_obj = PWN::Plugins::BurpSuite.start(
|
65
60
|
burp_jar_path: burp_jar_path,
|
66
61
|
headless: true,
|
67
|
-
browser_type: :headless
|
68
|
-
target_config: target_config
|
62
|
+
browser_type: :headless
|
69
63
|
)
|
70
64
|
else
|
71
65
|
burp_obj = PWN::Plugins::BurpSuite.start(
|
72
66
|
burp_jar_path: burp_jar_path,
|
73
|
-
browser_type: :chrome
|
74
|
-
target_config: target_config
|
67
|
+
browser_type: :chrome
|
75
68
|
)
|
76
69
|
end
|
77
70
|
|
@@ -31,25 +31,27 @@ module PWN
|
|
31
31
|
443
|
32
32
|
]
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
end
|
34
|
+
uri = "#{scheme}://#{host}:#{port}#{path}"
|
35
|
+
uri = "#{scheme}://#{host}#{path}" if implicit_http_ports_arr.include?(port)
|
36
|
+
|
37
|
+
uri
|
39
38
|
rescue StandardError => e
|
40
39
|
raise e
|
41
40
|
end
|
42
41
|
|
43
42
|
# Supported Method Parameters::
|
44
43
|
# burp_obj = PWN::Plugins::BurpSuite.start(
|
45
|
-
# burp_jar_path: '
|
44
|
+
# burp_jar_path: 'optional - path of burp suite pro jar file (defaults to /opt/burpsuite/burpsuite_pro.jar)',
|
46
45
|
# headless: 'optional - run burp headless if set to true',
|
47
46
|
# browser_type: 'optional - defaults to :firefox. See PWN::Plugins::TransparentBrowser.help for a list of types',
|
48
|
-
#
|
47
|
+
# burp_ip: 'optional - IP address for the Burp proxy (defaults to 127.0.0.1)',
|
48
|
+
# burp_port: 'optional - port for the Burp proxy (defaults to a random unused port)',
|
49
|
+
# pwn_burp_ip: 'optional - IP address for the PWN Burp API (defaults to 127.0.0.1)',
|
50
|
+
# pwn_burp_port: 'optional - port for the PWN Burp API (defaults to a random unused port)'
|
49
51
|
# )
|
50
52
|
|
51
53
|
public_class_method def self.start(opts = {})
|
52
|
-
burp_jar_path = opts[:burp_jar_path] ||= '/opt/burpsuite/
|
54
|
+
burp_jar_path = opts[:burp_jar_path] ||= '/opt/burpsuite/burpsuite-pro.jar'
|
53
55
|
raise 'Invalid path to burp jar file. Please check your spelling and try again.' unless File.exist?(burp_jar_path)
|
54
56
|
|
55
57
|
burp_root = File.dirname(burp_jar_path)
|
@@ -60,16 +62,20 @@ module PWN
|
|
60
62
|
opts[:browser_type]
|
61
63
|
end
|
62
64
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
burp_cmd_string = "#{burp_cmd_string}
|
65
|
+
burp_ip = opts[:burp_ip] ||= '127.0.0.1'
|
66
|
+
burp_port = opts[:burp_port] ||= 8080
|
67
|
+
# burp_port = opts[:burp_port] ||= PWN::Plugins::Sock.get_random_unused_port
|
68
|
+
#
|
69
|
+
pwn_burp_ip = opts[:pwn_burp_ip] ||= '127.0.0.1'
|
70
|
+
pwn_burp_port = opts[:pwn_burp_port] ||= 1337
|
71
|
+
# pwn_burp_port = opts[:pwn_burp_port] ||= PWN::Plugins::Sock.get_random_unused_port
|
72
|
+
|
73
|
+
burp_cmd_string = 'java -Xmx4G'
|
74
|
+
# burp_cmd_string = "#{burp_cmd_string} -Dhttp.proxyHost=#{burp_ip} -Dhttp.proxyPort=#{burp_port}"
|
75
|
+
# burp_cmd_string = "#{burp_cmd_string} -Dhttps.proxyHost=#{burp_ip} -Dhttps.proxyPort=#{burp_port}"
|
76
|
+
burp_cmd_string = "#{burp_cmd_string} -Djava.awt.headless=true" if opts[:headless]
|
77
|
+
burp_cmd_string = "#{burp_cmd_string} -Dserver.address=#{pwn_burp_ip} -Dserver.port=#{pwn_burp_port}"
|
78
|
+
burp_cmd_string = "#{burp_cmd_string} -jar #{burp_jar_path}"
|
73
79
|
|
74
80
|
# Construct burp_obj
|
75
81
|
burp_obj = {}
|
@@ -77,11 +83,8 @@ module PWN
|
|
77
83
|
browser_obj1 = PWN::Plugins::TransparentBrowser.open(browser_type: :rest)
|
78
84
|
rest_browser = browser_obj1[:browser]
|
79
85
|
|
80
|
-
|
81
|
-
|
82
|
-
# random_bb_port = PWN::Plugins::Sock.get_random_unused_port while random_bb_port == random_mitm_port
|
83
|
-
burp_obj[:mitm_proxy] = '127.0.0.1:8080'
|
84
|
-
burp_obj[:burpbuddy_api] = '127.0.0.1:8001'
|
86
|
+
burp_obj[:mitm_proxy] = "#{burp_ip}:#{burp_port}"
|
87
|
+
burp_obj[:pwn_burp_api] = "#{pwn_burp_ip}:#{pwn_burp_port}"
|
85
88
|
burp_obj[:rest_browser] = rest_browser
|
86
89
|
|
87
90
|
# Proxy always listens on localhost...use SSH tunneling if remote access is required
|
@@ -92,9 +95,9 @@ module PWN
|
|
92
95
|
|
93
96
|
burp_obj[:burp_browser] = browser_obj2
|
94
97
|
|
95
|
-
# Wait for
|
98
|
+
# Wait for pwn_burp_port to open prior to returning burp_obj
|
96
99
|
loop do
|
97
|
-
s = TCPSocket.new(
|
100
|
+
s = TCPSocket.new(pwn_burp_ip, pwn_burp_port)
|
98
101
|
s.close
|
99
102
|
break
|
100
103
|
rescue Errno::ECONNREFUSED
|
@@ -103,6 +106,15 @@ module PWN
|
|
103
106
|
next
|
104
107
|
end
|
105
108
|
|
109
|
+
# USE THIS WHEN Updating Proxy Listener settings become
|
110
|
+
# available in the BurpSuite Montoya API
|
111
|
+
# Update proxy listener to use the burp_ip and burp_port
|
112
|
+
# update_proxy_listener(
|
113
|
+
# burp_obj: burp_obj,
|
114
|
+
# address: burp_ip,
|
115
|
+
# port: burp_port
|
116
|
+
# )
|
117
|
+
|
106
118
|
burp_obj
|
107
119
|
rescue StandardError => e
|
108
120
|
stop(burp_obj: burp_obj) unless burp_obj.nil?
|
@@ -156,9 +168,9 @@ module PWN
|
|
156
168
|
public_class_method def self.enable_proxy(opts = {})
|
157
169
|
burp_obj = opts[:burp_obj]
|
158
170
|
rest_browser = burp_obj[:rest_browser]
|
159
|
-
|
171
|
+
pwn_burp_api = burp_obj[:pwn_burp_api]
|
160
172
|
|
161
|
-
enable_resp = rest_browser.post("http://#{
|
173
|
+
enable_resp = rest_browser.post("http://#{pwn_burp_api}/proxy/intercept/enable", nil)
|
162
174
|
rescue StandardError => e
|
163
175
|
stop(burp_obj: burp_obj) unless burp_obj.nil?
|
164
176
|
raise e
|
@@ -172,9 +184,9 @@ module PWN
|
|
172
184
|
public_class_method def self.disable_proxy(opts = {})
|
173
185
|
burp_obj = opts[:burp_obj]
|
174
186
|
rest_browser = burp_obj[:rest_browser]
|
175
|
-
|
187
|
+
pwn_burp_api = burp_obj[:pwn_burp_api]
|
176
188
|
|
177
|
-
disable_resp = rest_browser.post("http://#{
|
189
|
+
disable_resp = rest_browser.post("http://#{pwn_burp_api}/proxy/intercept/disable", nil)
|
178
190
|
rescue StandardError => e
|
179
191
|
stop(burp_obj: burp_obj) unless burp_obj.nil?
|
180
192
|
raise e
|
@@ -188,10 +200,21 @@ module PWN
|
|
188
200
|
public_class_method def self.get_current_sitemap(opts = {})
|
189
201
|
burp_obj = opts[:burp_obj]
|
190
202
|
rest_browser = burp_obj[:rest_browser]
|
191
|
-
|
192
|
-
|
193
|
-
sitemap = rest_browser.get("http://#{
|
194
|
-
JSON.parse(sitemap)
|
203
|
+
pwn_burp_api = burp_obj[:pwn_burp_api]
|
204
|
+
|
205
|
+
sitemap = rest_browser.get("http://#{pwn_burp_api}/sitemap", content_type: 'application/json; charset=UTF8')
|
206
|
+
# json_sitemap = JSON.parse(sitemap, symbolize_names: true)
|
207
|
+
# json_sitemap is an array of hashes.
|
208
|
+
# each hash contains a :request and :response key.
|
209
|
+
# both of these values are Base64 encoded strings.
|
210
|
+
# We want to decode them in an array of hashes.
|
211
|
+
# json_sitemap.map do |site|
|
212
|
+
# site[:request] = Base64.decode64(site[:request]) if site[:request]
|
213
|
+
# site[:response] = Base64.decode64(site[:response]) if site[:response]
|
214
|
+
# end
|
215
|
+
|
216
|
+
# json_sitemap
|
217
|
+
JSON.parse(sitemap, symbolize_names: true)
|
195
218
|
rescue StandardError => e
|
196
219
|
stop(burp_obj: burp_obj) unless burp_obj.nil?
|
197
220
|
raise e
|
@@ -207,11 +230,11 @@ module PWN
|
|
207
230
|
burp_obj = opts[:burp_obj]
|
208
231
|
target_url = opts[:target_url]
|
209
232
|
rest_browser = burp_obj[:rest_browser]
|
210
|
-
|
233
|
+
pwn_burp_api = burp_obj[:pwn_burp_api]
|
211
234
|
|
212
235
|
post_body = { url: target_url }.to_json
|
213
236
|
|
214
|
-
in_scope = rest_browser.post("http://#{
|
237
|
+
in_scope = rest_browser.post("http://#{pwn_burp_api}/scope", post_body, content_type: 'application/json; charset=UTF8')
|
215
238
|
JSON.parse(in_scope)
|
216
239
|
rescue StandardError => e
|
217
240
|
stop(burp_obj: burp_obj) unless burp_obj.nil?
|
@@ -227,26 +250,27 @@ module PWN
|
|
227
250
|
public_class_method def self.invoke_active_scan(opts = {})
|
228
251
|
burp_obj = opts[:burp_obj]
|
229
252
|
rest_browser = burp_obj[:rest_browser]
|
230
|
-
|
253
|
+
pwn_burp_api = burp_obj[:pwn_burp_api]
|
231
254
|
target_url = opts[:target_url].to_s.scrub.strip.chomp
|
232
255
|
target_scheme = URI.parse(target_url).scheme
|
233
256
|
target_host = URI.parse(target_url).host
|
234
257
|
target_port = URI.parse(target_url).port.to_i
|
235
|
-
if target_scheme == 'http'
|
236
|
-
|
237
|
-
else
|
238
|
-
|
239
|
-
end
|
258
|
+
# if target_scheme == 'http'
|
259
|
+
# use_https = false
|
260
|
+
# else
|
261
|
+
# use_https = true
|
262
|
+
# end
|
240
263
|
|
241
264
|
active_scan_url_arr = []
|
242
265
|
json_sitemap = get_current_sitemap(burp_obj: burp_obj)
|
243
266
|
json_sitemap.each do |site|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
267
|
+
json_req = site[:request]
|
268
|
+
json_path = json_req[:path]
|
269
|
+
b64_encoded_req = json_req[:raw]
|
270
|
+
json_http_svc = site[:http_service]
|
271
|
+
json_protocol = json_http_svc[:protocol]
|
272
|
+
json_host = json_http_svc[:host].to_s.scrub.strip.chomp
|
273
|
+
json_port = json_http_svc[:port].to_i
|
250
274
|
|
251
275
|
json_uri = format_uri_from_sitemap_resp(
|
252
276
|
scheme: json_protocol,
|
@@ -255,30 +279,32 @@ module PWN
|
|
255
279
|
path: json_path
|
256
280
|
)
|
257
281
|
|
282
|
+
# TODO: check if the URI is in scope
|
283
|
+
# next unless uri_in_scope(...)
|
258
284
|
next unless json_host == target_host && json_port == target_port
|
259
285
|
|
260
|
-
|
261
|
-
|
286
|
+
use_https = true if json_protocol == 'https'
|
287
|
+
|
262
288
|
puts "Adding #{json_uri} to Active Scan"
|
263
289
|
active_scan_url_arr.push(json_uri)
|
264
290
|
post_body = {
|
265
291
|
host: json_host,
|
266
292
|
port: json_port,
|
267
293
|
use_https: use_https,
|
268
|
-
request:
|
294
|
+
request: b64_encoded_req
|
269
295
|
}.to_json
|
270
296
|
# Kick off an active scan for each given page in the json_sitemap results
|
271
|
-
rest_browser.post("http://#{
|
297
|
+
rest_browser.post("http://#{pwn_burp_api}/scan/active", post_body, content_type: 'application/json')
|
272
298
|
end
|
273
299
|
|
274
300
|
# Wait for scan completion
|
275
|
-
scan_queue = rest_browser.get("http://#{
|
301
|
+
scan_queue = rest_browser.get("http://#{pwn_burp_api}/scan/active")
|
276
302
|
json_scan_queue = JSON.parse(scan_queue)
|
277
303
|
scan_queue_total = json_scan_queue.count
|
278
304
|
json_scan_queue.each do |scan_item|
|
279
305
|
this_scan_item_id = scan_item['id']
|
280
306
|
until scan_item['status'] == 'finished'
|
281
|
-
scan_item_resp = rest_browser.get("http://#{
|
307
|
+
scan_item_resp = rest_browser.get("http://#{pwn_burp_api}/scan/active/#{this_scan_item_id}")
|
282
308
|
scan_item = JSON.parse(scan_item_resp)
|
283
309
|
scan_status = scan_item['status']
|
284
310
|
puts "Target ID ##{this_scan_item_id} of ##{scan_queue_total}| #{scan_status}"
|
@@ -301,9 +327,9 @@ module PWN
|
|
301
327
|
public_class_method def self.get_scan_issues(opts = {})
|
302
328
|
burp_obj = opts[:burp_obj]
|
303
329
|
rest_browser = burp_obj[:rest_browser]
|
304
|
-
|
330
|
+
pwn_burp_api = burp_obj[:pwn_burp_api]
|
305
331
|
|
306
|
-
scan_issues = rest_browser.get("http://#{
|
332
|
+
scan_issues = rest_browser.get("http://#{pwn_burp_api}/scanissues")
|
307
333
|
JSON.parse(scan_issues)
|
308
334
|
rescue StandardError => e
|
309
335
|
stop(burp_obj: burp_obj) unless burp_obj.nil?
|
@@ -322,9 +348,9 @@ module PWN
|
|
322
348
|
burp_obj = opts[:burp_obj]
|
323
349
|
target_url = opts[:target_url]
|
324
350
|
rest_browser = burp_obj[:rest_browser]
|
325
|
-
|
351
|
+
pwn_burp_api = burp_obj[:pwn_burp_api]
|
326
352
|
report_type = opts[:report_type]
|
327
|
-
# When
|
353
|
+
# When pwn_burp begins to support XML report generation
|
328
354
|
valid_report_types_arr = %i[
|
329
355
|
html
|
330
356
|
xml
|
@@ -337,27 +363,130 @@ module PWN
|
|
337
363
|
scheme = URI.parse(target_url).scheme
|
338
364
|
host = URI.parse(target_url).host
|
339
365
|
port = URI.parse(target_url).port
|
366
|
+
path = URI.parse(target_url).path
|
340
367
|
|
341
368
|
target_domain = format_uri_from_sitemap_resp(
|
342
369
|
scheme: scheme,
|
343
370
|
host: host,
|
344
|
-
port: port
|
371
|
+
port: port,
|
372
|
+
path: path
|
345
373
|
)
|
346
374
|
|
375
|
+
puts "Generating #{report_type} report for #{target_domain}..."
|
347
376
|
report_url = Base64.strict_encode64(target_domain)
|
348
|
-
# Ready scanreport API call in
|
349
|
-
# This is for the older burpbuddy-3.1.1-SNAPSHOT-all.jar
|
377
|
+
# Ready scanreport API call in pwn_burp to support HTML & XML report generation
|
350
378
|
report_resp = rest_browser.get(
|
351
|
-
"http://#{
|
379
|
+
"http://#{pwn_burp_api}/scanreport/#{report_type.to_s.upcase}/#{report_url}"
|
352
380
|
)
|
353
381
|
|
354
|
-
# This is for the older burpbuddy-3.1.0-SNAPSHOT-all.jar
|
355
|
-
# report_resp = rest_browser.get(
|
356
|
-
# "http://#{burpbuddy_api}/scanreport/#{report_url}"
|
357
|
-
# )
|
358
382
|
File.open(output_path, 'w') do |f|
|
359
383
|
f.puts(report_resp.body.gsub("\r\n", "\n"))
|
360
384
|
end
|
385
|
+
rescue RestClient::BadRequest => e
|
386
|
+
puts e.response
|
387
|
+
rescue StandardError => e
|
388
|
+
# stop(burp_obj: burp_obj) unless burp_obj.nil?
|
389
|
+
raise e
|
390
|
+
end
|
391
|
+
|
392
|
+
# Supported Method Parameters::
|
393
|
+
# json_proxy_listeners = PWN::Plugins::BurpSuite.get_proxy_listeners(
|
394
|
+
# burp_obj: 'required - burp_obj returned by #start method'
|
395
|
+
# )
|
396
|
+
|
397
|
+
public_class_method def self.get_proxy_listeners(opts = {})
|
398
|
+
burp_obj = opts[:burp_obj]
|
399
|
+
rest_browser = burp_obj[:rest_browser]
|
400
|
+
pwn_burp_api = burp_obj[:pwn_burp_api]
|
401
|
+
|
402
|
+
listeners = rest_browser.get("http://#{pwn_burp_api}/proxy/listeners", content_type: 'application/json; charset=UTF8')
|
403
|
+
JSON.parse(listeners, symbolize_names: true)
|
404
|
+
rescue StandardError => e
|
405
|
+
stop(burp_obj: burp_obj) unless burp_obj.nil?
|
406
|
+
raise e
|
407
|
+
end
|
408
|
+
|
409
|
+
# Supported Method Parameters::
|
410
|
+
# json_proxy_listener = PWN::Plugins::BurpSuite.add_proxy_listener(
|
411
|
+
# burp_obj: 'required - burp_obj returned by #start method',
|
412
|
+
# bind_address: 'required - bind address for the proxy listener (e.g., "127.0.0.1")',
|
413
|
+
# port: 'required - port for the proxy listener (e.g., 8081)',
|
414
|
+
# enabled: 'optional - enable the listener (defaults to true)'
|
415
|
+
# )
|
416
|
+
|
417
|
+
public_class_method def self.add_proxy_listener(opts = {})
|
418
|
+
burp_obj = opts[:burp_obj]
|
419
|
+
rest_browser = burp_obj[:rest_browser]
|
420
|
+
pwn_burp_api = burp_obj[:pwn_burp_api]
|
421
|
+
bind_address = opts[:bind_address]
|
422
|
+
raise 'ERROR: bind_address parameter is required' if bind_address.nil?
|
423
|
+
|
424
|
+
port = opts[:port]
|
425
|
+
raise 'ERROR: port parameter is required' if port.nil?
|
426
|
+
|
427
|
+
enabled = opts[:enabled] != false # Default to true if not specified
|
428
|
+
|
429
|
+
post_body = {
|
430
|
+
id: "#{bind_address}:#{port}",
|
431
|
+
bind_address: bind_address,
|
432
|
+
port: port,
|
433
|
+
enabled: enabled
|
434
|
+
}.to_json
|
435
|
+
|
436
|
+
listener = rest_browser.post("http://#{pwn_burp_api}/proxy/listeners", post_body, content_type: 'application/json; charset=UTF8')
|
437
|
+
JSON.parse(listener, symbolize_names: true)
|
438
|
+
rescue StandardError => e
|
439
|
+
stop(burp_obj: burp_obj) unless burp_obj.nil?
|
440
|
+
raise e
|
441
|
+
end
|
442
|
+
|
443
|
+
# Supported Method Parameters::
|
444
|
+
# json_proxy_listener = PWN::Plugins::BurpSuite.update_proxy_listener(
|
445
|
+
# burp_obj: 'required - burp_obj returned by #start method',
|
446
|
+
# id: 'optional - ID of the proxy listener (defaults to "127.0.0.1:8080")',
|
447
|
+
# bind_address: 'optional - bind address for the proxy listener (defaults to "127.0.0.1")',
|
448
|
+
# port: 'optional - port for the proxy listener (defaults to 8080)',
|
449
|
+
# enabled: 'optional - enable or disable the listener (defaults to true)'
|
450
|
+
# )
|
451
|
+
|
452
|
+
public_class_method def self.update_proxy_listener(opts = {})
|
453
|
+
burp_obj = opts[:burp_obj]
|
454
|
+
rest_browser = burp_obj[:rest_browser]
|
455
|
+
pwn_burp_api = burp_obj[:pwn_burp_api]
|
456
|
+
id = opts[:id] ||= '127.0.0.1:8080'
|
457
|
+
bind_address = opts[:bind_address] ||= '127.0.0.1'
|
458
|
+
port = opts[:port] ||= 8080
|
459
|
+
enabled = opts[:enabled] != false # Default to true if not specified
|
460
|
+
|
461
|
+
post_body = {
|
462
|
+
id: id,
|
463
|
+
bind_address: bind_address,
|
464
|
+
port: port,
|
465
|
+
enabled: enabled
|
466
|
+
}.to_json
|
467
|
+
|
468
|
+
listener = rest_browser.put("http://#{pwn_burp_api}/proxy/listeners/#{id}", post_body, content_type: 'application/json; charset=UTF8')
|
469
|
+
JSON.parse(listener, symbolize_names: true)
|
470
|
+
rescue StandardError => e
|
471
|
+
stop(burp_obj: burp_obj) unless burp_obj.nil?
|
472
|
+
raise e
|
473
|
+
end
|
474
|
+
|
475
|
+
# Supported Method Parameters::
|
476
|
+
# PWN::Plugins::BurpSuite.delete_proxy_listener(
|
477
|
+
# burp_obj: 'required - burp_obj returned by #start method',
|
478
|
+
# id: 'required - ID of the proxy listener (e.g., "127.0.0.1:8080")'
|
479
|
+
# )
|
480
|
+
|
481
|
+
public_class_method def self.delete_proxy_listener(opts = {})
|
482
|
+
burp_obj = opts[:burp_obj]
|
483
|
+
rest_browser = burp_obj[:rest_browser]
|
484
|
+
pwn_burp_api = burp_obj[:pwn_burp_api]
|
485
|
+
id = opts[:id]
|
486
|
+
raise 'ERROR: id parameter is required' if id.nil?
|
487
|
+
|
488
|
+
rest_browser.delete("http://#{pwn_burp_api}/proxy/listeners/#{id}")
|
489
|
+
true # Return true to indicate successful deletion (or error if API fails)
|
361
490
|
rescue StandardError => e
|
362
491
|
stop(burp_obj: burp_obj) unless burp_obj.nil?
|
363
492
|
raise e
|
@@ -401,15 +530,10 @@ module PWN
|
|
401
530
|
|
402
531
|
public_class_method def self.help
|
403
532
|
puts "USAGE:
|
404
|
-
# PLEASE NOTE: IF RUNNING THIS MODULE THE FIRST TIME, YOU HAVE TO MANUALLY LOAD
|
405
|
-
# /opt/burpsuite/burpsuite_pro.jar INTO THE BURP SUITE PRO UI IN ORDER FOR
|
406
|
-
# THIS TO WORK PROPERLY MOVING FORWARD. THIS SHOULD ONLY BE NECESSARY TO
|
407
|
-
# DO ONCE.
|
408
533
|
burp_obj = #{self}.start(
|
409
|
-
burp_jar_path: '
|
534
|
+
burp_jar_path: 'optional - path of burp suite pro jar file (defaults to /opt/burpsuite/burpsuite_pro.jar)',
|
410
535
|
headless: 'optional - run headless if set to true',
|
411
|
-
browser_type: 'optional - defaults to :firefox. See PWN::Plugins::TransparentBrowser.help for a list of types'
|
412
|
-
target_config: 'optional - path to burp suite pro target config JSON file'
|
536
|
+
browser_type: 'optional - defaults to :firefox. See PWN::Plugins::TransparentBrowser.help for a list of types'
|
413
537
|
)
|
414
538
|
|
415
539
|
uri_in_scope_bool = #{self}.uri_in_scope(
|
@@ -429,6 +553,30 @@ module PWN
|
|
429
553
|
burp_obj: 'required - burp_obj returned by #start method'
|
430
554
|
)
|
431
555
|
|
556
|
+
json_proxy_listeners = #{self}.get_proxy_listeners(
|
557
|
+
burp_obj: 'required - burp_obj returned by #start method'
|
558
|
+
)
|
559
|
+
|
560
|
+
json_proxy_listener = #{self}.add_proxy_listener(
|
561
|
+
burp_obj: 'required - burp_obj returned by #start method',
|
562
|
+
bind_address: 'required - bind address for the proxy listener (e.g., \"127.0.0.1\")',
|
563
|
+
port: 'required - port for the proxy listener (e.g., 8081)',
|
564
|
+
enabled: 'optional - enable the listener (defaults to true)'
|
565
|
+
)
|
566
|
+
|
567
|
+
json_proxy_listener = #{self}.update_proxy_listener(
|
568
|
+
burp_obj: 'required - burp_obj returned by #start method',
|
569
|
+
id: 'required - ID of the proxy listener (e.g., \"127.0.0.1:8080\")',
|
570
|
+
bind_address: 'required - new bind address for the proxy listener',
|
571
|
+
port: 'required - new port for the proxy listener',
|
572
|
+
enabled: 'optional - enable or disable the listener (defaults to true)'
|
573
|
+
)
|
574
|
+
|
575
|
+
#{self}.delete_proxy_listener(
|
576
|
+
burp_obj: 'required - burp_obj returned by #start method',
|
577
|
+
id: 'required - ID of the proxy listener (e.g., \"127.0.0.1:8080\")'
|
578
|
+
)
|
579
|
+
|
432
580
|
active_scan_url_arr = #{self}.invoke_active_scan(
|
433
581
|
burp_obj: 'required - burp_obj returned by #start method',
|
434
582
|
target_url: 'required - target url to scan in sitemap (should be loaded & authenticated w/ burp_obj[:burp_browser])'
|
@@ -440,7 +588,7 @@ module PWN
|
|
440
588
|
|
441
589
|
#{self}.generate_scan_report(
|
442
590
|
burp_obj: 'required - burp_obj returned by #start method',
|
443
|
-
|
591
|
+
target_url: 'required - target_url passed to #invoke_active_scan method',
|
444
592
|
report_type: :html|:xml,
|
445
593
|
output_path: 'required - path to save report results'
|
446
594
|
)
|
@@ -426,6 +426,41 @@ module PWN
|
|
426
426
|
raise e
|
427
427
|
end
|
428
428
|
|
429
|
+
# Supported Method Parameters::
|
430
|
+
# PWN::Plugins::OwaspZap.import_openapi_spec_file(
|
431
|
+
# zap_obj: 'required - zap_obj returned from #open method',
|
432
|
+
# spec: 'required - path to OpenAPI spec file (e.g. /path/to/openapi.yaml)',
|
433
|
+
# target: 'required - target URL to ovverride the service URL in the OpenAPI spec (e.g. https://fq.dn)',
|
434
|
+
# context_id: 'optional - ID of the ZAP context (Defaults to first context, if any)',
|
435
|
+
# user_id: 'optional - ID of the ZAP user (Defaults to first user, if any)'
|
436
|
+
# )
|
437
|
+
|
438
|
+
public_class_method def self.import_openapi_spec_file(opts = {})
|
439
|
+
zap_obj = opts[:zap_obj]
|
440
|
+
api_key = zap_obj[:api_key].to_s.scrub
|
441
|
+
spec = opts[:spec]
|
442
|
+
target = opts[:target]
|
443
|
+
context_id = opts[:context_id]
|
444
|
+
user_id = opts[:user_id]
|
445
|
+
|
446
|
+
params = {
|
447
|
+
apikey: api_key,
|
448
|
+
file: spec,
|
449
|
+
target: target,
|
450
|
+
contextId: context_id,
|
451
|
+
user_id: user_id
|
452
|
+
}
|
453
|
+
|
454
|
+
zap_rest_call(
|
455
|
+
zap_obj: zap_obj,
|
456
|
+
rest_call: "JSON/break/action/openapi/?zapapiformat=JSON&apikey=#{api_key}",
|
457
|
+
params: params
|
458
|
+
)
|
459
|
+
rescue StandardError, SystemExit, Interrupt => e
|
460
|
+
stop(zap_obj) unless zap_obj.nil?
|
461
|
+
raise e
|
462
|
+
end
|
463
|
+
|
429
464
|
# Supported Method Parameters::
|
430
465
|
# watir_resp = PWN::Plugins::OwaspZap.request(
|
431
466
|
# zap_obj: 'required - zap_obj returned from #open method',
|
data/lib/pwn/version.rb
CHANGED
data/third_party/pwn_rdoc.jsonl
CHANGED
@@ -502,7 +502,7 @@
|
|
502
502
|
{"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.get_scan_issues Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.get_scan_issues`: Supported Method Parameters\n\njson_scan_issues = PWN::Plugins::BurpSuite.get_scan_issues(\n\nburp_obj: 'required - burp_obj returned by #start method'\n\n)\n"}]}
|
503
503
|
{"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.help Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.help`: "}]}
|
504
504
|
{"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.invoke_active_scan Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.invoke_active_scan`: Supported Method Parameters\n\nactive_scan_url_arr = PWN::Plugins::BurpSuite.invoke_active_scan(\n\nburp_obj: 'required - burp_obj returned by #start method',\ntarget_url: 'required - target url to scan in sitemap (should be loaded & authenticated w/ burp_obj[:burp_browser])'\n\n)\n"}]}
|
505
|
-
{"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.start Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.start`: Supported Method Parameters\n\nburp_obj = PWN::Plugins::BurpSuite.start(\n\nburp_jar_path: 'options - path of burp suite pro jar file (defaults to /opt/burpsuite/burpsuite_pro.jar)',\nheadless: 'optional - run burp headless if set to true',\nbrowser_type: 'optional - defaults to :firefox. See PWN::Plugins::TransparentBrowser.help for a list of types'
|
505
|
+
{"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.start Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.start`: Supported Method Parameters\n\nburp_obj = PWN::Plugins::BurpSuite.start(\n\nburp_jar_path: 'options - path of burp suite pro jar file (defaults to /opt/burpsuite/burpsuite_pro.jar)',\nheadless: 'optional - run burp headless if set to true',\nbrowser_type: 'optional - defaults to :firefox. See PWN::Plugins::TransparentBrowser.help for a list of types'\n\n)\n"}]}
|
506
506
|
{"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.stop Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.stop`: Supported Method Parameters\n\nPWN::Plugins::BurpSuite.stop(\n\nburp_obj: 'required - burp_obj returned by #start method'\n\n)\n"}]}
|
507
507
|
{"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.update_burp_jar Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.update_burp_jar`: Supported Method Parameters\n\nPWN::Plugins::BurpSuite.update_burp_jar( )\n"}]}
|
508
508
|
{"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.uri_in_scope Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.uri_in_scope`: Supported Method Parameters\n\nuri_in_scope_bool = PWN::Plugins::BurpSuite.uri_in_scope(\n\ntarget_config: 'required - path to burp suite pro target config JSON file',\nuri: 'required - URI to determine if in scope'\n\n)\n"}]}
|
@@ -800,6 +800,7 @@
|
|
800
800
|
{"messages":[{"role":"user","content":"PWN::Plugins::OwaspZap.breakpoint Usage"},{"role":"assistant","content":"`PWN::Plugins::OwaspZap.breakpoint`: Supported Method Parameters\n\nPWN::Plugins::OwaspZap.breakpoint(\n\nzap_obj: 'required - zap_obj returned from #open method',\nregex_type: 'required - :url, :request_header, :request_body, :response_header or :response_body',\nregex_pattern: 'required - regex pattern to search for respective regex_type',\nenabled: 'optional - boolean (defaults to true)'\n\n)\n"}]}
|
801
801
|
{"messages":[{"role":"user","content":"PWN::Plugins::OwaspZap.generate_report Usage"},{"role":"assistant","content":"`PWN::Plugins::OwaspZap.generate_report`: Supported Method Parameters\n\nreport_path = PWN::Plugins::OwaspZap.generate_report(\n\nzap_obj: 'required - zap_obj returned from #open method',\noutput_dir: 'required - directory to save report',\nreport_type: 'required - <html|markdown|xml>'\n\n)\n"}]}
|
802
802
|
{"messages":[{"role":"user","content":"PWN::Plugins::OwaspZap.help Usage"},{"role":"assistant","content":"`PWN::Plugins::OwaspZap.help`: "}]}
|
803
|
+
{"messages":[{"role":"user","content":"PWN::Plugins::OwaspZap.import_openapi_spec_file Usage"},{"role":"assistant","content":"`PWN::Plugins::OwaspZap.import_openapi_spec_file`: Supported Method Parameters\n\nPWN::Plugins::OwaspZap.import_openapi_spec_file(\n\nzap_obj: 'required - zap_obj returned from #open method',\nspec: 'required - path to OpenAPI spec file (e.g. /path/to/openapi.yaml)',\ntarget: 'required - target URL to ovverride the service URL in the OpenAPI spec (e.g. https://fq.dn)',\ncontext_id: 'optional - ID of the ZAP context (Defaults to first context, if any)',\nuser_id: 'optional - ID of the ZAP user (Defaults to first user, if any)'\n\n)\n"}]}
|
803
804
|
{"messages":[{"role":"user","content":"PWN::Plugins::OwaspZap.request Usage"},{"role":"assistant","content":"`PWN::Plugins::OwaspZap.request`: Supported Method Parameters\n\nwatir_resp = PWN::Plugins::OwaspZap.request(\n\nzap_obj: 'required - zap_obj returned from #open method',\nbrowser_obj: 'required - browser_obj w/ browser_type: :firefox||:headless returned from #open method',\ninstruction: 'required - watir instruction to make (e.g. button(text: \"Google Search\").click)'\n\n)\n"}]}
|
804
805
|
{"messages":[{"role":"user","content":"PWN::Plugins::OwaspZap.spider Usage"},{"role":"assistant","content":"`PWN::Plugins::OwaspZap.spider`: Supported Method Parameters\n\nPWN::Plugins::OwaspZap.spider(\n\nzap_obj: 'required - zap_obj returned from #open method',\ntarget: 'required - url to spider'\n\n)\n"}]}
|
805
806
|
{"messages":[{"role":"user","content":"PWN::Plugins::OwaspZap.start Usage"},{"role":"assistant","content":"`PWN::Plugins::OwaspZap.start`: Supported Method Parameters\n\nzap_obj = PWN::Plugins::OwaspZap.start(\n\napi_key: 'required - api key for API authorization',\nzap_bin_path: 'optional - path to zap.sh file'\nheadless: 'optional - run zap headless if set to true',\nproxy: 'optional - change local zap proxy listener (defaults to http://127.0.0.1:<Random 1024-65535>)',\n\n)\n"}]}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pwn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.330
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 0day Inc.
|
@@ -337,14 +337,14 @@ dependencies:
|
|
337
337
|
requirements:
|
338
338
|
- - '='
|
339
339
|
- !ruby/object:Gem::Version
|
340
|
-
version: 0.
|
340
|
+
version: 0.29.0
|
341
341
|
type: :runtime
|
342
342
|
prerelease: false
|
343
343
|
version_requirements: !ruby/object:Gem::Requirement
|
344
344
|
requirements:
|
345
345
|
- - '='
|
346
346
|
- !ruby/object:Gem::Version
|
347
|
-
version: 0.
|
347
|
+
version: 0.29.0
|
348
348
|
- !ruby/object:Gem::Dependency
|
349
349
|
name: htmlentities
|
350
350
|
requirement: !ruby/object:Gem::Requirement
|
@@ -407,14 +407,14 @@ dependencies:
|
|
407
407
|
requirements:
|
408
408
|
- - '='
|
409
409
|
- !ruby/object:Gem::Version
|
410
|
-
version: 2.13.
|
410
|
+
version: 2.13.1
|
411
411
|
type: :runtime
|
412
412
|
prerelease: false
|
413
413
|
version_requirements: !ruby/object:Gem::Requirement
|
414
414
|
requirements:
|
415
415
|
- - '='
|
416
416
|
- !ruby/object:Gem::Version
|
417
|
-
version: 2.13.
|
417
|
+
version: 2.13.1
|
418
418
|
- !ruby/object:Gem::Dependency
|
419
419
|
name: jsonpath
|
420
420
|
requirement: !ruby/object:Gem::Requirement
|
@@ -925,14 +925,14 @@ dependencies:
|
|
925
925
|
requirements:
|
926
926
|
- - '='
|
927
927
|
- !ruby/object:Gem::Version
|
928
|
-
version: 1.
|
928
|
+
version: 1.79.0
|
929
929
|
type: :runtime
|
930
930
|
prerelease: false
|
931
931
|
version_requirements: !ruby/object:Gem::Requirement
|
932
932
|
requirements:
|
933
933
|
- - '='
|
934
934
|
- !ruby/object:Gem::Version
|
935
|
-
version: 1.
|
935
|
+
version: 1.79.0
|
936
936
|
- !ruby/object:Gem::Dependency
|
937
937
|
name: rubocop-rake
|
938
938
|
requirement: !ruby/object:Gem::Requirement
|
@@ -2298,7 +2298,6 @@ files:
|
|
2298
2298
|
- spec/lib/pwn_spec.rb
|
2299
2299
|
- spec/spec_helper.rb
|
2300
2300
|
- third_party/.gitkeep
|
2301
|
-
- third_party/burpbuddy-3.1.1-SNAPSHOT-all.jar
|
2302
2301
|
- third_party/http-request-headers-fields-large.txt
|
2303
2302
|
- third_party/pwn_rdoc.jsonl
|
2304
2303
|
- third_party/r2-pwn-layout
|
Binary file
|