pwn 0.5.504 → 0.5.505
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 +126 -113
- 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: bee5101dd6376bc129ed438a7e5afdf0fb2fb71612ff4663aa9747b9b538c639
|
|
4
|
+
data.tar.gz: ceac8682de6d7347a350ed8fd3598f371c6a4d1df107f471920bfd8ca7da8520
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4791d10076ceda124e859a7cc92efa78822ede231a3d47acd05e5cd80526aff75d3679f857d2a0c89e52245191fb1f5b211c74e415e3307325f9e8e1f19be331
|
|
7
|
+
data.tar.gz: d039ccf4f5b7ee4fafa39b444fccf29ded52d294d70ef29f4b8df16f170328896885ef9babd5dd0b19588bcbbe24a63bd79f7cab739819e0cad1343e7a2d9d46
|
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.505]: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.505]: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.505]: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[sitemap proxy_history 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,128 @@ 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
|
-
sitemap
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
proxy_entry
|
|
146
|
-
|
|
147
|
-
proxy_entry[:
|
|
130
|
+
# modifications to the request to further probe for vulnerabilities _quickly_.
|
|
131
|
+
case type
|
|
132
|
+
when :sitemap
|
|
133
|
+
proxy_history = get_proxy_history(burp_obj: burp_obj)
|
|
134
|
+
sitemap = get_sitemap(burp_obj: burp_obj)
|
|
135
|
+
sitemap.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
|
+
proxy_history_entry = nil
|
|
146
|
+
if proxy_history.any?
|
|
147
|
+
proxy_history_entry = proxy_history.find do |proxy_entry|
|
|
148
|
+
next unless proxy_entry.key?(:http_service) && proxy_entry.key?(:request)
|
|
149
|
+
|
|
150
|
+
proxy_entry[:http_service][:host] == host &&
|
|
151
|
+
proxy_entry[:http_service][:port] == port &&
|
|
152
|
+
proxy_entry[:http_service][:protocol] == protocol &&
|
|
153
|
+
proxy_entry[:request] == entry[:request]
|
|
154
|
+
end
|
|
148
155
|
end
|
|
149
|
-
end
|
|
150
156
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
157
|
+
if proxy_history_entry.is_a?(Hash) && proxy_history_entry[:comment].length.positive?
|
|
158
|
+
entry[:comment] = proxy_history_entry[:comment]
|
|
159
|
+
entry[:highlight] = proxy_history_entry[:highlight]
|
|
160
|
+
else
|
|
161
|
+
request = Base64.strict_decode64(request)
|
|
162
|
+
response = Base64.strict_decode64(response)
|
|
163
|
+
http_request_response = PWN::Plugins::Char.force_utf8("#{request}\r\n\r\n#{response}")
|
|
164
|
+
ai_analysis = PWN::AI::Introspection.reflect_on(
|
|
165
|
+
system_role_content: system_role_content,
|
|
166
|
+
request: http_request_response,
|
|
167
|
+
suppress_pii_warning: true
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
next if ai_analysis.nil? || ai_analysis.strip.empty?
|
|
171
|
+
|
|
172
|
+
entry[:comment] = ai_analysis
|
|
173
|
+
entry[:highlight] = get_highlight_color.call(ai_analysis: ai_analysis)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
update_sitemap(
|
|
177
|
+
burp_obj: burp_obj,
|
|
178
|
+
entry: entry
|
|
162
179
|
)
|
|
180
|
+
end
|
|
163
181
|
|
|
164
|
-
|
|
182
|
+
when :proxy_history
|
|
183
|
+
sitemap = get_sitemap(burp_obj: burp_obj)
|
|
184
|
+
proxy_history = get_proxy_history(burp_obj: burp_obj)
|
|
185
|
+
proxy_history.each do |entry|
|
|
186
|
+
next unless entry.key?(:comment) && entry[:comment].to_s.strip.empty?
|
|
187
|
+
|
|
188
|
+
request = entry[:request]
|
|
189
|
+
response = entry[:response]
|
|
190
|
+
host = entry[:http_service][:host]
|
|
191
|
+
port = entry[:http_service][:port]
|
|
192
|
+
protocol = entry[:http_service][:protocol]
|
|
193
|
+
next if request.nil? || response.nil? || host.nil? || port.nil? || protocol.nil?
|
|
194
|
+
|
|
195
|
+
# If sitemap comment and highlight color exists, use that instead of re-analyzing
|
|
196
|
+
sitemap_entry = nil
|
|
197
|
+
if sitemap.any?
|
|
198
|
+
sitemap_entry = sitemap.find do |site|
|
|
199
|
+
next unless site.key?(:http_service) && site.key?(:request)
|
|
200
|
+
|
|
201
|
+
site[:http_service][:host] == host &&
|
|
202
|
+
site[:http_service][:port] == port &&
|
|
203
|
+
site[:http_service][:protocol] == protocol &&
|
|
204
|
+
site[:request] == entry[:request]
|
|
205
|
+
end
|
|
206
|
+
end
|
|
165
207
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
208
|
+
if sitemap_entry.is_a?(Hash) && sitemap_entry[:comment].length.positive?
|
|
209
|
+
entry[:comment] = sitemap_entry[:comment]
|
|
210
|
+
entry[:highlight] = sitemap_entry[:highlight]
|
|
211
|
+
else
|
|
212
|
+
request = Base64.strict_decode64(request)
|
|
213
|
+
response = Base64.strict_decode64(response)
|
|
169
214
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
215
|
+
http_request_response = PWN::Plugins::Char.force_utf8("#{request}\r\n\r\n#{response}")
|
|
216
|
+
ai_analysis = PWN::AI::Introspection.reflect_on(
|
|
217
|
+
system_role_content: system_role_content,
|
|
218
|
+
request: http_request_response,
|
|
219
|
+
suppress_pii_warning: true
|
|
220
|
+
)
|
|
175
221
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
request = entry[:request]
|
|
181
|
-
response = entry[:response]
|
|
182
|
-
host = entry[:http_service][:host]
|
|
183
|
-
port = entry[:http_service][:port]
|
|
184
|
-
protocol = entry[:http_service][:protocol]
|
|
185
|
-
next if request.nil? || response.nil? || host.nil? || port.nil? || protocol.nil?
|
|
186
|
-
|
|
187
|
-
# If sitemap comment and highlight color exists, use that instead of re-analyzing
|
|
188
|
-
sitemap_entry = nil
|
|
189
|
-
if sitemap.any?
|
|
190
|
-
sitemap_entry = sitemap.find do |site|
|
|
191
|
-
next unless site.key?(:http_service) && site.key?(:request)
|
|
192
|
-
|
|
193
|
-
site[:http_service][:host] == host &&
|
|
194
|
-
site[:http_service][:port] == port &&
|
|
195
|
-
site[:http_service][:protocol] == protocol &&
|
|
196
|
-
site[:request] == entry[:request]
|
|
222
|
+
next if ai_analysis.nil? || ai_analysis.strip.empty?
|
|
223
|
+
|
|
224
|
+
entry[:comment] = ai_analysis
|
|
225
|
+
entry[:highlight] = get_highlight_color.call(ai_analysis: ai_analysis)
|
|
197
226
|
end
|
|
227
|
+
|
|
228
|
+
update_proxy_history(
|
|
229
|
+
burp_obj: burp_obj,
|
|
230
|
+
entry: entry
|
|
231
|
+
)
|
|
198
232
|
end
|
|
199
233
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
234
|
+
when :websocket_history
|
|
235
|
+
websocket_history = get_websocket_history(burp_obj: burp_obj)
|
|
236
|
+
websocket_history.each do |entry|
|
|
237
|
+
next unless entry.key?(:comment) && entry[:comment].to_s.strip.empty?
|
|
238
|
+
|
|
239
|
+
web_socket_id = entry[:web_socket_id]
|
|
240
|
+
direction = entry[:direction]
|
|
241
|
+
payload = entry[:payload]
|
|
242
|
+
next if web_socket_id.nil? || direction.nil? || payload.nil?
|
|
206
243
|
|
|
207
|
-
|
|
244
|
+
payload = Base64.strict_decode64(payload)
|
|
245
|
+
websocket_req = PWN::Plugins::Char.force_utf8("WebSocket ID: #{web_socket_id}\nDirection: #{direction}\nPayload:\n#{payload}")
|
|
208
246
|
ai_analysis = PWN::AI::Introspection.reflect_on(
|
|
209
247
|
system_role_content: system_role_content,
|
|
210
|
-
request:
|
|
248
|
+
request: websocket_req,
|
|
211
249
|
suppress_pii_warning: true
|
|
212
250
|
)
|
|
213
251
|
|
|
@@ -215,43 +253,15 @@ module PWN
|
|
|
215
253
|
|
|
216
254
|
entry[:comment] = ai_analysis
|
|
217
255
|
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
|
-
|
|
226
|
-
websocket_history = get_websocket_history(burp_obj: burp_obj)
|
|
227
|
-
websocket_history.each do |entry|
|
|
228
|
-
next unless entry.key?(:comment) && entry[:comment].to_s.strip.empty?
|
|
229
|
-
|
|
230
|
-
web_socket_id = entry[:web_socket_id]
|
|
231
|
-
direction = entry[:direction]
|
|
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
256
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
update_websocket_history(
|
|
249
|
-
burp_obj: burp_obj,
|
|
250
|
-
entry: entry
|
|
251
|
-
)
|
|
257
|
+
update_websocket_history(
|
|
258
|
+
burp_obj: burp_obj,
|
|
259
|
+
entry: entry
|
|
260
|
+
)
|
|
261
|
+
end
|
|
252
262
|
end
|
|
253
263
|
|
|
254
|
-
sleep
|
|
264
|
+
sleep Random.rand(30..60)
|
|
255
265
|
end
|
|
256
266
|
rescue Errno::ECONNREFUSED
|
|
257
267
|
puts 'BurpSuite AI Introspection Thread >>> Terminating API Calls...'
|
|
@@ -263,7 +273,7 @@ module PWN
|
|
|
263
273
|
puts 'BurpSuite AI Introspection Thread >>> Goodbye.'
|
|
264
274
|
end
|
|
265
275
|
|
|
266
|
-
burp_obj[:
|
|
276
|
+
burp_obj[:introspection_threads] = introspection_thread_arr.push(introspection_thread)
|
|
267
277
|
end
|
|
268
278
|
|
|
269
279
|
burp_obj
|
|
@@ -352,7 +362,9 @@ module PWN
|
|
|
352
362
|
enabled: true
|
|
353
363
|
)
|
|
354
364
|
|
|
355
|
-
init_introspection_thread(burp_obj: burp_obj)
|
|
365
|
+
burp_obj = init_introspection_thread(burp_obj: burp_obj, type: :sitemap)
|
|
366
|
+
burp_obj = init_introspection_thread(burp_obj: burp_obj, type: :proxy_history)
|
|
367
|
+
init_introspection_thread(burp_obj: burp_obj, type: :websocket_history)
|
|
356
368
|
rescue StandardError => e
|
|
357
369
|
stop(burp_obj: burp_obj) unless burp_obj.nil?
|
|
358
370
|
raise e
|
|
@@ -1994,8 +2006,9 @@ module PWN
|
|
|
1994
2006
|
browser_obj = burp_obj[:mitm_browser]
|
|
1995
2007
|
rest_browser = burp_obj[:rest_browser]
|
|
1996
2008
|
mitm_rest_api = burp_obj[:mitm_rest_api]
|
|
1997
|
-
|
|
1998
|
-
|
|
2009
|
+
introspection_thread_arr = burp_obj[:introspection_threads]
|
|
2010
|
+
introspection_thread_arr.each(&:kill) if introspection_thread_arr.is_a?(Array) && introspection_thread_arr.any?
|
|
2011
|
+
# introspection_thread.kill unless introspection_thread.nil?
|
|
1999
2012
|
|
|
2000
2013
|
PWN::Plugins::TransparentBrowser.close(browser_obj: browser_obj)
|
|
2001
2014
|
rest_browser.post("http://#{mitm_rest_api}/shutdown", '')
|
data/lib/pwn/version.rb
CHANGED