pwn 0.5.496 → 0.5.497

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: bd65663e9522de07f7a818795b857aabd14bcacc219de51b8524dfbf8b6a7b2b
4
- data.tar.gz: ea6abda9dd1d68e00b1a11f93a455e10c15bb91690979853a6bfec0cae33ecd7
3
+ metadata.gz: fc62a689871a26571f1d0a2cfb4b5c54f3e141193ce296b6d5ffe02b663620d0
4
+ data.tar.gz: ac4355cc47e2137b31d9136456eb4551d20ff1bdd663fee7f0a3c7ce4792dd13
5
5
  SHA512:
6
- metadata.gz: 404c8240305e111d85d7c600e45e558097c912fa7955ecba7bafe1c319d8f0b2b6a08475439acbb1320993fa2d729ddf8bf6de4c908c0a736e8594c960a985b3
7
- data.tar.gz: 5689c6e8c2cde63fda33290b2837722a43acc3a4f21edfc017b9e3efd3977d30037bca8b819578d7cacb5b08501de4948b226d29aba82b707b62c80a1ac23ed2
6
+ metadata.gz: ea4bdea71706c9799647f47c3c2e336786c63bcdc136b802e1c8c2f880f216a4466bd92bed7537f9fcfd9f9af398507f59604dc102bb4c8b3d7c0118c626191a
7
+ data.tar.gz: 3b9ccf0836db5973162a3bfde9ed106ab2f6597e250e7046927b5be5c2f497c27da20005312fc2ca0b91f86e32c9efc30c4c6acc8970e29a34c3745842008f42
data/.rubocop.yml CHANGED
@@ -18,7 +18,7 @@ Metrics/CyclomaticComplexity:
18
18
  Metrics/MethodLength:
19
19
  Max: 565
20
20
  Metrics/ModuleLength:
21
- Max: 1149
21
+ Max: 1447
22
22
  Metrics/PerceivedComplexity:
23
23
  Max: 157
24
24
  Style/HashEachMethods:
data/Gemfile CHANGED
@@ -93,7 +93,7 @@ gem 'selenium-webdriver', '4.38.0'
93
93
  gem 'slack-ruby-client', '3.0.0'
94
94
  gem 'socksify', '1.8.1'
95
95
  gem 'spreadsheet', '1.3.4'
96
- gem 'sqlite3', '2.7.4'
96
+ gem 'sqlite3', '2.8.0'
97
97
  gem 'thin', '2.0.1'
98
98
  gem 'tty-prompt', '0.23.1'
99
99
  gem 'tty-spinner', '0.9.3'
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.496]:001 >>> PWN.help
40
+ pwn[v0.5.497]: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.496]:001 >>> PWN.help
55
+ pwn[v0.5.497]: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.496]:001 >>> PWN.help
65
+ pwn[v0.5.497]: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:
data/lib/pwn/ai/grok.rb CHANGED
@@ -132,7 +132,7 @@ module PWN
132
132
 
133
133
  # Supported Method Parameters::
134
134
  # response = PWN::AI::Grok.chat(
135
- # request: 'required - message to ChatGPT'
135
+ # request: 'required - message to Grok'
136
136
  # model: 'optional - model to use for text generation (defaults to PWN::Env[:ai][:grok][:model])',
137
137
  # temp: 'optional - creative response float (deafults to PWN::Env[:ai][:grok][:temp])',
138
138
  # system_role_content: 'optional - context to set up the model behavior for conversation (Default: PWN::Env[:ai][:grok][:system_role_content])',
@@ -145,6 +145,9 @@ module PWN
145
145
  public_class_method def self.chat(opts = {})
146
146
  engine = PWN::Env[:ai][:grok]
147
147
  request = opts[:request]
148
+ max_prompt_length = engine[:max_prompt_length] ||= 256_000
149
+ request_trunc_idx = ((max_prompt_length - 1) / 3.36).floor
150
+ request = request[0..request_trunc_idx]
148
151
 
149
152
  model = opts[:model] ||= engine[:model]
150
153
  raise 'ERROR: Model is required. Call #get_models method for details' if model.nil?
@@ -237,7 +240,7 @@ module PWN
237
240
  models = #{self}.get_models
238
241
 
239
242
  response = #{self}.chat(
240
- request: 'required - message to ChatGPT',
243
+ request: 'required - message to Grok',
241
244
  model: 'optional - model to use for text generation (defaults to PWN::Env[:ai][:grok][:model])',
242
245
  temp: 'optional - creative response float (defaults to PWN::Env[:ai][:grok][:temp])',
243
246
  system_role_content: 'optional - context to set up the model behavior for conversation (Default: PWN::Env[:ai][:grok][:system_role_content])',
@@ -12,7 +12,8 @@ module PWN
12
12
  # response = PWN::AI::Introspection.reflect_on(
13
13
  # request: 'required - String - What you want the AI to reflect on',
14
14
  # system_role_content: 'optional - context to set up the model behavior for reflection',
15
- # spinner: 'optional - Boolean - Display spinner during operation (default: false)'
15
+ # spinner: 'optional - Boolean - Display spinner during operation (default: false)',
16
+ # suppress_pii_warning: 'optional - Boolean - Suppress PII Warnings (default: false)'
16
17
  # )
17
18
 
18
19
  public_class_method def self.reflect_on(opts = {})
@@ -23,6 +24,8 @@ module PWN
23
24
 
24
25
  spinner = opts[:spinner] || false
25
26
 
27
+ suppress_pii_warning = opts[:suppress_pii_warning] || false
28
+
26
29
  response = nil
27
30
 
28
31
  ai_introspection = PWN::Env[:ai][:introspection]
@@ -32,6 +35,7 @@ module PWN
32
35
  engine = PWN::Env[:ai][:active].to_s.downcase.to_sym
33
36
  raise "ERROR: Unsupported AI engine. Supported engines are: #{valid_ai_engines}" unless valid_ai_engines.include?(engine)
34
37
 
38
+ puts "WARNING: AI Introspection is enabled. Ensure #{engine} has been authorized for use and/or requests are sanitized properly." unless suppress_pii_warning
35
39
  case engine
36
40
  when :grok
37
41
  response = PWN::AI::Grok.chat(
@@ -84,7 +88,8 @@ module PWN
84
88
  #{self}.reflect_on(
85
89
  request: 'required - String - What you want the AI to reflect on',
86
90
  system_role_content: 'optional - context to set up the model behavior for reflection',
87
- spinner: 'optional - Boolean - Display spinner during operation (default: false)'
91
+ spinner: 'optional - Boolean - Display spinner during operation (default: false)',
92
+ suppress_pii_warning: 'optional - Boolean - Suppress PII Warnings (default: false)'
88
93
  )
89
94
 
90
95
  #{self}.authors
data/lib/pwn/ai/ollama.rb CHANGED
@@ -134,7 +134,7 @@ module PWN
134
134
 
135
135
  # Supported Method Parameters::
136
136
  # response = PWN::AI::Ollama.chat(
137
- # request: 'required - message to ChatGPT'
137
+ # request: 'required - message to Ollama'
138
138
  # model: 'optional - model to use for text generation (defaults to PWN::Env[:ai][:ollama][:model])',
139
139
  # temp: 'optional - creative response float (deafults to PWN::Env[:ai][:ollama][:temp])',
140
140
  # system_role_content: 'optional - context to set up the model behavior for conversation (Default: PWN::Env[:ai][:ollama][:system_role_content])',
@@ -147,6 +147,9 @@ module PWN
147
147
  public_class_method def self.chat(opts = {})
148
148
  engine = PWN::Env[:ai][:ollama]
149
149
  request = opts[:request]
150
+ max_prompt_length = engine[:max_prompt_length] ||= 1_000_000
151
+ request_trunc_idx = ((max_prompt_length - 1) / 3.36).floor
152
+ request = request[0..request_trunc_idx]
150
153
 
