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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0843f0e4e3ed905cafcb9ca071cedac0f2bd5707f1b087ddb9720d4bbea12bd2'
4
- data.tar.gz: 8587c3be1cffbeda6c0f46d2e513a2570bd0339995172bf9d5c0ff0c2c4146c8
3
+ metadata.gz: c2402a13b3e2cd7cbbdd21760049fce61980dc14871236a6345d51c50dae439b
4
+ data.tar.gz: e31a43da568d89bea803c9de5985edd089f7fea80db82fd9fa871fcfb524fe73
5
5
  SHA512:
6
- metadata.gz: 6e1cab51e4759e9409203f465575f9359f1f4baa19d1149bfaf3e5fe57e32f2d03b16d14ceeaee79fdb4a9420dbf409f7084560b5847505dd0623d9fe9b7b6d2
7
- data.tar.gz: 50cc81e0012b45ec88821d0b129cefd02dca8123c261f2f88cab3b49ce418ee3b07f47a92bc3ef6255663db1846dba9dc795d48da30ea6b1e16dc7f5d7da8f75
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.28.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.0'
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.78.0'
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.327]:001 >>> PWN.help
40
+ pwn[v0.5.330]:001 >>> PWN.help
41
41
  ```
42
42
 
43
43
  [![Installing the pwn Security Automation Framework](https://raw.githubusercontent.com/0dayInc/pwn/master/documentation/pwn_install.png)](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.327]:001 >>> PWN.help
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.327]:001 >>> PWN.help
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
- if implicit_http_ports_arr.include?(port)
35
- uri = "#{scheme}://#{host}#{path}"
36
- else
37
- uri = "#{scheme}://#{host}:#{port}#{path}"
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: 'options - path of burp suite pro jar file (defaults to /opt/burpsuite/burpsuite_pro.jar)',
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
- # target_config: 'optional - path to burp suite pro target config JSON file'
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/burpsuite_pro.jar'
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
- target_config = opts[:target_config]
64
-
65
- if opts[:headless]
66
- # burp_cmd_string = "java -Xmx4G -Djava.awt.headless=true -classpath #{burp_root}/burpbuddy.jar:#{burp_jar_path} burp.StartBurp"
67
- burp_cmd_string = "java -Xmx4G -Djava.awt.headless=true -classpath #{burp_root}/burpbuddy.jar -jar #{burp_jar_path}"
68
- else
69
- # burp_cmd_string = "java -Xmx4G -classpath #{burp_root}/burpbuddy.jar:#{burp_jar_path} burp.StartBurp"
70
- burp_cmd_string = "java -Xmx4G -classpath #{burp_root}/burpbuddy.jar -jar #{burp_jar_path}"
71
- end
72
- burp_cmd_string = "#{burp_cmd_string} --config-file=#{target_config}" if target_config && File.exist?(target_config)
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
- # random_mitm_port = PWN::Plugins::Sock.get_random_unused_port
81
- # random_bb_port = random_mitm_port
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 TCP 8001 to open prior to returning burp_obj
98
+ # Wait for pwn_burp_port to open prior to returning burp_obj
96
99
  loop do
97
- s = TCPSocket.new('127.0.0.1', 8001)
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
- burpbuddy_api = burp_obj[:burpbuddy_api]
171
+ pwn_burp_api = burp_obj[:pwn_burp_api]
160
172
 
161
- enable_resp = rest_browser.post("http://#{burpbuddy_api}/proxy/intercept/enable", nil)
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
- burpbuddy_api = burp_obj[:burpbuddy_api]
187
+ pwn_burp_api = burp_obj[:pwn_burp_api]
176
188
 
177
- disable_resp = rest_browser.post("http://#{burpbuddy_api}/proxy/intercept/disable", nil)
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
- burpbuddy_api = burp_obj[:burpbuddy_api]
192
-
193
- sitemap = rest_browser.get("http://#{burpbuddy_api}/sitemap", content_type: 'application/json; charset=UTF8')
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
- burpbuddy_api = burp_obj[:burpbuddy_api]
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://#{burpbuddy_api}/scope", post_body, content_type: 'application/json; charset=UTF8')
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
- burpbuddy_api = burp_obj[:burpbuddy_api]
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
- use_https = false
237
- else
238
- use_https = true
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
- json_http_svc = site['http_service']
245
- json_req = site['request']
246
- json_protocol = json_http_svc['protocol']
247
- json_host = json_http_svc['host'].to_s.scrub.strip.chomp
248
- json_port = json_http_svc['port'].to_i
249
- json_path = json_req['path']
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
- # More info on the BurpBuddy API can be found here:
261
- # https://github.com/tomsteele/burpbuddy/blob/master/src/main/kotlin/burp/API.kt
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: json_req['raw']
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://#{burpbuddy_api}/scan/active", post_body, content_type: 'application/json')
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://#{burpbuddy_api}/scan/active")
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://#{burpbuddy_api}/scan/active/#{this_scan_item_id}")
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
- burpbuddy_api = burp_obj[:burpbuddy_api]
330
+ pwn_burp_api = burp_obj[:pwn_burp_api]
305
331
 
306
- scan_issues = rest_browser.get("http://#{burpbuddy_api}/scanissues")
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
- burpbuddy_api = burp_obj[:burpbuddy_api]
351
+ pwn_burp_api = burp_obj[:pwn_burp_api]
326
352
  report_type = opts[:report_type]
327
- # When burpbuddy begins to support XML report generation
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 burpbuddy to support HTML & XML report generation
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://#{burpbuddy_api}/scanreport/#{report_type.to_s.upcase}/#{report_url}"
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: 'required - path of burp suite pro jar file (defaults to /opt/burpsuite/burpsuite_pro.jar)',
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
- active_scan_url_arr: 'required - active_scan_url_arr returned by #invoke_active_scan method',
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PWN
4
- VERSION = '0.5.327'
4
+ VERSION = '0.5.330'
5
5
  end
@@ -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',\ntarget_config: 'optional - path to burp suite pro target config JSON file'\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'\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.327
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.28.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.28.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.0
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.0
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.78.0
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.78.0
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