pwn 0.5.504 → 0.5.506
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/README.md +3 -3
- data/lib/pwn/plugins/burp_suite.rb +129 -115
- data/lib/pwn/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ff5a5cd8f4d9e0ce9d23468de01cb6c0f685ed4c9541e08af39dcb05b8c50d67
|
|
4
|
+
data.tar.gz: e9afe048562d6d832972c9990a24db2b78a6d5c76e95959079ac4412e959c152
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 30d268063617d51deeed10b035ed8566913eebf114247ea8f4d988347a447faff622105e032f103ece1a56a69145e8ade0a79a6c9b0ec183f075065ca9d25818
|
|
7
|
+
data.tar.gz: 1c8deccd120888637f7a257cd3304374caac61bb9276a6f48b7c20a68e00087a7ec952a2c823745e62aa87c720c478b99f69e367ad95151365d06f644cfd49a0
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
|
@@ -37,7 +37,7 @@ $ cd /opt/pwn
|
|
|
37
37
|
$ ./install.sh
|
|
38
38
|
$ ./install.sh ruby-gem
|
|
39
39
|
$ pwn
|
|
40
|
-
pwn[v0.5.
|
|
40
|
+
pwn[v0.5.506]:001 >>> PWN.help
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
[](https://youtu.be/G7iLUY4FzsI)
|
|
@@ -52,7 +52,7 @@ $ rvm use ruby-3.4.4@pwn
|
|
|
52
52
|
$ gem uninstall --all --executables pwn
|
|
53
53
|
$ gem install --verbose pwn
|
|
54
54
|
$ pwn
|
|
55
|
-
pwn[v0.5.
|
|
55
|
+
pwn[v0.5.506]:001 >>> PWN.help
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
If you're using a multi-user install of RVM do:
|
|
@@ -62,7 +62,7 @@ $ rvm use ruby-3.4.4@pwn
|
|
|
62
62
|
$ rvmsudo gem uninstall --all --executables pwn
|
|
63
63
|
$ rvmsudo gem install --verbose pwn
|
|
64
64
|
$ pwn
|
|
65
|
-
pwn[v0.5.
|
|
65
|
+
pwn[v0.5.506]: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:
|
|
@@ -46,7 +46,7 @@ module PWN
|
|
|
46
46
|
# Supported Method Parameters::
|
|
47
47
|
# burp_obj = PWN::Plugins::BurpSuite.init_introspection_thread(
|
|
48
48
|
# burp_obj: 'required - burp_obj returned by #start method',
|
|
49
|
-
#
|
|
49
|
+
# type: 'required - type of history to introspect (:sitemap, :proxy_history, :websocket_history)'
|
|
50
50
|
# )
|
|
51
51
|
private_class_method def self.init_introspection_thread(opts = {})
|
|
52
52
|
# if PWN::Env[:ai][:introspection] is true,
|
|
@@ -60,7 +60,12 @@ module PWN
|
|
|
60
60
|
burp_obj = opts[:burp_obj]
|
|
61
61
|
raise 'ERROR: burp_obj parameter is required' unless burp_obj.is_a?(Hash)
|
|
62
62
|
|
|
63
|
+
valid_types = %i[proxy_history sitemap websocket_history]
|
|
64
|
+
type = opts[:type]
|
|
65
|
+
raise "ERROR: type parameter is required and must be one of: #{valid_types.join(', ')}" unless valid_types.include?(type)
|
|
66
|
+
|
|
63
67
|
if PWN::Env[:ai][:introspection]
|
|
68
|
+
introspection_thread_arr = burp_obj[:introspection_threads] ||= []
|
|
64
69
|
introspection_thread = Thread.new do
|
|
65
70
|
system_role_content = '
|
|
66
71
|
Your expertise lies in dissecting HTTP request/response pairs and WebSocket messages 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, race conditions, and API abuse. You prioritize zero-days and novel chains, always focusing on exploitability, impact (e.g., account takeover, data exfiltration, RCE), and reproducibility.
|
|
@@ -119,95 +124,130 @@ module PWN
|
|
|
119
124
|
highlight_color
|
|
120
125
|
end
|
|
121
126
|
|
|
122
|
-
proxy_history = []
|
|
123
127
|
loop do
|
|
124
|
-
# TODO: Implement
|
|
125
|
-
# Sitemap should work the same as proxy history.
|
|
128
|
+
# TODO: Implement repeater into the loop? This reduces load to LLM but is slooow.
|
|
126
129
|
# Repeater should analyze the reqesut/response pair and suggest
|
|
127
|
-
# modifications to the request to further probe for vulnerabilities.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
130
|
+
# modifications to the request to further probe for vulnerabilities _quickly_.
|
|
131
|
+
case type
|
|
132
|
+
when :proxy_history
|
|
133
|
+
sitemap = get_sitemap(burp_obj: burp_obj)
|
|
134
|
+
proxy_history = get_proxy_history(burp_obj: burp_obj)
|
|
135
|
+
proxy_history.each do |entry|
|
|
136
|
+
next unless entry.key?(:comment) && entry[:comment].to_s.strip.empty?
|
|
137
|
+
|
|
138
|
+
request = entry[:request]
|
|
139
|
+
response = entry[:response]
|
|
140
|
+
host = entry[:http_service][:host]
|
|
141
|
+
port = entry[:http_service][:port]
|
|
142
|
+
protocol = entry[:http_service][:protocol]
|
|
143
|
+
next if request.nil? || response.nil? || host.nil? || port.nil? || protocol.nil?
|
|
144
|
+
|
|
145
|
+
# If sitemap comment and highlight color exists, use that instead of re-analyzing
|
|
146
|
+
sitemap_entry = nil
|
|
147
|
+
if sitemap.any?
|
|
148
|
+
sitemap_entry = sitemap.find do |site|
|
|
149
|
+
next unless site.key?(:http_service) && site.key?(:request)
|
|
150
|
+
|
|
151
|
+
site[:http_service][:host] == host &&
|
|
152
|
+
site[:http_service][:port] == port &&
|
|
153
|
+
site[:http_service][:protocol] == protocol &&
|
|
154
|
+
site[:request] == entry[:request]
|
|
155
|
+
end
|
|
148
156
|
end
|
|
149
|
-
end
|
|
150
157
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
http_request_response = PWN::Plugins::Char.force_utf8("#{request}\r\n\r\n#{response}")
|
|
158
|
-
ai_analysis = PWN::AI::Introspection.reflect_on(
|
|
159
|
-
system_role_content: system_role_content,
|
|
160
|
-
request: http_request_response,
|
|
161
|
-
suppress_pii_warning: true
|
|
162
|
-
)
|
|
158
|
+
if sitemap_entry.is_a?(Hash) && sitemap_entry[:comment].length.positive?
|
|
159
|
+
entry[:comment] = sitemap_entry[:comment]
|
|
160
|
+
entry[:highlight] = sitemap_entry[:highlight]
|
|
161
|
+
else
|
|
162
|
+
request = Base64.strict_decode64(request)
|
|
163
|
+
response = Base64.strict_decode64(response)
|
|
163
164
|
|
|
164
|
-
|
|
165
|
+
http_request_response = PWN::Plugins::Char.force_utf8("#{request}\r\n\r\n#{response}")
|
|
166
|
+
ai_analysis = PWN::AI::Introspection.reflect_on(
|
|
167
|
+
system_role_content: system_role_content,
|
|
168
|
+
request: http_request_response,
|
|
169
|
+
suppress_pii_warning: true
|
|
170
|
+
)
|
|
165
171
|
|
|
166
|
-
|
|
167
|
-
entry[:highlight] = get_highlight_color.call(ai_analysis: ai_analysis)
|
|
168
|
-
end
|
|
172
|
+
next if ai_analysis.nil? || ai_analysis.strip.empty?
|
|
169
173
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
174
|
+
entry[:comment] = ai_analysis
|
|
175
|
+
entry[:highlight] = get_highlight_color.call(ai_analysis: ai_analysis)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
update_proxy_history(
|
|
179
|
+
burp_obj: burp_obj,
|
|
180
|
+
entry: entry
|
|
181
|
+
)
|
|
182
|
+
end
|
|
183
|
+
sleep Random.rand(30..60)
|
|
184
|
+
|
|
185
|
+
when :sitemap
|
|
186
|
+
proxy_history = get_proxy_history(burp_obj: burp_obj)
|
|
187
|
+
sitemap = get_sitemap(burp_obj: burp_obj)
|
|
188
|
+
sitemap.each do |entry|
|
|
189
|
+
next unless entry.key?(:comment) && entry[:comment].to_s.strip.empty?
|
|
190
|
+
|
|
191
|
+
request = entry[:request]
|
|
192
|
+
response = entry[:response]
|
|
193
|
+
host = entry[:http_service][:host]
|
|
194
|
+
port = entry[:http_service][:port]
|
|
195
|
+
protocol = entry[:http_service][:protocol]
|
|
196
|
+
next if request.nil? || response.nil? || host.nil? || port.nil? || protocol.nil?
|
|
197
|
+
|
|
198
|
+
proxy_history_entry = nil
|
|
199
|
+
if proxy_history.any?
|
|
200
|
+
proxy_history_entry = proxy_history.find do |proxy_entry|
|
|
201
|
+
next unless proxy_entry.key?(:http_service) && proxy_entry.key?(:request)
|
|
202
|
+
|
|
203
|
+
proxy_entry[:http_service][:host] == host &&
|
|
204
|
+
proxy_entry[:http_service][:port] == port &&
|
|
205
|
+
proxy_entry[:http_service][:protocol] == protocol &&
|
|
206
|
+
proxy_entry[:request] == entry[:request]
|
|
207
|
+
end
|
|
208
|
+
end
|
|
175
209
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
site[:http_service][:host] == host &&
|
|
194
|
-
site[:http_service][:port] == port &&
|
|
195
|
-
site[:http_service][:protocol] == protocol &&
|
|
196
|
-
site[:request] == entry[:request]
|
|
210
|
+
if proxy_history_entry.is_a?(Hash) && proxy_history_entry[:comment].length.positive?
|
|
211
|
+
entry[:comment] = proxy_history_entry[:comment]
|
|
212
|
+
entry[:highlight] = proxy_history_entry[:highlight]
|
|
213
|
+
else
|
|
214
|
+
request = Base64.strict_decode64(request)
|
|
215
|
+
response = Base64.strict_decode64(response)
|
|
216
|
+
http_request_response = PWN::Plugins::Char.force_utf8("#{request}\r\n\r\n#{response}")
|
|
217
|
+
ai_analysis = PWN::AI::Introspection.reflect_on(
|
|
218
|
+
system_role_content: system_role_content,
|
|
219
|
+
request: http_request_response,
|
|
220
|
+
suppress_pii_warning: true
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
next if ai_analysis.nil? || ai_analysis.strip.empty?
|
|
224
|
+
|
|
225
|
+
entry[:comment] = ai_analysis
|
|
226
|
+
entry[:highlight] = get_highlight_color.call(ai_analysis: ai_analysis)
|
|
197
227
|
end
|
|
228
|
+
|
|
229
|
+
update_sitemap(
|
|
230
|
+
burp_obj: burp_obj,
|
|
231
|
+
entry: entry
|
|
232
|
+
)
|
|
198
233
|
end
|
|
234
|
+
sleep Random.rand(60..90)
|
|
199
235
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
request = Base64.strict_decode64(request)
|
|
205
|
-
response = Base64.strict_decode64(response)
|
|
236
|
+
when :websocket_history
|
|
237
|
+
websocket_history = get_websocket_history(burp_obj: burp_obj)
|
|
238
|
+
websocket_history.each do |entry|
|
|
239
|
+
next unless entry.key?(:comment) && entry[:comment].to_s.strip.empty?
|
|
206
240
|
|
|
207
|
-
|
|
241
|
+
web_socket_id = entry[:web_socket_id]
|
|
242
|
+
direction = entry[:direction]
|
|
243
|
+
payload = entry[:payload]
|
|
244
|
+
next if web_socket_id.nil? || direction.nil? || payload.nil?
|
|
245
|
+
|
|
246
|
+
payload = Base64.strict_decode64(payload)
|
|
247
|
+
websocket_req = PWN::Plugins::Char.force_utf8("WebSocket ID: #{web_socket_id}\nDirection: #{direction}\nPayload:\n#{payload}")
|
|
208
248
|
ai_analysis = PWN::AI::Introspection.reflect_on(
|
|
209
249
|
system_role_content: system_role_content,
|
|
210
|
-
request:
|
|
250
|
+
request: websocket_req,
|
|
211
251
|
suppress_pii_warning: true
|
|
212
252
|
)
|
|
213
253
|
|
|
@@ -215,43 +255,14 @@ module PWN
|
|
|
215
255
|
|
|
216
256
|
entry[:comment] = ai_analysis
|
|
217
257
|
entry[:highlight] = get_highlight_color.call(ai_analysis: ai_analysis)
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
update_proxy_history(
|
|
221
|
-
burp_obj: burp_obj,
|
|
222
|
-
entry: entry
|
|
223
|
-
)
|
|
224
|
-
end
|
|
225
258
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
payload = entry[:payload]
|
|
233
|
-
next if web_socket_id.nil? || direction.nil? || payload.nil?
|
|
234
|
-
|
|
235
|
-
payload = Base64.strict_decode64(payload)
|
|
236
|
-
websocket_req = PWN::Plugins::Char.force_utf8("WebSocket ID: #{web_socket_id}\nDirection: #{direction}\nPayload:\n#{payload}")
|
|
237
|
-
ai_analysis = PWN::AI::Introspection.reflect_on(
|
|
238
|
-
system_role_content: system_role_content,
|
|
239
|
-
request: websocket_req,
|
|
240
|
-
suppress_pii_warning: true
|
|
241
|
-
)
|
|
242
|
-
|
|
243
|
-
next if ai_analysis.nil? || ai_analysis.strip.empty?
|
|
244
|
-
|
|
245
|
-
entry[:comment] = ai_analysis
|
|
246
|
-
entry[:highlight] = get_highlight_color.call(ai_analysis: ai_analysis)
|
|
247
|
-
|
|
248
|
-
update_websocket_history(
|
|
249
|
-
burp_obj: burp_obj,
|
|
250
|
-
entry: entry
|
|
251
|
-
)
|
|
259
|
+
update_websocket_history(
|
|
260
|
+
burp_obj: burp_obj,
|
|
261
|
+
entry: entry
|
|
262
|
+
)
|
|
263
|
+
end
|
|
264
|
+
sleep Random.rand(3..10)
|
|
252
265
|
end
|
|
253
|
-
|
|
254
|
-
sleep 3
|
|
255
266
|
end
|
|
256
267
|
rescue Errno::ECONNREFUSED
|
|
257
268
|
puts 'BurpSuite AI Introspection Thread >>> Terminating API Calls...'
|
|
@@ -263,7 +274,7 @@ module PWN
|
|
|
263
274
|
puts 'BurpSuite AI Introspection Thread >>> Goodbye.'
|
|
264
275
|
end
|
|
265
276
|
|
|
266
|
-
burp_obj[:
|
|
277
|
+
burp_obj[:introspection_threads] = introspection_thread_arr.push(introspection_thread)
|
|
267
278
|
end
|
|
268
279
|
|
|
269
280
|
burp_obj
|
|
@@ -352,7 +363,9 @@ module PWN
|
|
|
352
363
|
enabled: true
|
|
353
364
|
)
|
|
354
365
|
|
|
355
|
-
init_introspection_thread(burp_obj: burp_obj)
|
|
366
|
+
burp_obj = init_introspection_thread(burp_obj: burp_obj, type: :sitemap)
|
|
367
|
+
burp_obj = init_introspection_thread(burp_obj: burp_obj, type: :proxy_history)
|
|
368
|
+
init_introspection_thread(burp_obj: burp_obj, type: :websocket_history)
|
|
356
369
|
rescue StandardError => e
|
|
357
370
|
stop(burp_obj: burp_obj) unless burp_obj.nil?
|
|
358
371
|
raise e
|
|
@@ -1994,8 +2007,9 @@ module PWN
|
|
|
1994
2007
|
browser_obj = burp_obj[:mitm_browser]
|
|
1995
2008
|
rest_browser = burp_obj[:rest_browser]
|
|
1996
2009
|
mitm_rest_api = burp_obj[:mitm_rest_api]
|
|
1997
|
-
|
|
1998
|
-
|
|
2010
|
+
introspection_thread_arr = burp_obj[:introspection_threads]
|
|
2011
|
+
introspection_thread_arr.each(&:kill) if introspection_thread_arr.is_a?(Array) && introspection_thread_arr.any?
|
|
2012
|
+
# introspection_thread.kill unless introspection_thread.nil?
|
|
1999
2013
|
|
|
2000
2014
|
PWN::Plugins::TransparentBrowser.close(browser_obj: browser_obj)
|
|
2001
2015
|
rest_browser.post("http://#{mitm_rest_api}/shutdown", '')
|
data/lib/pwn/version.rb
CHANGED