151
154
  model = opts[:model] ||= engine[:model]
152
155
  raise 'ERROR: Model is required. Call #get_models method for details' if model.nil?
@@ -239,7 +242,7 @@ module PWN
239
242
  models = #{self}.get_models
240
243
 
241
244
  response = #{self}.chat(
242
- request: 'required - message to ChatGPT',
245
+ request: 'required - message to Ollama',
243
246
  model: 'optional - model to use for text generation (defaults to PWN::Env[:ai][:ollama][:model])',
244
247
  temp: 'optional - creative response float (defaults to PWN::Env[:ai][:ollama][:temp])',
245
248
  system_role_content: 'optional - context to set up the model behavior for conversation (Default: PWN::Env[:ai][:ollama][:system_role_content])',
@@ -143,6 +143,9 @@ module PWN
143
143
  public_class_method def self.chat(opts = {})
144
144
  engine = PWN::Env[:ai][:openai]
145
145
  request = opts[:request]
146
+ max_prompt_length = engine[:max_prompt_length] ||= 128_000
147
+ request_trunc_idx = ((max_prompt_length - 1) / 3.36).floor
148
+ request = request[0..request_trunc_idx]
146
149
 
147
150
  model = opts[:model] ||= engine[:model]
148
151
 
@@ -185,7 +185,8 @@ module PWN
185
185
  system_role_content = 'Provide a useful summary of this latest bitcoin block returned from a bitcoin node via getblockchaininfo.'
186
186
  ai_analysis = PWN::AI::Introspection.reflect_on(
187
187
  request: latest_block.to_s,
188
- system_role_content: system_role_content
188
+ system_role_content: system_role_content,
189
+ suppress_pii_warning: true
189
190
  )
190
191
  puts ai_analysis
191
192
 
data/lib/pwn/config.rb CHANGED
@@ -35,21 +35,24 @@ module PWN
35
35
  key: 'required - OpenAI API Key',
36
36
  model: 'optional - Grok model to use',
37
37
  system_role_content: 'You are an ethically hacking OpenAI agent.',
38
- temp: 'optional - OpenAI temperature'
38
+ temp: 'optional - OpenAI temperature',
39
+ max_prompt_length: 256_000
39
40
  },
40
41
  openai: {
41
42
  base_uri: 'optional - Base URI for OpenAI - Use private base OR defaults to https://api.openai.com/v1',
42
43
  key: 'required - OpenAI API Key',
43
44
  model: 'optional - OpenAI model to use',
44
45
  system_role_content: 'You are an ethically hacking OpenAI agent.',
45
- temp: 'optional - OpenAI temperature'
46
+ temp: 'optional - OpenAI temperature',
47
+ max_prompt_length: 128_000
46
48
  },
47
49
  ollama: {
48
50
  base_uri: 'required - Base URI for Open WebUI - e.g. https://ollama.local',
49
51
  key: 'required - Open WebUI API Key Under Settings >> Account >> JWT Token',
50
52
  model: 'required - Ollama model to use',
51
53
  system_role_content: 'You are an ethically hacking Ollama agent.',
52
- temp: 'optional - Ollama temperature'
54
+ temp: 'optional - Ollama temperature',
55
+ max_prompt_length: 32_000
53
56
  }
54
57
  },
55
58
  plugins: {
@@ -25,10 +25,11 @@ module PWN
25
25
 
26
26
  raise 'ERROR: opcodes parameter is required.' if opcodes.nil?
27
27
 
28
- system_role_content = "Analyze the #{endian} endian #{arch} assembly opcodes below and provide a concise summary of their functionality."
28
+ system_role_content = "Analyze the #{endian} endian #{arch} assembly opcodes below and provide a concise summary of their functionality. If possible, also convert the assembly to c/c++ code."
29
29
  ai_analysis = PWN::AI::Introspection.reflect_on(
30
30
  request: opcodes,
31
- system_role_content: system_role_content
31
+ system_role_content: system_role_content,
32
+ suppress_pii_warning: true
32
33
  )
33
34
 
34
35
  case arch.to_s.downcase
@@ -140,7 +141,8 @@ module PWN
140
141
  system_role_content = "Analyze the #{endian} endian #{arch} assembly instructions below and provide a concise summary of their functionality."
141
142
  ai_analysis = PWN::AI::Introspection.reflect_on(
142
143
  request: asm,
143
- system_role_content: system_role_content
144
+ system_role_content: system_role_content,
145
+ suppress_pii_warning: true
144
146
  )
145
147
 
146
148
  case arch.to_s.downcase
@@ -80,7 +80,7 @@ module PWN
80
80
 
81
81
  # Construct burp_obj
82
82
  burp_obj = {}
83
- burp_obj[:pid] = Process.spawn(burp_cmd_string)
83
+ burp_obj[:pid] = Process.spawn(burp_cmd_string, pgroup: true)
84
84
  browser_obj1 = PWN::Plugins::TransparentBrowser.open(browser_type: :rest)
85
85
  rest_browser = browser_obj1[:browser]
86
86
 
@@ -124,6 +124,116 @@ module PWN
124
124
  enabled: true
125
125
  )
126
126
 
