pwn 0.4.646 → 0.4.648
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/README.md +2 -2
- data/bin/pwn +162 -50
- data/lib/pwn/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cb95e1a689de3ccedc52ac145a4d55e39b3b4189504a256094cb5de24163f5b6
|
|
4
|
+
data.tar.gz: 3300a6a7bbf155e635579898f24b07968995daa6204b16b15061afeeb2cbfe1e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cd989a97ab5630ec645309f00a84e28d8fc907816fca8fa87dae628edeed6566a34e373c382eb6c44c8b980d5f6307aaaa884dd94cd618a1ce6a7b6791d22cf9
|
|
7
|
+
data.tar.gz: 6a4a7a3350fbc575d3ffdabe037f0f3c0d90fd7bdb058f8170a18b45a67521c55a1fd2f1986c72242dc7ad036e269ad5025eff068306ace8ffc72ed7b804c38e
|
data/README.md
CHANGED
|
@@ -37,7 +37,7 @@ $ rvm use ruby-3.2.2@pwn
|
|
|
37
37
|
$ rvm list gemsets
|
|
38
38
|
$ gem install --verbose pwn
|
|
39
39
|
$ pwn
|
|
40
|
-
pwn[v0.4.
|
|
40
|
+
pwn[v0.4.648]:001 >>> PWN.help
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
[](https://youtu.be/G7iLUY4FzsI)
|
|
@@ -52,7 +52,7 @@ $ rvm use ruby-3.2.2@pwn
|
|
|
52
52
|
$ gem uninstall --all --executables pwn
|
|
53
53
|
$ gem install --verbose pwn
|
|
54
54
|
$ pwn
|
|
55
|
-
pwn[v0.4.
|
|
55
|
+
pwn[v0.4.648]:001 >>> PWN.help
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
|
data/bin/pwn
CHANGED
|
@@ -5,9 +5,6 @@ require 'optparse'
|
|
|
5
5
|
require 'pwn'
|
|
6
6
|
require 'pry'
|
|
7
7
|
require 'yaml'
|
|
8
|
-
# require 'colorize'
|
|
9
|
-
# require 'tty-prompt'
|
|
10
|
-
# require 'tty-reader'
|
|
11
8
|
|
|
12
9
|
opts = {}
|
|
13
10
|
OptionParser.new do |options|
|
|
@@ -21,29 +18,39 @@ OptionParser.new do |options|
|
|
|
21
18
|
end.parse!
|
|
22
19
|
|
|
23
20
|
begin
|
|
24
|
-
def
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
# version = PWN::VERSION.cyan
|
|
30
|
-
version = "\001\e[36m\002v#{PWN::VERSION}\001\e[0m\002"
|
|
31
|
-
# dchars = '>>>'.green
|
|
32
|
-
dchars = "\001\e[32m\002>>>\001\e[0m\002"
|
|
33
|
-
# dchars = '***'.yellow if delim == :splat
|
|
34
|
-
dchars = "\001\e[33m\002***\001\e[0m\002" if delim == :splat
|
|
35
|
-
|
|
36
|
-
proc do |_target_self, _nest_level, pry|
|
|
37
|
-
pry.config.pwn_repl_line += 1
|
|
21
|
+
def refresh_ps1_proc(opts = {})
|
|
22
|
+
mode = opts[:mode]
|
|
23
|
+
|
|
24
|
+
proc do |_target_self, _nest_level, pi|
|
|
25
|
+
pi.config.pwn_repl_line += 1
|
|
38
26
|
line_pad = format(
|
|
39
27
|
'%0.3d',
|
|
40
|
-
|
|
28
|
+
pi.config.pwn_repl_line
|
|
41
29
|
)
|
|
42
|
-
|
|
43
|
-
|
|
30
|
+
|
|
31
|
+
pi.config.prompt_name = :pwn
|
|
32
|
+
name = "\001\e[1m\002\001\e[31m\002#{pi.config.prompt_name}\001\e[0m\002"
|
|
33
|
+
version = "\001\e[36m\002v#{PWN::VERSION}\001\e[0m\002"
|
|
34
|
+
line_count = "\001\e[34m\002#{line_pad}\001\e[0m\002"
|
|
35
|
+
dchars = "\001\e[32m\002>>>\001\e[0m\002"
|
|
36
|
+
dchars = "\001\e[33m\002***\001\e[0m\002" if mode == :splat
|
|
37
|
+
if pi.config.chat_gpt
|
|
38
|
+
pi.config.prompt_name = 'chatGPT.pwn'
|
|
39
|
+
pi.config.prompt_name = 'SPEAKING.chatGPT.pwn' if pi.config.chat_gpt_speak
|
|
40
|
+
name = "\001\e[1m\002\001\e[33m\002#{pi.config.prompt_name}\001\e[0m\002"
|
|
41
|
+
dchars = "\001\e[32m\002>>>\001\e[31m\002"
|
|
42
|
+
dchars = "\001\e[33m\002***\001\e[31m\002" if mode == :splat
|
|
43
|
+
if pi.config.chat_gpt_debug
|
|
44
|
+
dchars = "\001\e[32m\002(DEBUG) >>>\001\e[31m\002"
|
|
45
|
+
dchars = "\001\e[33m\002(DEBUG) ***\001\e[31m\002" if mode == :splat
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
"#{name}[#{version}]:#{line_count} #{dchars} ".to_s.scrub
|
|
44
50
|
end
|
|
45
51
|
end
|
|
46
52
|
|
|
53
|
+
# Pry Monkey Patches \_(oo)_/
|
|
47
54
|
class Pry
|
|
48
55
|
# Overwrite Pry::History.push method in History class to get duplicate history entries
|
|
49
56
|
# in order to properly replay automation in this prototyping driver
|
|
@@ -66,6 +73,108 @@ begin
|
|
|
66
73
|
end
|
|
67
74
|
alias << push
|
|
68
75
|
end
|
|
76
|
+
|
|
77
|
+
def handle_line(line, options)
|
|
78
|
+
if line.nil?
|
|
79
|
+
config.control_d_handler.call(self)
|
|
80
|
+
return
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
ensure_correct_encoding!(line)
|
|
84
|
+
Pry.history << line unless options[:generated]
|
|
85
|
+
|
|
86
|
+
@suppress_output = false
|
|
87
|
+
inject_sticky_locals!
|
|
88
|
+
begin
|
|
89
|
+
unless process_command_safely(line)
|
|
90
|
+
@eval_string += "#{line.chomp}\n" if !line.empty? || !@eval_string.empty?
|
|
91
|
+
end
|
|
92
|
+
rescue RescuableException => e
|
|
93
|
+
self.last_exception = e
|
|
94
|
+
result = e
|
|
95
|
+
|
|
96
|
+
Pry.critical_section do
|
|
97
|
+
show_result(result)
|
|
98
|
+
end
|
|
99
|
+
return
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# This hook is supposed to be executed after each line of ruby code
|
|
103
|
+
# has been read (regardless of whether eval_string is yet a complete expression)
|
|
104
|
+
exec_hook :after_read, eval_string, self
|
|
105
|
+
|
|
106
|
+
begin
|
|
107
|
+
if config.chat_gpt
|
|
108
|
+
complete_expr = true
|
|
109
|
+
@eval_string += ';'
|
|
110
|
+
else
|
|
111
|
+
complete_expr = Pry::Code.complete_expression?(@eval_string)
|
|
112
|
+
end
|
|
113
|
+
rescue SyntaxError => e
|
|
114
|
+
output.puts e.message.gsub(/^.*syntax error, */, "SyntaxError: ")
|
|
115
|
+
reset_eval_string
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
if complete_expr
|
|
119
|
+
if @eval_string =~ /;\Z/ || @eval_string.empty? || @eval_string =~ /\A *#.*\n\z/
|
|
120
|
+
@suppress_output = true
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# A bug in jruby makes java.lang.Exception not rescued by
|
|
124
|
+
# `rescue Pry::RescuableException` clause.
|
|
125
|
+
#
|
|
126
|
+
# * https://github.com/pry/pry/issues/854
|
|
127
|
+
# * https://jira.codehaus.org/browse/JRUBY-7100
|
|
128
|
+
#
|
|
129
|
+
# Until that gets fixed upstream, treat java.lang.Exception
|
|
130
|
+
# as an additional exception to be rescued explicitly.
|
|
131
|
+
#
|
|
132
|
+
# This workaround has a side effect: java exceptions specified
|
|
133
|
+
# in `Pry.config.unrescued_exceptions` are ignored.
|
|
134
|
+
jruby_exceptions = []
|
|
135
|
+
jruby_exceptions << Java::JavaLang::Exception if Helpers::Platform.jruby?
|
|
136
|
+
|
|
137
|
+
begin
|
|
138
|
+
# Reset eval string, in case we're evaluating Ruby that does something
|
|
139
|
+
# like open a nested REPL on this instance.
|
|
140
|
+
eval_string = @eval_string
|
|
141
|
+
reset_eval_string
|
|
142
|
+
|
|
143
|
+
result = evaluate_ruby(eval_string)
|
|
144
|
+
rescue RescuableException, *jruby_exceptions => e
|
|
145
|
+
# Eliminate following warning:
|
|
146
|
+
# warning: singleton on non-persistent Java type X
|
|
147
|
+
# (http://wiki.jruby.org/Persistence)
|
|
148
|
+
if Helpers::Platform.jruby? && e.class.respond_to?('__persistent__')
|
|
149
|
+
e.class.__persistent__ = true
|
|
150
|
+
end
|
|
151
|
+
self.last_exception = e
|
|
152
|
+
result = e
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
Pry.critical_section do
|
|
156
|
+
show_result(result)
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
throw(:breakout) if current_binding.nil?
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Ensure the return value in chat_gpt mode reflects the input
|
|
164
|
+
def evaluate_ruby(code)
|
|
165
|
+
if config.chat_gpt
|
|
166
|
+
result = message = code.to_s
|
|
167
|
+
return
|
|
168
|
+
end
|
|
169
|
+
inject_sticky_locals!
|
|
170
|
+
exec_hook :before_eval, code, self
|
|
171
|
+
|
|
172
|
+
result = current_binding.eval(code, Pry.eval_path, Pry.current_line)
|
|
173
|
+
set_last_result(result, code)
|
|
174
|
+
ensure
|
|
175
|
+
update_input_history(code)
|
|
176
|
+
exec_hook :after_eval, result, self
|
|
177
|
+
end
|
|
69
178
|
end
|
|
70
179
|
|
|
71
180
|
# Define Custom REPL Commands
|
|
@@ -86,48 +195,43 @@ begin
|
|
|
86
195
|
end
|
|
87
196
|
end
|
|
88
197
|
|
|
89
|
-
Pry::Commands.create_command 'toggle-chatGPT
|
|
90
|
-
description "
|
|
198
|
+
Pry::Commands.create_command 'toggle-chatGPT' do
|
|
199
|
+
description "Interact w/ OpenAI's ChatGPT"
|
|
91
200
|
|
|
92
201
|
def process
|
|
93
202
|
pi = pry_instance
|
|
94
|
-
pi.config.
|
|
95
|
-
|
|
96
|
-
|
|
203
|
+
pi.config.chat_gpt ? pi.config.chat_gpt = false : pi.config.chat_gpt = true
|
|
204
|
+
pi.config.color = false if pi.config.chat_gpt
|
|
205
|
+
pi.config.color = true unless pi.config.chat_gpt
|
|
97
206
|
end
|
|
98
207
|
end
|
|
99
208
|
|
|
100
|
-
Pry::Commands.create_command 'toggle-chatGPT-
|
|
101
|
-
description
|
|
209
|
+
Pry::Commands.create_command 'toggle-chatGPT-debug' do
|
|
210
|
+
description "Display the response_history object while using OpenAI's ChatGPT."
|
|
102
211
|
|
|
103
212
|
def process
|
|
104
213
|
pi = pry_instance
|
|
105
|
-
pi.config.
|
|
106
|
-
puts 'ChatGPT Speech Enabled.' if pi.config.chat_gpt_speak
|
|
107
|
-
puts 'ChatGPT Speech Disabled.' unless pi.config.chat_gpt_speak
|
|
214
|
+
pi.config.chat_gpt_debug ? pi.config.chat_gpt_debug = false : pi.config.chat_gpt_debug = true
|
|
108
215
|
end
|
|
109
216
|
end
|
|
110
217
|
|
|
111
|
-
Pry::Commands.create_command 'toggle-chatGPT' do
|
|
112
|
-
description
|
|
218
|
+
Pry::Commands.create_command 'toggle-chatGPT-speaks' do
|
|
219
|
+
description 'Use speech capabilities within PWN to speak OpenAI ChatGPT answers.'
|
|
113
220
|
|
|
114
221
|
def process
|
|
115
222
|
pi = pry_instance
|
|
116
|
-
pi.config.
|
|
117
|
-
puts 'ChatGPT Enabled.' if pi.config.chat_gpt
|
|
118
|
-
puts 'ChatGPT Disabled.' unless pi.config.chat_gpt
|
|
223
|
+
pi.config.chat_gpt_speak ? pi.config.chat_gpt_speak = false : pi.config.chat_gpt_speak = true
|
|
119
224
|
end
|
|
120
225
|
end
|
|
121
226
|
|
|
122
227
|
# Define REPL Hooks
|
|
123
228
|
# Welcome Banner Hook
|
|
124
|
-
Pry.config.hooks.add_hook(:before_session, :welcome) do |output, _binding,
|
|
229
|
+
Pry.config.hooks.add_hook(:before_session, :welcome) do |output, _binding, _pi|
|
|
125
230
|
output.puts PWN::Banner.welcome
|
|
126
231
|
end
|
|
127
232
|
|
|
128
233
|
# ChatGPT Hooks
|
|
129
234
|
Pry.config.hooks.add_hook(:before_session, :init_opts) do |_output, _binding, pi|
|
|
130
|
-
pi.config.chat_gpt_token = ''
|
|
131
235
|
if opts[:yaml_config_path] && File.exist?(opts[:yaml_config_path])
|
|
132
236
|
yaml_config_path = opts[:yaml_config_path]
|
|
133
237
|
yaml_config = YAML.load_file(yaml_config_path, symbolize_names: true)
|
|
@@ -135,22 +239,30 @@ begin
|
|
|
135
239
|
end
|
|
136
240
|
end
|
|
137
241
|
|
|
138
|
-
Pry.config.hooks.add_hook(:
|
|
139
|
-
if
|
|
242
|
+
Pry.config.hooks.add_hook(:after_read, :open_ai_hook) do |request, pi|
|
|
243
|
+
if pi.config.chat_gpt && !request.chomp.empty?
|
|
244
|
+
request = pi.input.line_buffer
|
|
140
245
|
debug = pi.config.chat_gpt_debug
|
|
141
246
|
token = pi.config.chat_gpt_token
|
|
142
|
-
token
|
|
247
|
+
token ||= ''
|
|
248
|
+
if token.empty?
|
|
249
|
+
token = PWN::Plugins::AuthenticationHelper.mask_password(
|
|
250
|
+
prompt: 'OpenAI API Key'
|
|
251
|
+
)
|
|
252
|
+
pi.config.chat_gpt_token = token
|
|
253
|
+
end
|
|
254
|
+
|
|
143
255
|
response_history = pi.config.chat_gpt_response_history
|
|
144
256
|
speak_answer = pi.config.chat_gpt_speak
|
|
145
257
|
response = PWN::Plugins::OpenAI.chat(
|
|
146
258
|
token: token,
|
|
147
|
-
request: request.
|
|
259
|
+
request: request.chomp,
|
|
148
260
|
temp: 1,
|
|
149
261
|
max_tokens: 0,
|
|
150
262
|
response_history: response_history,
|
|
151
263
|
speak_answer: speak_answer
|
|
152
264
|
)
|
|
153
|
-
puts "\n\n\n#{response[:choices].last[:content]}\n\n\n"
|
|
265
|
+
puts "\n\n\n\001\e[32m\002#{response[:choices].last[:content]}\001\e[31m\002\n\n\n"
|
|
154
266
|
|
|
155
267
|
response_history = {
|
|
156
268
|
id: response[:id],
|
|
@@ -161,9 +273,9 @@ begin
|
|
|
161
273
|
response_history[:choices] ||= response[:choices]
|
|
162
274
|
|
|
163
275
|
if debug
|
|
164
|
-
puts 'DEBUG: response_history
|
|
276
|
+
puts 'DEBUG: response_history => '
|
|
165
277
|
pp response_history
|
|
166
|
-
puts "
|
|
278
|
+
puts "\nresponse_history[:choices] Length: #{response_history[:choices].length}\n" unless response_history.nil?
|
|
167
279
|
end
|
|
168
280
|
pi.config.chat_gpt_response_history = response_history
|
|
169
281
|
end
|
|
@@ -171,22 +283,22 @@ begin
|
|
|
171
283
|
|
|
172
284
|
# Define PS1 Prompt
|
|
173
285
|
Pry.config.pwn_repl_line = 0
|
|
174
|
-
|
|
175
|
-
|
|
286
|
+
Pry.config.prompt_name = :pwn
|
|
287
|
+
arrow_ps1_proc = refresh_ps1_proc
|
|
288
|
+
splat_ps1_proc = refresh_ps1_proc(mode: :splat)
|
|
176
289
|
prompt_ps1 = [arrow_ps1_proc, splat_ps1_proc]
|
|
177
|
-
|
|
178
|
-
pwn_prompt = Pry::Prompt.new(
|
|
290
|
+
prompt = Pry::Prompt.new(
|
|
179
291
|
:pwn,
|
|
180
292
|
'PWN Prototyping REPL',
|
|
181
293
|
prompt_ps1
|
|
182
294
|
)
|
|
183
295
|
|
|
184
296
|
# Start PWN REPL
|
|
185
|
-
Pry.config.prompt_name = :pwn
|
|
186
297
|
Pry.start(
|
|
187
298
|
self,
|
|
188
|
-
prompt:
|
|
299
|
+
prompt: prompt
|
|
189
300
|
)
|
|
190
301
|
rescue StandardError => e
|
|
302
|
+
puts 1111 if Pry.config.chat_gpt
|
|
191
303
|
raise e
|
|
192
304
|
end
|
data/lib/pwn/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pwn
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.648
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- 0day Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-04-
|
|
11
|
+
date: 2023-04-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|