127
+ # if PWN::Env[:ai][:introspection] is true,
128
+ # spin up PWN::Plugins::ThreadPool to
129
+ # 1. Periodically call get_proxy_history(burp_obj: burp_obj) method
130
+ # 2. For each entry w/ empty comment,
131
+ # generate AI analysis via PWN::AI::Introspection.reflect_on
132
+ # and populate the comment field for the entry.
133
+ # 3. Update the highlight field based on EPSS score extracted from AI analysis.
134
+ # 4. Call update_proxy_history(burp_obj: burp_obj, entry: updated_entry)
135
+ if PWN::Env[:ai][:introspection]
136
+ proxy_history_introspection = Thread.new do
137
+ loop do
138
+ proxy_history = get_proxy_history(burp_obj: burp_obj)
139
+ proxy_history.each do |entry|
140
+ next unless entry.key?(:comment) && entry[:comment].to_s.strip.empty?
141
+
142
+ request = entry[:request]
143
+ response = entry[:response]
144
+ host = entry[:http_service][:host]
145
+ port = entry[:http_service][:port]
146
+ protocol = entry[:http_service][:protocol]
147
+ next if request.nil? || response.nil? || host.nil? || port.nil? || protocol.nil?
148
+
149
+ request = Base64.strict_decode64(request)
150
+ response = Base64.strict_decode64(response)
151
+
152
+ http_request_response = PWN::Plugins::Char.force_utf8("#{request}\r\n\r\n#{response}")
153
+ system_role_content = '
154
+ Your expertise lies in dissecting HTTP request/response pairs to identify high-impact vulnerabilities, including but not limited to XSS (reflected, stored, DOM-based), CSRF, SSRF, IDOR, open redirects, CORS misconfigurations, authentication bypasses, SQLi/NoSQLi, command/code injection, business logic flaws, and API abuse. You prioritize zero-days and novel chains, always focusing on exploitability, impact (e.g., account takeover, data exfiltration, RCE), and reproducibility.
155
+
156
+ When analyzing HTTP request/response pairs:
157
+
158
+ 1. **Parse and Contextualize Traffic**:
159
+ - Break down every element: HTTP method, URI (path, query parameters), headers (e.g., Host, User-Agent, Cookies, Authorization, Referer, Origin, Content-Type), request body (e.g., form data, JSON payloads), response status code, response headers, and response body (HTML, JSON, XML, etc.).
160
+ - Identify dynamic elements: User-controlled inputs (e.g., query params, POST data, headers like X-Forwarded-For), server-side echoes, redirects, and client-side processing.
161
+ - Trace data flow: Map how inputs propagate from request to response, including any client-side JavaScript execution where exploitation may be possible in the client without communicating with the server (e.g. DOM-XSS).
162
+
163
+ 2. **Vulnerability Hunting Framework**:
164
+ - **Input Validation & Sanitization**: Check for unescaped/lack of encoding in outputs (e.g., HTML context for XSS, URL context for open redirects).
165
+ - **XSS Focus**: Hunt for sinks like innerHTML/outerHTML, document.write, eval, setTimeout/setInterval with strings, location.href/assign/replace, and history.pushState. Test payloads like <script>alert(1)</script>, javascript:alert(1), and polyglots. For DOM-based, simulate client-side execution.
166
+ - **JavaScript Library Analysis**: If JS is present (e.g., in response body or referenced scripts), deobfuscate and inspect:
167
+ - Objects/properties that could clobber DOM (e.g., window.name, document.cookie manipulation leading to prototype pollution).
168
+ - DOM XSS vectors: Analyze event handlers, querySelector, addEventListener with unsanitized data from location.hash/search, postMessage, or localStorage.
169
+ - Third-party libs (e.g., jQuery, React): Flag known sink patterns like .html(), dangerouslySetInnerHTML, or eval-like functions.
170
+ - **Server-Side Issues**: Probe for SSRF (e.g., via URL params fetching internal resources), IDOR (e.g., manipulating IDs in paths/bodies), rate limiting bypass, and insecure deserialization (e.g., in JSON/PHP objects).
171
+ - **Headers & Misc**: Examine for exposed sensitive info (e.g., debug headers, stack traces), misconfigured security headers (CSP, HSTS), and upload flaws (e.g., file extension bypass).
172
+ - **Chaining Opportunities**: Always consider multi-step exploits, like XSS leading to CSRF token theft or SSRF to internal metadata endpoints.
173
+
174
+ 3. **PoC Generation**:
175
+ - Produce concise, step-by-step PoCs in a standardized format:
176
+ - **Description**: Clear vuln summary, CVSS-like severity, and impact.
177
+ - **Steps to Reproduce**: Numbered HTTP requests (use curl or Burp syntax, e.g., `curl -X POST -d "param=<payload>" https://target.com/endpoint`).
178
+ - **Payloads**: Provide working, minimal payloads with variations for evasion (e.g., encoded, obfuscated).
179
+ - **Screenshots/Evidence**: Suggest what to capture (e.g., alert popup for XSS, response diff for IDOR).
180
+ - **Mitigation Advice**: Recommend fixes (e.g., output encoding, input validation).
181
+ - Ensure PoCs are ethical: Target only in-scope assets, avoid DoS, and emphasize disclosure via proper channels (e.g., HackerOne, Bugcrowd).
182
+ - If no vuln found, explain why and suggest further tests (e.g., fuzzing params).
183
+ 4. Risk Score:
184
+ For each analysis generate a risk score between 0% - 100% based on exploitability and impact. This should be reflected as { "risk_score": "nnn%" } in the final output JSON.
185
+
186
+ Analyze provided HTTP request/response pairs methodically: Start with a high-level overview, then dive into specifics, flag potential issues with evidence from the traffic, and end with PoC if applicable. Be verbose in reasoning but concise in output. Prioritize high-severity findings. If data is incomplete, request clarifications.
187
+ '
188
+
189
+ ai_analysis = PWN::AI::Introspection.reflect_on(
190
+ system_role_content: system_role_content,
191
+ request: http_request_response,
192
+ suppress_pii_warning: true
193
+ )
194
+
195
+ next if ai_analysis.nil? || ai_analysis.strip.empty?
196
+
197
+ entry[:comment] = ai_analysis
198
+ # Extract score and assign color highlight based on severity
199
+ if ai_analysis =~ /"risk_score":\s*"(\d{1,3})%"/
200
+ score = Regexp.last_match(1).to_i
201
+ highlight_color = case score
202
+ when 0..24
203
+ 'GREEN'
204
+ when 25..49
205
+ 'YELLOW'
206
+ when 50..74
207
+ 'ORANGE'
208
+ when 75..100
209
+ 'RED'
210
+ end
211
+ end
212
+ highlight_color ||= 'GRAY'
213
+ entry[:highlight] = highlight_color
214
+
215
+ entry.delete(:request)
216
+ entry.delete(:response)
217
+ entry.delete(:http_service)
218
+
219
+ update_proxy_history(
220
+ burp_obj: burp_obj,
221
+ entry: entry
222
+ )
223
+ end
224
+ sleep 10
225
+ end
226
+ rescue Errno::ECONNREFUSED
227
+ puts 'BurpSuite Proxy History AI Introspection Thread Terminating...'
228
+ rescue StandardError => e
229
+ puts "BurpSuite Proxy History AI Introspection Thread Error: #{e}"
230
+ puts e.backtrace
231
+ raise e
232
+ end
233
+
234
+ burp_obj[:proxy_history_introspection_thread] = proxy_history_introspection
235
+ end
236
+
127
237
  burp_obj
128
238
  rescue StandardError => e
129
239
  stop(burp_obj: burp_obj) unless burp_obj.nil?
@@ -296,7 +406,6 @@ module PWN
296
406
  enabled = opts[:enabled] != false # Default to true if not specified
297
407
 
298
408
  proxy_listeners = get_proxy_listeners(burp_obj: burp_obj)
299
- puts "Proxy Listeners: #{proxy_listeners.inspect}"
300
409
  last_known_proxy_id = 0
301
410
  last_known_proxy_id = proxy_listeners.last[:id].to_i if proxy_listeners.any?
302
411
  next_id = last_known_proxy_id + 1
@@ -374,6 +483,219 @@ module PWN
374
483
  raise e
375
484
  end
376
485
 
486
+ # Supported Method Parameters::
487
+ # json_proxy_history = PWN::Plugins::BurpSuite.get_proxy_history(
488
+ # burp_obj: 'required - burp_obj returned by #start method',
489
+ # keyword: 'optional - keyword to filter proxy history entries (default: nil)',
490
+ # return_as: 'optional - :base64 or :har (defaults to :base64)'
491
+ # )
492
+
493
+ public_class_method def self.get_proxy_history(opts = {})
494
+ burp_obj = opts[:burp_obj]
495
+ rest_browser = burp_obj[:rest_browser]
496
+ mitm_rest_api = burp_obj[:mitm_rest_api]
497
+ keyword = opts[:keyword]
498
+ return_as = opts[:return_as] ||= :base64
499
+
500
+ rest_call = "http://#{mitm_rest_api}/proxyhistory"
501
+
502
+ sitemap = rest_browser.get(
503
+ rest_call,
504
+ content_type: 'application/json; charset=UTF8'
505
+ )
506
+
507
+ sitemap_arr = JSON.parse(sitemap, symbolize_names: true)
508
+
509
+ if keyword
510
+ sitemap_arr = sitemap_arr.select do |site|
511
+ decoded_request = Base64.strict_decode64(site[:request])
512
+ decoded_request.include?(keyword)
513
+ end
514
+ end
515
+
516
+ if return_as == :har
517
+ # Convert to HAR format
518
+ har_entries = sitemap_arr.map do |site|
519
+ decoded_request = Base64.strict_decode64(site[:request])
520
+
521
+ # Parse request head and body
522
+ if decoded_request.include?("\r\n\r\n")
523
+ request_head, request_body = decoded_request.split("\r\n\r\n", 2)
524
+ else
525
+ request_head = decoded_request
526
+ request_body = ''
527
+ end
528
+ request_lines = request_head.split("\r\n")
529
+ request_line = request_lines.shift
530
+ method, full_path, http_version = request_line.split(' ', 3)
531
+ headers = {}
532
+ request_lines.each do |line|
533
+ next if line.empty?
534
+
535
+ key, value = line.split(': ', 2)
536
+ headers[key] = value if key && value
537
+ end
538
+
539
+ host = headers['Host'] || raise('No Host header found in request')
540
+ scheme = 'http' # Hardcoded as protocol is not available; consider enhancing if available in site
541
+ url = "#{scheme}://#{host}#{full_path}"
542
+ uri = URI.parse(url)
543
+ query_string = uri.query ? URI.decode_www_form(uri.query).map { |k, v| { name: k, value: v.to_s } } : []
544
+
545
+ request_headers_size = request_head.bytesize + 4 # Account for \r\n\r\n
546
+ request_body_size = request_body.bytesize
547
+
548
+ request_obj = {
549
+ method: method,
550
+ url: uri.to_s,
551
+ httpVersion: http_version,
552
+ headers: headers.map { |k, v| { name: k, value: v } },
553
+ queryString: query_string,
554
+ headersSize: request_headers_size,
555
+ bodySize: request_body_size
556
+ }
557
+
558
+ if request_body_size.positive?
559
+ mime_type = headers['Content-Type'] || 'application/octet-stream'
560
+ post_data = {
561
+ mimeType: mime_type,
562
+ text: request_body
563
+ }
564
+ post_data[:params] = URI.decode_www_form(request_body).map { |k, v| { name: k, value: v.to_s } } if mime_type.include?('x-www-form-urlencoded')
565
+ request_obj[:postData] = post_data
566
+ end
567
+
568
+ if site[:response]
569
+ decoded_response = Base64.strict_decode64(site[:response])
570
+
571
+ # Parse response head and body
572
+ if decoded_response.include?("\r\n\r\n")
573
+ response_head, response_body = decoded_response.split("\r\n\r\n", 2)
574
+ else
575
+ response_head = decoded_response
576
+ response_body = ''
577
+ end
578
+ response_lines = response_head.split("\r\n")
579
+ status_line = response_lines.shift
580
+ version, status_str, status_text = status_line.split(' ', 3)
581
+ status = status_str.to_i
582
+ status_text ||= ''
583
+ response_headers = {}
584
+ response_lines.each do |line|
585
+ next if line.empty?
586
+
587
+ key, value = line.split(': ', 2)
588
+ response_headers[key] = value if key && value
589
+ end
590
+
591
+ response_headers_size = response_head.bytesize + 4 # Account for \r\n\r\n
592
+ response_body_size = response_body.bytesize
593
+ mime_type = response_headers['Content-Type'] || 'text/plain'
594
+
595
+ response_obj = {
596
+ status: status,
597
+ statusText: status_text,
598
+ httpVersion: version,
599
+ headers: response_headers.map { |k, v| { name: k, value: v } },
600
+ content: {
601
+ size: response_body_size,
602
+ mimeType: mime_type,
603
+ text: response_body
604
+ },
605
+ redirectURL: response_headers['Location'] || '',
606
+ headersSize: response_headers_size,
607
+ bodySize: response_body_size
608
+ }
609
+ else
610
+ response_obj = {
611
+ status: 0,
612
+ statusText: 'No response',
613
+ httpVersion: 'unknown',
614
+ headers: [],
615
+ content: {
616
+ size: 0,
617
+ mimeType: 'text/plain',
618
+ text: ''
619
+ },
620
+ redirectURL: '',
621
+ headersSize: -1,
622
+ bodySize: 0
623
+ }
624
+ end
625
+
626
+ {
627
+ startedDateTime: Time.now.iso8601,
628
+ time: 0,
629
+ request: request_obj,
630
+ response: response_obj,
631
+ cache: {},
632
+ timings: {
633
+ send: 0,
634
+ wait: 0,
635
+ receive: 0
636
+ },
637
+ pageref: 'page_1'
638
+ }
639
+ end
640
+
641
+ har_log = {
642
+ log: {
643
+ version: '1.2',
644
+ creator: {
645
+ name: 'BurpSuite via PWN::Plugins::BurpSuite',
646
+ version: '1.0'
647
+ },
648
+ pages: [{
649
+ startedDateTime: Time.now.iso8601,
650
+ id: 'page_1',
651
+ title: 'Sitemap Export',
652
+ pageTimings: {}
653
+ }],
654
+ entries: har_entries
655
+ }
656
+ }
657
+
658
+ sitemap_arr = har_log
659
+ end
660
+
661
+ sitemap_arr.uniq
662
+ rescue StandardError => e
663
+ stop(burp_obj: burp_obj) unless burp_obj.nil?
664
+ raise e
665
+ end
666
+
667
+ # Supported Method Parameters::
668
+ # repeater_obj = PWN::Plugins::BurpSuite.update_proxy_history(
669
+ # burp_obj: 'required - burp_obj returned by #start method',
670
+ # entry: 'required - hash of the proxy history entry to update'
671
+ # )
672
+
673
+ public_class_method def self.update_proxy_history(opts = {})
674
+ burp_obj = opts[:burp_obj]
675
+ raise 'ERROR: burp_obj parameter is required' unless burp_obj.is_a?(Hash)
676
+
677
+ entry = opts[:entry]
678
+ raise 'ERROR: entry parameter is required and must be a hash' unless entry.is_a?(Hash)
679
+
680
+ id = entry[:id]
681
+ raise 'ERROR: id key value pair is required within entry hash' if id.nil?
682
+
683
+ rest_browser = burp_obj[:rest_browser]
684
+ mitm_rest_api = burp_obj[:mitm_rest_api]
685
+
686
+ put_body = entry.to_json
687
+
688
+ proxy_history_resp = rest_browser.put(
689
+ "http://#{mitm_rest_api}/proxyhistory/#{id}",
690
+ put_body,
691
+ content_type: 'application/json; charset=UTF8'
692
+ )
693
+
694
+ JSON.parse(proxy_history_resp, symbolize_names: true)
695
+ rescue StandardError => e
696
+ raise e
697
+ end
698
+
377
699
  # Supported Method Parameters::
378
700
  # json_sitemap = PWN::Plugins::BurpSuite.get_sitemap(
379
701
  # burp_obj: 'required - burp_obj returned by #start method',
@@ -584,23 +906,55 @@ module PWN
584
906
  sitemap = opts[:sitemap] ||= {}
585
907
  debug = opts[:debug] || false
586
908
 
587
- decoded_sitemap = {
588
- request: Base64.strict_decode64(sitemap[:request]),
589
- http_service: {
590
- host: sitemap[:http_service][:host],
591
- port: sitemap[:http_service][:port],
592
- protocol: sitemap[:http_service][:protocol]
593
- }
594
- }
595
- system_role_content = 'Your sole purpose is to analyze each `protocol`, `host`, `port`, and `request` and generate an Exploit Prediction Scoring System (EPSS) score from 0%-100%. Just generate a score unless the score is >= 75% in which a PoC should also be generated to communicate the threat. You can always generate an score - provide the score at _the beggining of your analysis_. Be concise and to the point.'
909
+ request = Base64.strict_decode64(sitemap[:request])
910
+ response = Base64.strict_decode64(sitemap[:response])
911
+
912
+ http_request_response = PWN::Plugins::Char.force_utf8("#{request}\r\n\r\n#{response}")
913
+
914
+ system_role_content = '
915
+ Your expertise lies in dissecting HTTP request/response pairs to identify high-impact vulnerabilities, including but not limited to XSS (reflected, stored, DOM-based), CSRF, SSRF, IDOR, open redirects, CORS misconfigurations, authentication bypasses, SQLi/NoSQLi, command/code injection, business logic flaws, and API abuse. You prioritize zero-days and novel chains, always focusing on exploitability, impact (e.g., account takeover, data exfiltration, RCE), and reproducibility.
916
+
917
+ When analyzing HTTP request/response pairs:
918
+
919
+ 1. **Parse and Contextualize Traffic**:
920
+ - Break down every element: HTTP method, URI (path, query parameters), headers (e.g., Host, User-Agent, Cookies, Authorization, Referer, Origin, Content-Type), request body (e.g., form data, JSON payloads), response status code, response headers, and response body (HTML, JSON, XML, etc.).
921
+ - Identify dynamic elements: User-controlled inputs (e.g., query params, POST data, headers like X-Forwarded-For), server-side echoes, redirects, and client-side processing.
922
+ - Trace data flow: Map how inputs propagate from request to response, including any client-side JavaScript execution where exploitation may be possible in the client without communicating with the server (e.g. DOM-XSS).
923
+
924
+ 2. **Vulnerability Hunting Framework**:
925
+ - **Input Validation & Sanitization**: Check for unescaped/lack of encoding in outputs (e.g., HTML context for XSS, URL context for open redirects).
926
+ - **XSS Focus**: Hunt for sinks like innerHTML/outerHTML, document.write, eval, setTimeout/setInterval with strings, location.href/assign/replace, and history.pushState. Test payloads like <script>alert(1)</script>, javascript:alert(1), and polyglots. For DOM-based, simulate client-side execution.
927
+ - **JavaScript Library Analysis**: If JS is present (e.g., in response body or referenced scripts), deobfuscate and inspect:
928
+ - Objects/properties that could clobber DOM (e.g., window.name, document.cookie manipulation leading to prototype pollution).
929
+ - DOM XSS vectors: Analyze event handlers, querySelector, addEventListener with unsanitized data from location.hash/search, postMessage, or localStorage.
930
+ - Third-party libs (e.g., jQuery, React): Flag known sink patterns like .html(), dangerouslySetInnerHTML, or eval-like functions.
931
+ - **Server-Side Issues**: Probe for SSRF (e.g., via URL params fetching internal resources), IDOR (e.g., manipulating IDs in paths/bodies), rate limiting bypass, and insecure deserialization (e.g., in JSON/PHP objects).
932
+ - **Headers & Misc**: Examine for exposed sensitive info (e.g., debug headers, stack traces), misconfigured security headers (CSP, HSTS), and upload flaws (e.g., file extension bypass).
933
+ - **Chaining Opportunities**: Always consider multi-step exploits, like XSS leading to CSRF token theft or SSRF to internal metadata endpoints.
934
+
935
+ 3. **PoC Generation**:
936
+ - Produce concise, step-by-step PoCs in a standardized format:
937
+ - **Description**: Clear vuln summary, CVSS-like severity, and impact.
938
+ - **Steps to Reproduce**: Numbered HTTP requests (use curl or Burp syntax, e.g., `curl -X POST -d "param=<payload>" https://target.com/endpoint`).
939
+ - **Payloads**: Provide working, minimal payloads with variations for evasion (e.g., encoded, obfuscated).
940
+ - **Screenshots/Evidence**: Suggest what to capture (e.g., alert popup for XSS, response diff for IDOR).
941
+ - **Mitigation Advice**: Recommend fixes (e.g., output encoding, input validation).
942
+ - Ensure PoCs are ethical: Target only in-scope assets, avoid DoS, and emphasize disclosure via proper channels (e.g., HackerOne, Bugcrowd).
943
+ - If no vuln found, explain why and suggest further tests (e.g., fuzzing params).
944
+ 4. Risk Score:
945
+ For each analysis generate a risk score between 0% - 100% based on exploitability and impact. This should be reflected as { "risk_score": "nnn%" } in the final output JSON.
946
+
947
+ Analyze provided HTTP request/response pairs methodically: Start with a high-level overview, then dive into specifics, flag potential issues with evidence from the traffic, and end with PoC if applicable. Be verbose in reasoning but concise in output. Prioritize high-severity findings. If data is incomplete, request clarifications.
948
+ '
949
+
596
950
  ai_analysis = PWN::AI::Introspection.reflect_on(
597
951
  system_role_content: system_role_content,
598
- request: decoded_sitemap.to_json,
952
+ request: http_request_response,
599
953
  spinner: true
600
954
  )
601
955
  sitemap[:comment] = ai_analysis unless ai_analysis.nil?
602
956
  # Extract score and assign color highlight based on severity
603
- if ai_analysis =~ /(\d{1,3})%/
957
+ if ai_analysis =~ /"risk_score":\s*"(\d{1,3})%"/
604
958
  score = Regexp.last_match(1).to_i
605
959
  highlight_color = case score
606
960
  when 0..24
@@ -611,11 +965,10 @@ module PWN
611
965
  'ORANGE'
612
966
  when 75..100
613
967
  'RED'
614
- else
615
- 'NONE'
616
968
  end
617
- sitemap[:highlight] = highlight_color
618
969
  end
970
+ highlight_color ||= 'GRAY'
971
+ sitemap[:highlight] = highlight_color
619
972
 
620
973
  rest_client = rest_browser::Request
621
974
  response = rest_client.execute(
@@ -1476,8 +1829,10 @@ module PWN
1476
1829
  browser_obj = burp_obj[:mitm_browser]
1477
1830
  rest_browser = burp_obj[:rest_browser]
1478
1831
  mitm_rest_api = burp_obj[:mitm_rest_api]
1832
+ proxy_intruder_thread = burp_obj[:proxy_intruder_thread]
1479
1833
  # burp_pid = burp_obj[:pid]
1480
1834
 
1835
+ proxy_intruder_thread.kill unless proxy_intruder_thread.nil?
1481
1836
  PWN::Plugins::TransparentBrowser.close(browser_obj: browser_obj)
1482
1837
  rest_browser.post("http://#{mitm_rest_api}/shutdown", '')
1483
1838
  # Process.kill('TERM', burp_pid)
@@ -1552,6 +1907,12 @@ module PWN
1552
1907
  id: 'optional - ID of the proxy listener (defaults to 0)'
1553
1908
  )
1554
1909
 
1910
+ json_proxy_history = #{self}.get_proxy_history(
1911
+ burp_obj: 'required - burp_obj returned by #start method',
1912
+ keyword: 'optional - keyword to filter proxy history results (default: nil)',
1913
+ return_as: 'optional - :base64 or :har (defaults to :base64)'
1914
+ )
1915
+
1555
1916
  json_sitemap = #{self}.get_sitemap(
1556
1917
  burp_obj: 'required - burp_obj returned by #start method',
1557
1918
  keyword: 'optional - keyword to filter sitemap results (default: nil)',
@@ -7,6 +7,23 @@ module PWN
7
7
  module Plugins
8
8
  # This plugin was created to generate various characters for fuzzing
9
9
  module Char
10
+ # Supported Method Parameters::
11
+ # PWN::Plugins::Char.force_utf8(
12
+ # obj: 'required - object to force to UTF-8'
13
+ # )
14
+ public_class_method def self.force_utf8(obj)
15
+ case obj
16
+ when String
17
+ obj.force_encoding('ISO-8859-1').encode('UTF-8', invalid: :replace, undef: :replace)
18
+ when Array
19
+ obj.map { |item| force_utf8(item) }
20
+ when Hash
21
+ obj.transform_values { |value| force_utf8(value) }
22
+ else
23
+ obj
24
+ end
25
+ end
26
+
10
27
  # Supported Method Parameters::
11
28
  # PWN::Plugins::Char.generate_by_range(
12
29
  # from: 'required - integer to start from',
@@ -1202,7 +1202,8 @@ module PWN
1202
1202
  callbacks_to_delete = devtools.callbacks.keys.reject { |k| k == 'Target.attachedToTarget' }
1203
1203
  Timeout.timeout(30) { browser_obj[:browser].refresh }
1204
1204
  until devtools.callbacks.keys.include?(method) && breakpoint_arr.any? { |bp| bp['caught'] == true }
1205
- callbacks_to_delete.each { |method| devtools.callbacks.delete(method) }
1205
+ devtools.callbacks.delete(method)
1206
+ devtools.debugger.resume
1206
1207
  devtools.debugger.on(:paused) do |params|
1207
1208
  breakpoint_id_caught = params['callFrames'].first['location']['scriptId']
1208
1209
  breakpoint_arr.each_with_index do |bp, idx|
@@ -1213,8 +1214,11 @@ module PWN
1213
1214
  debugger_state[:breakpoints] = breakpoint_arr
1214
1215
  devtools.instance_variable_set(:@debugger_state, debugger_state)
1215
1216
  end
1216
- puts "TARGET BREAKPOINTS: #{breakpoint_arr.inspect}"
1217
- puts "PARAMS Observerd: #{params.inspect}"
1217
+ # puts "TARGET BREAKPOINTS: #{breakpoint_arr.inspect}"
1218
+ # puts "PARAMS Observerd: #{params.inspect}"
1219
+ debugger_state = devtools.instance_variable_get(:@debugger_state)
1220
+ puts devtools.callbacks.inspect
1221
+ puts debugger_state.inspect
1218
1222
  end
1219
1223
  devtools.debugger.pause
1220
1224
  # browser_obj[:browser].refresh
@@ -1413,7 +1417,8 @@ module PWN
1413
1417
 
1414
1418
  ai_analysis = PWN::AI::Introspection.reflect_on(
1415
1419
  system_role_content: system_role_content,
1416
- request: current_step
1420
+ request: current_step,
1421
+ suppress_pii_output: true
1417
1422
  )
1418
1423
  puts "^^^ #{ai_analysis}" unless ai_analysis.nil?
1419
1424
  end
@@ -129,7 +129,7 @@ module PWN
129
129
 
130
130
  zaproxy_cmd = "#{zaproxy_cmd} -host #{zap_ip} -port #{zap_port}"
131
131
 
132
- zap_obj[:pid] = Process.spawn(zaproxy_cmd)
132
+ zap_obj[:pid] = Process.spawn(zaproxy_cmd, pgroup: true)
133
133
  # Wait for pwn_burp_port to open prior to returning burp_obj
134
134
  loop do
135
135
  s = TCPSocket.new(zap_rest_ip, zap_rest_port)
@@ -82,7 +82,13 @@ module PWN
82
82
  line_no: line_no,
83
83
  source_code_snippet: contents
84
84
  }.to_json
85
- ai_analysis = PWN::AI::Introspection.reflect_on(request: request)
85
+
86
+ system_role_content = 'Your sole purpose is to analyze source code snippets and generate an Exploit Prediction Scoring System (EPSS) score between 0% - 100%. Just generate a score unless score is >= 75% in which a PoC and code fix should also be included.'
87
+ ai_analysis = PWN::AI::Introspection.reflect_on(
88
+ system_role_content: system_role_content,
89
+ request: request,
90
+ suppress_pii_warning: true
91
+ )
86
92
  ai_analysis ||= 'N/A'
87
93
 
88
94
  hash_line[:line_no_and_contents] = line_no_and_contents_arr.push(
@@ -124,7 +124,13 @@ module PWN
124
124
  line_no: line_no,
125
125
  source_code_snippet: contents
126
126
  }.to_json
127
- ai_analysis = PWN::AI::Introspection.reflect_on(request: request)
127
+
128
+ system_role_content = 'Your sole purpose is to analyze source code snippets and generate an Exploit Prediction Scoring System (EPSS) score between 0% - 100%. Just generate a score unless score is >= 75% in which a PoC and code fix should also be included.'
129
+ ai_analysis = PWN::AI::Introspection.reflect_on(
130
+ system_role_content: system_role_content,
131
+ request: request,
132
+ suppress_pii_warning: true
133
+ )
128
134
  ai_analysis ||= 'N/A'
129
135
 
130
136
  hash_line[:line_no_and_contents] = line_no_and_contents_arr.push(
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.496'
4
+ VERSION = '0.5.497'
5
5
  end
@@ -139,7 +139,8 @@ module PWN
139
139
  ai_analysis = PWN::AI::Introspection.reflect_on(
140
140
  request: programs_arr.to_json,
141
141
  system_role_content: system_role_content,
142
- spinner: true
142
+ spinner: true,
143
+ suppress_pii_warning: true
143
144
  )
144
145
  puts "\n\n#{ai_analysis}" unless ai_analysis.nil?
145
146
 
@@ -284,7 +285,8 @@ module PWN
284
285
  ai_analysis = PWN::AI::Introspection.reflect_on(
285
286
  request: json_resp.to_json,
286
287
  system_role_content: system_role_content,
287
- spinner: true
288
+ spinner: true,
289
+ suppress_pii_warning: true
288
290
  )
289
291
  puts "\n\n#{ai_analysis}" unless ai_analysis.nil?
290
292
 
@@ -432,7 +434,8 @@ module PWN
432
434
  ai_analysis = PWN::AI::Introspection.reflect_on(
433
435
  request: json_resp.to_json,
434
436
  system_role_content: system_role_content,
435
- spinner: true
437
+ spinner: true,
438
+ suppress_pii_warning: true
436
439
  )
437
440
  puts "\n\n#{ai_analysis}" unless ai_analysis.nil?
438
441
 
@@ -7,7 +7,7 @@
7
7
  {"messages":[{"role":"user","content":"PWN::AI::Grok.help Usage"},{"role":"assistant","content":"`PWN::AI::Grok.help`: "}]}
8
8
  {"messages":[{"role":"user","content":"PWN::AI::Introspection.authors Usage"},{"role":"assistant","content":"`PWN::AI::Introspection.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
9
9
  {"messages":[{"role":"user","content":"PWN::AI::Introspection.help Usage"},{"role":"assistant","content":"`PWN::AI::Introspection.help`: "}]}
10
- {"messages":[{"role":"user","content":"PWN::AI::Introspection.reflect_on Usage"},{"role":"assistant","content":"`PWN::AI::Introspection.reflect_on`: Supported Method Parameters\n\nresponse = PWN::AI::Introspection.reflect_on(\n\nrequest: 'required - String - What you want the AI to reflect on',\nsystem_role_content: 'optional - context to set up the model behavior for reflection'\n\n)\n"}]}
10
+ {"messages":[{"role":"user","content":"PWN::AI::Introspection.reflect_on Usage"},{"role":"assistant","content":"`PWN::AI::Introspection.reflect_on`: Supported Method Parameters\n\nresponse = PWN::AI::Introspection.reflect_on(\n\nrequest: 'required - String - What you want the AI to reflect on',\nsystem_role_content: 'optional - context to set up the model behavior for reflection',\nspinner: 'optional - Boolean - Display spinner during operation (default: false)'\n\n)\n"}]}
11
11
  {"messages":[{"role":"user","content":"PWN::AI::Ollama.authors Usage"},{"role":"assistant","content":"`PWN::AI::Ollama.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
12
12
  {"messages":[{"role":"user","content":"PWN::AI::Ollama.chat Usage"},{"role":"assistant","content":"`PWN::AI::Ollama.chat`: Supported Method Parameters\n\nresponse = PWN::AI::Ollama.chat(\n\nrequest: 'required - message to ChatGPT'\nmodel: 'optional - model to use for text generation (defaults to PWN::Env[:ai][:ollama][:model])',\ntemp: 'optional - creative response float (deafults to PWN::Env[:ai][:ollama][:temp])',\nsystem_role_content: 'optional - context to set up the model behavior for conversation (Default: PWN::Env[:ai][:ollama][:system_role_content])',\nresponse_history: 'optional - pass response back in to have a conversation',\nspeak_answer: 'optional speak answer using PWN::Plugins::Voice.text_to_speech (Default: nil)',\ntimeout: 'optional timeout in seconds (defaults to 300)',\nspinner: 'optional - display spinner (defaults to false)'\n\n)\n"}]}
13
13
  {"messages":[{"role":"user","content":"PWN::AI::Ollama.get_models Usage"},{"role":"assistant","content":"`PWN::AI::Ollama.get_models`: Supported Method Parameters\n\nresponse = PWN::AI::Ollama.get_models\n"}]}
@@ -550,12 +550,12 @@
550
550
  {"messages":[{"role":"user","content":"PWN::Plugins::BlackDuckBinaryAnalysis.help Usage"},{"role":"assistant","content":"`PWN::Plugins::BlackDuckBinaryAnalysis.help`: "}]}
551
551
  {"messages":[{"role":"user","content":"PWN::Plugins::BlackDuckBinaryAnalysis.upload_file Usage"},{"role":"assistant","content":"`PWN::Plugins::BlackDuckBinaryAnalysis.upload_file`: Supported Method Parameters\n\nresponse = PWN::Plugins::BlackDuckBinaryAnalysis.upload_file(\n\ntoken: 'required - Bearer token',\nfile: 'required - path of file to upload',\ngroup_id: 'optional - group id',\ndelete_binary: 'optional - delete binary after upload (defaults to false)',\nforce_scan: 'optional - force scan (defaults to false)',\ncallback_url: 'optional - callback url',\nscan_infoleak: 'optional - scan infoleak (defaults to true)',\ncode_analysis: 'optional - code analysis (defaults to true)',\nscan_code_familiarity: 'optional - scan code familiarity (defaults to false)',\nversion: 'optional - version',\nproduct_id: 'optional - product id'\n\n)\n"}]}
552
552
  {"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.active_scan Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.active_scan`: Supported Method Parameters\n\nactive_scan_url_arr = PWN::Plugins::BurpSuite.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[:mitm_browser])',\nexclude_paths: 'optional - array of paths to exclude from active scan (default: [])'\n\n)\n"}]}
553
- {"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.add_proxy_listener Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.add_proxy_listener`: Supported Method Parameters\n\njson_proxy_listener = PWN::Plugins::BurpSuite.add_proxy_listener(\n\nburp_obj: 'required - burp_obj returned by #start method',\nbind_address: 'required - bind address for the proxy listener (e.g., \"127.0.0.1\")',\nport: 'required - port for the proxy listener (e.g., 8081)',\nenabled: 'optional - enable the listener (defaults to true)'\n\n)\n"}]}
553
+ {"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.add_proxy_listener Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.add_proxy_listener`: Supported Method Parameters\n\njson_proxy_listener = PWN::Plugins::BurpSuite.add_proxy_listener(\n\nburp_obj: 'required - burp_obj returned by #start method',\nbindAddress: 'required - bind address for the proxy listener (e.g., \"127.0.0.1\")',\nport: 'required - port for the proxy listener (e.g., 8081)',\nenabled: 'optional - enable the listener (defaults to true)'\n\n)\n"}]}
554
554
  {"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.add_repeater_tab Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.add_repeater_tab`: Supported Method Parameters\n\nrepeater_id = PWN::Plugins::BurpSuite.add_repeater_tab(\n\nburp_obj: 'required - burp_obj returned by #start method',\nname: 'required - name of the repeater tab (max 30 characters)',\nrequest: 'optional - base64 encoded HTTP request string'\n\n)\n"}]}
555
555
  {"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.add_to_scope Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.add_to_scope`: Supported Method Parameters\n\njson_in_scope = PWN::Plugins::BurpSuite.add_to_scope(\n\nburp_obj: 'required - burp_obj returned by #start method',\ntarget_url: 'required - target url to add to scope'\n\n)\n"}]}
556
556
  {"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.add_to_sitemap Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.add_to_sitemap`: "}]}
557
557
  {"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.authors Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
558
- {"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.delete_proxy_listener Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.delete_proxy_listener`: Supported Method Parameters\n\nPWN::Plugins::BurpSuite.delete_proxy_listener(\n\nburp_obj: 'required - burp_obj returned by #start method',\nid: 'required - ID of the proxy listener (defaults to \"0\")'\n\n)\n"}]}
558
+ {"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.delete_proxy_listener Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.delete_proxy_listener`: Supported Method Parameters\n\nPWN::Plugins::BurpSuite.delete_proxy_listener(\n\nburp_obj: 'required - burp_obj returned by #start method',\nid: 'optional - ID of the proxy listener (defaults to 0)'\n\n)\n"}]}
559
559
  {"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.delete_repeater_tab Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.delete_repeater_tab`: Supported Method Parameters\n\nuri_in_scope = PWN::Plugins::BurpSuite.delete_repeater_tab(\n\nburp_obj: 'required - burp_obj returned by #start method',\nid: 'required - id of the repeater tab to delete'\n\n)\n"}]}
560
560
  {"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.disable_proxy Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.disable_proxy`: Supported Method Parameters\n\nPWN::Plugins::BurpSuite.disable_proxy(\n\nburp_obj: 'required - burp_obj returned by #start method'\n\n)\n"}]}
561
561
  {"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.enable_proxy Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.enable_proxy`: Supported Method Parameters\n\nPWN::Plugins::BurpSuite.enable_proxy(\n\nburp_obj: 'required - burp_obj returned by #start method'\n\n)\n"}]}
@@ -574,7 +574,7 @@
574
574
  {"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.start Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.start`: Supported Method Parameters\n\nburp_obj1 = PWN::Plugins::BurpSuite.start(\n\nburp_jar_path: 'optional - 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',\nburp_ip: 'optional - IP address for the Burp proxy (defaults to 127.0.0.1)',\nburp_port: 'optional - port for the Burp proxy (defaults to a random unused port)',\npwn_burp_ip: 'optional - IP address for the PWN Burp API (defaults to 127.0.0.1)',\npwn_burp_port: 'optional - port for the PWN Burp API (defaults to a random unused port)'\n\n)\n"}]}
575
575
  {"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"}]}
576
576
  {"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"}]}
577
- {"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.update_proxy_listener Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.update_proxy_listener`: Supported Method Parameters\n\njson_proxy_listener = PWN::Plugins::BurpSuite.update_proxy_listener(\n\nburp_obj: 'required - burp_obj returned by #start method',\nid: 'optional - ID of the proxy listener (defaults to \"0\")',\nbind_address: 'optional - bind address for the proxy listener (defaults to \"127.0.0.1\")',\nport: 'optional - port for the proxy listener (defaults to 8080)',\nenabled: 'optional - enable or disable the listener (defaults to true)'\n\n)\n"}]}
577
+ {"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.update_proxy_listener Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.update_proxy_listener`: Supported Method Parameters\n\njson_proxy_listener = PWN::Plugins::BurpSuite.update_proxy_listener(\n\nburp_obj: 'required - burp_obj returned by #start method',\nid: 'optional - ID of the proxy listener (defaults to 0)',\nbindAddress: 'optional - bind address for the proxy listener (defaults to value of existing listener)',\nport: 'optional - port for the proxy listener (defaults to value of existing listener)',\nenabled: 'optional - enable or disable the listener (defaults to value of existing listener)'\n\n)\n"}]}
578
578
  {"messages":[{"role":"user","content":"PWN::Plugins::BurpSuite.update_repeater_tab Usage"},{"role":"assistant","content":"`PWN::Plugins::BurpSuite.update_repeater_tab`: Supported Method Parameters\n\nrepeater_obj = PWN::Plugins::BurpSuite.update_repeater_tab(\n\nburp_obj: 'required - burp_obj returned by #start method',\nid: 'required - id of the repeater tab to update',\nname: 'required - name of the repeater tab (max 30 characters)',\nrequest: 'required - base64 encoded HTTP request string'\n\n)\n"}]}
579
579
  {"messages":[{"role":"user","content":"PWN::Plugins::BusPirate.authors Usage"},{"role":"assistant","content":"`PWN::Plugins::BusPirate.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
580
580
  {"messages":[{"role":"user","content":"PWN::Plugins::BusPirate.connect Usage"},{"role":"assistant","content":"`PWN::Plugins::BusPirate.connect`: Supported Method Parameters\n\nbus_pirate_obj = PWN::Plugins::BusPirate.connect(\n\nblock_dev: 'optional serial block device path (defaults to /dev/ttyUSB0)',\nbaud: 'optional (defaults to 9600)',\ndata_bits: 'optional (defaults to 8)',\nstop_bits: 'optional (defaults to 1)',\nparity: 'optional (defaults to SerialPort::NONE)',\nflow_control: 'optional (defaults to SerialPort::HARD) SerialPort::NONE|SerialPort::SOFT|SerialPort::HARD'\n\n)\n"}]}
@@ -1001,6 +1001,7 @@
1001
1001
  {"messages":[{"role":"user","content":"PWN::Plugins::Tor.switch_exit_node Usage"},{"role":"assistant","content":"`PWN::Plugins::Tor.switch_exit_node`: Supported Method Parameters\n\nPWN::Plugins::Tor.switch_exit_node(\n\ntor_obj: 'required - tor_obj returned from #start method',\nresponse_timeout: 'optional - float in seconds to timeout (default: 3.0)'\n\n)\n"}]}
1002
1002
  {"messages":[{"role":"user","content":"PWN::Plugins::Tor.tor_control_cmd Usage"},{"role":"assistant","content":"`PWN::Plugins::Tor.tor_control_cmd`: Supported Method Parameters\n\ntor_ctrl_cmd(\n\ntor_obj: 'required - tor_obj returned from #start method'\ncmd: 'required - Tor control command to execute',\nresponse_timeout: 'optional - float in seconds to timeout (default: 3.0)'\n\n)\n"}]}
1003
1003
  {"messages":[{"role":"user","content":"PWN::Plugins::TransparentBrowser.authors Usage"},{"role":"assistant","content":"`PWN::Plugins::TransparentBrowser.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
1004
+ {"messages":[{"role":"user","content":"PWN::Plugins::TransparentBrowser.breakpoint_locations Usage"},{"role":"assistant","content":"`PWN::Plugins::TransparentBrowser.breakpoint_locations`: Supported Method Parameters\n\npage_state_arr = PWN::Plugins::TransparentBrowser.breakpoint_locations(\n\nbrowser_obj: 'required - browser_obj returned from #open method)'\n\n)\n"}]}
1004
1005
  {"messages":[{"role":"user","content":"PWN::Plugins::TransparentBrowser.close Usage"},{"role":"assistant","content":"`PWN::Plugins::TransparentBrowser.close`: Supported Method Parameters\n\nbrowser_obj1 = PWN::Plugins::TransparentBrowser.close(\n\nbrowser_obj: 'required - browser_obj returned from #open method)'\n\n)\n"}]}
1005
1006
  {"messages":[{"role":"user","content":"PWN::Plugins::TransparentBrowser.close_tab Usage"},{"role":"assistant","content":"`PWN::Plugins::TransparentBrowser.close_tab`: Supported Method Parameters\n\ntab = PWN::Plugins::TransparentBrowser.close_tab(\n\nbrowser_obj: 'required - browser_obj returned from #open method)',\nindex: 'optional - index of tab to close (defaults to closing active tab)',\nkeyword: 'optional - keyword in title or url used to close tabs (defaults to closing active tab)'\n\n)\n"}]}
1006
1007
  {"messages":[{"role":"user","content":"PWN::Plugins::TransparentBrowser.console Usage"},{"role":"assistant","content":"`PWN::Plugins::TransparentBrowser.console`: Supported Method Parameters\n\nconsole_resp = PWN::Plugins::TransparentBrowser.console(\n\nbrowser_obj: browser_obj1,\njs: 'required - JavaScript expression to evaluate',\nreturn_to: 'optional - return to :console or :stdout (defaults to :console)'\n\n)\n"}]}
@@ -1010,6 +1011,7 @@
1010
1011
  {"messages":[{"role":"user","content":"PWN::Plugins::TransparentBrowser.dump_links Usage"},{"role":"assistant","content":"`PWN::Plugins::TransparentBrowser.dump_links`: Supported Method Parameters\n\nbrowser_obj = PWN::Plugins::TransparentBrowser.dump_links(\n\nbrowser_obj: browser_obj1\n\n)\n"}]}
1011
1012
  {"messages":[{"role":"user","content":"PWN::Plugins::TransparentBrowser.find_elements_by_text Usage"},{"role":"assistant","content":"`PWN::Plugins::TransparentBrowser.find_elements_by_text`: Supported Method Parameters\n\nbrowser_obj = PWN::Plugins::TransparentBrowser.find_elements_by_text(\n\nbrowser_obj: browser_obj1,\ntext: 'required - text to search for in the DOM'\n\n)\n"}]}
1012
1013
  {"messages":[{"role":"user","content":"PWN::Plugins::TransparentBrowser.get_page_state Usage"},{"role":"assistant","content":"`PWN::Plugins::TransparentBrowser.get_page_state`: Supported Method Parameters\n\npage_state = PWN::Plugins::TransparentBrowser.get_page_state(\n\nbrowser_obj: 'required - browser_obj returned from #open method)'\n\n)\n"}]}
1014
+ {"messages":[{"role":"user","content":"PWN::Plugins::TransparentBrowser.get_targets Usage"},{"role":"assistant","content":"`PWN::Plugins::TransparentBrowser.get_targets`: Supported Method Parameters\n\npage_state_arr = PWN::Plugins::TransparentBrowser.get_targets(\n\nbrowser_obj: 'required - browser_obj returned from #open method)'\n\n)\n"}]}
1013
1015
  {"messages":[{"role":"user","content":"PWN::Plugins::TransparentBrowser.help Usage"},{"role":"assistant","content":"`PWN::Plugins::TransparentBrowser.help`: "}]}
1014
1016
  {"messages":[{"role":"user","content":"PWN::Plugins::TransparentBrowser.hide_dom_mutations Usage"},{"role":"assistant","content":"`PWN::Plugins::TransparentBrowser.hide_dom_mutations`: Supported Method Parameters\n\nconsole_resp = PWN::Plugins::TransparentBrowser.hide_dom_mutations(\n\nbrowser_obj: browser_obj1,\nindex: 'optional - index of tab to switch to (defaults to active tab)'\n\n)\n"}]}
1015
1017
  {"messages":[{"role":"user","content":"PWN::Plugins::TransparentBrowser.jmp_devtools_panel Usage"},{"role":"assistant","content":"`PWN::Plugins::TransparentBrowser.jmp_devtools_panel`: Supported Method Parameters\n\nPWN::Plugins::TransparentBrowser.jmp_devtools_panel(\n\nbrowser_obj: 'required - browser_obj returned from #open method)',\npanel: 'optional - panel to switch to :elements|:inspector|:console|:debugger|:sources|:network\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.496
4
+ version: 0.5.497
5
5
  platform: ruby
6
6
  authors:
7
7
  - 0day Inc.
@@ -1149,14 +1149,14 @@ dependencies:
1149
1149
  requirements:
1150
1150
  - - '='
1151
1151
  - !ruby/object:Gem::Version
1152
- version: 2.7.4
1152
+ version: 2.8.0
1153
1153
  type: :runtime
1154
1154
  prerelease: false
1155
1155
  version_requirements: !ruby/object:Gem::Requirement
1156
1156
  requirements:
1157
1157
  - - '='
1158
1158
  - !ruby/object:Gem::Version
1159
- version: 2.7.4
1159
+ version: 2.8.0
1160
1160
  - !ruby/object:Gem::Dependency
1161
1161
  name: thin
1162
1162
  requirement: !ruby/object:Gem::Requirement