pwn 0.5.40 → 0.5.42

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4327c8038770a06069be1c810f891bdcf49b50c12809c635a1c8f8d5c9a0c4c7
4
- data.tar.gz: 3279e4cdb7e735fa2db943ec818b1237048186e4d53d03cd6d357dac119793ab
3
+ metadata.gz: 132c78ae9112e7c2da8c02d5b2d7d32370953c7bc05686026e097ad04d5c4ba0
4
+ data.tar.gz: 2d51b81f19297ba49e61288998df35b4bc3c88a2dff0ca05a0ba44b6db1c3f65
5
5
  SHA512:
6
- metadata.gz: b639ee4e0187f0e178a4d8907aa35d2c8d6e2bc9307ae85a538f73ea8870b3330756214d004b4e208a33c3f7b1d7bcc158e2173f52c5a6e9c9e5b439069389a1
7
- data.tar.gz: 7378d801b6d60c5395464404545b8fec47fb29b98adde522c7013ec9023be8e303459d245b1986775a5e51360388389d044df1a8f1bec86189d24774878cde92
6
+ metadata.gz: 23a021b1d27dc5fd2352c61e9c00afea1aa9ffe98e7a6040e5d0cb913c5261eebd9e429a2f416304f3177c9c726bc8ca0cfec1c2d8bcc2a7cf7025852758d44a
7
+ data.tar.gz: 7a71c1e70bb63993f113b4c5ee7d6ce4162b6252da72b4795c2d9e320b740b7f8ef871179c5a65c4c77d1e6590008480e16127f15be868a403cea8362e021c5c
data/Gemfile CHANGED
@@ -96,4 +96,4 @@ gem 'waveform', '0.1.3'
96
96
  gem 'webrick', '1.8.1'
97
97
  gem 'whois', '5.1.1'
98
98
  gem 'whois-parser', '2.0.0'
99
- gem 'wicked_pdf', '2.7.0'
99
+ gem 'wicked_pdf', '2.8.0'
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]:001 >>> PWN.help
40
+ pwn[v0.5.42]: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.3.0@pwn
52
52
  $ gem uninstall --all --executables pwn
53
53
  $ gem install --verbose pwn
54
54
  $ pwn
55
- pwn[v0.5.40]:001 >>> PWN.help
55
+ pwn[v0.5.42]: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.3.0@pwn
62
62
  $ rvmsudo gem uninstall --all --executables pwn
63
63
  $ rvmsudo gem install --verbose pwn
64
64
  $ pwn
65
- pwn[v0.5.40]:001 >>> PWN.help
65
+ pwn[v0.5.42]: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/bin/pwn CHANGED
@@ -49,8 +49,8 @@ begin
49
49
  if pi.config.pwn_asm
50
50
  pi.config.prompt_name = 'pwn.asm'
51
51
  name = "\001\e[1m\002\001\e[37m\002#{pi.config.prompt_name}\001\e[0m\002"
52
- dchars = "\001\e[32m\002>>>\001\e[37m\002"
53
- dchars = "\001\e[33m\002***\001\e[37m\002" if mode == :splat
52
+ dchars = "\001\e[32m\002>>>\001\e[33m\002"
53
+ dchars = "\001\e[33m\002***\001\e[33m\002" if mode == :splat
54
54
  end
55
55
 
56
56
  if pi.config.pwn_gpt
@@ -157,7 +157,11 @@ begin
157
157
  eval_string = @eval_string
158
158
  reset_eval_string
159
159
 
160
- result = evaluate_ruby(eval_string)
160
+ result = evaluate_ruby(eval_string) unless config.pwn_gpt ||
161
+ config.pwn_asm
162
+
163
+ result = eval_string if config.pwn_gpt ||
164
+ config.pwn_asm
161
165
  rescue RescuableException, *jruby_exceptions => e
162
166
  # Eliminate following warning:
163
167
  # warning: singleton on non-persistent Java type X
@@ -179,10 +183,10 @@ begin
179
183
 
180
184
  # Ensure the return value in pwn_gpt mode reflects the input
181
185
  def evaluate_ruby(code)
182
- if config.pwn_gpt || config.pwn_asm
183
- result = message = code.to_s
184
- return
185
- end
186
+ # if config.pwn_gpt || config.pwn_asm
187
+ # result = message = code.to_s
188
+ # return
189
+ # end
186
190
  inject_sticky_locals!
187
191
  exec_hook :before_eval, code, self
188
192
 
@@ -218,9 +222,6 @@ begin
218
222
  def process
219
223
  pi = pry_instance
220
224
  pi.config.pwn_asm ? pi.config.pwn_asm = false : pi.config.pwn_asm = true
221
-
222
- pi.config.color = false if pi.config.pwn_asm
223
- pi.config.color = true unless pi.config.pwn_asm
224
225
  end
225
226
  end
226
227
 
@@ -230,7 +231,6 @@ begin
230
231
  def process
231
232
  pi = pry_instance
232
233
  pi.config.pwn_gpt ? pi.config.pwn_gpt = false : pi.config.pwn_gpt = true
233
-
234
234
  pi.config.color = false if pi.config.pwn_gpt
235
235
  pi.config.color = true unless pi.config.pwn_gpt
236
236
  end
@@ -273,19 +273,34 @@ begin
273
273
  Pry.config.hooks.add_hook(:after_read, :pwn_asm_hook) do |request, pi|
274
274
  if pi.config.pwn_asm && !request.chomp.empty?
275
275
  request = pi.input.line_buffer
276
- # Determine what request is and determine if it's asm or opcodes
277
- if request =~ /^[a-fA-F0-9\s]+$/
278
- response = PWN::Plugins::Assembly.opcodes_to_asm(opcodes: request)
276
+
277
+ # Analyze request to determine if it should be processed as opcodes or asm.
278
+ straight_hex = /^[a-fA-F0-9\s]+$/
279
+ hex_esc_strings = /\\x[\da-fA-F]{2}/
280
+ hex_comma_delim_w_dbl_qt = /"(?:[0-9a-fA-F]{2})",?/
281
+ hex_comma_delim_w_sng_qt = /'(?:[0-9a-fA-F]{2})',?/
282
+ hex_byte_array_as_str = /^\[\s*(?:"[0-9a-fA-F]{2}",\s*)*"[0-9a-fA-F]{2}"\s*\]$/
283
+
284
+ if request.match?(straight_hex) ||
285
+ request.match?(hex_esc_strings) ||
286
+ request.match?(hex_comma_delim_w_dbl_qt) ||
287
+ request.match?(hex_comma_delim_w_sng_qt) ||
288
+ request.match?(hex_byte_array_as_str)
289
+
290
+ response = PWN::Plugins::Assembly.opcodes_to_asm(
291
+ opcodes: request,
292
+ opcodes_always_strings_obj: true
293
+ )
279
294
  else
280
295
  response = PWN::Plugins::Assembly.asm_to_opcodes(asm: request)
281
296
  end
282
- puts "\n\n\n\001\e[31m\002#{response}\001\e[0m\002\n\n\n"
297
+ puts "\001\e[31m\002#{response}\001\e[0m\002"
283
298
  end
284
299
  end
285
300
 
286
301
  Pry.config.hooks.add_hook(:after_read, :pwn_gpt_hook) do |request, pi|
287
302
  if pi.config.pwn_gpt && !request.chomp.empty?
288
- request = pi.input.line_buffer
303
+ request = pi.input.line_buffer.to_s
289
304
  debug = pi.config.pwn_gpt_debug
290
305
  open_ai_key = pi.config.pwn_gpt_key
291
306
  open_ai_key ||= ''
@@ -305,7 +320,8 @@ begin
305
320
  response_history: response_history,
306
321
  speak_answer: speak_answer
307
322
  )
308
- puts "\n\n\n\001\e[32m\002#{response[:choices].last[:content]}\001\e[31m\002\n\n\n"
323
+ last_response = response[:choices].last[:content]
324
+ puts "\n\001\e[32m\002#{last_response}\001\e[0m\002\n\n"
309
325
 
310
326
  response_history = {
311
327
  id: response[:id],
@@ -11,12 +11,14 @@ module PWN
11
11
  # Supported Method Parameters::
12
12
  # PWN::Plugins::Assembly.opcodes_to_asm(
13
13
  # opcodes: 'required - hex escaped opcode(s) (e.g. "\x90\x90\x90")',
14
+ # opcodes_always_string_obj: 'optional - always interpret opcodes passed in as a string object (defaults to false)',
14
15
  # arch: 'optional - architecture returned from objdump --info (defaults to PWN::Plugins::DetectOS.arch)',
15
16
  # endian: 'optional - endianess (defaults to :little)'
16
17
  # )
17
18
 
18
19
  public_class_method def self.opcodes_to_asm(opts = {})
19
20
  opcodes = opts[:opcodes]
21
+ opcodes_always_string_obj = opts[:opcodes_always_string_obj] ||= false
20
22
  arch = opts[:arch] ||= PWN::Plugins::DetectOS.arch
21
23
  endian = opts[:endian] ||= :little
22
24
 
@@ -40,28 +42,43 @@ module PWN
40
42
  # '909090'
41
43
  opcodes_orig_len = opcodes.length
42
44
  opcodes = opcodes.join(',') if opcodes.is_a?(Array)
45
+ # puts opcodes.inspect
43
46
  opcodes = CGI.escape(opcodes)
44
47
  # puts opcodes.inspect
45
- # Doesnt work with sommething like: "'ff', 'e4'"
46
- # known to work with:
48
+ # known to work (when method is called directly) with:
47
49
  # 'ffe4'
48
50
  # 'ff,e4'
51
+ # 'ff e4'
49
52
  # "ff,e4"
53
+ # "ff e4"
50
54
  # ['ff', 'e4']
51
55
  # ["ff", "e4"]
52
56
  # '\xff\xe4'
53
57
  # "\xff\xe4"
54
- opcodes.delete!('%5Cx') if opcodes.include?('%5Cx')
55
- opcodes.delete!('%2C') if opcodes.include?('%2C')
56
- opcodes.delete!('%22') if opcodes.include?('%22')
57
- opcodes.delete!('%27') if opcodes.include?('%27')
58
- opcodes.delete!('+') if opcodes.include?('+')
59
- opcodes.delete!('%') if opcodes.include?('%')
58
+ # "'ff', 'e4'"
59
+ # '"ff", "e4"'
60
+ # only known to work in pwn REPL driver with:
61
+ # ffe4
62
+ # ff e4
63
+ # puts opcodes.inspect
64
+ # More stripping if passed in via pwn REPL driver
65
+ # if opcodes_always_string_obj
66
+ # end
67
+
68
+ opcodes.delete!('%5B')
69
+ opcodes.delete!('%5D')
70
+ opcodes.delete!('%5Cx')
71
+ opcodes.delete!('%2C')
72
+ opcodes.delete!('%22')
73
+ opcodes.delete!('%27')
74
+ opcodes.delete!('+')
75
+ opcodes.delete!('%')
76
+
60
77
  # puts opcodes.inspect
61
78
  opcodes = [opcodes].pack('H*')
62
79
  # puts opcodes.inspect
63
80
 
64
- Metasm::Shellcode.disassemble(arch_obj, opcodes).to_s
81
+ Metasm::Shellcode.disassemble(arch_obj, opcodes).to_s.squeeze("\n")
65
82
  rescue StandardError => e
66
83
  raise e
67
84
  end
@@ -95,7 +112,13 @@ module PWN
95
112
  raise "Unsupported architecture: #{arch}"
96
113
  end
97
114
 
98
- Metasm::Shellcode.assemble(arch_obj, asm).encode_string.bytes.map { |b| format('\x%02x', b) }.join
115
+ opcodes = Metasm::Shellcode.assemble(arch_obj, asm).encode_string
116
+ hex_encoded_opcodes = opcodes.bytes.map { |b| format('\x%02x', b) }.join
117
+
118
+ "\n#{hex_encoded_opcodes}\n"
119
+ rescue Metasm::ParseError
120
+ puts "Invalid assembly instruction(s) provided:\n#{asm}"
121
+ # Should we try to call opcode_to_asm here or just raise the error?
99
122
  rescue StandardError => e
100
123
  raise e
101
124
  end
@@ -114,6 +137,7 @@ module PWN
114
137
  puts "USAGE:
115
138
  #{self}.opcodes_to_asm(
116
139
  opcodes: 'required - hex escaped opcode(s) (e.g. \"\\x90\\x90\\x90\")',
140
+ opcodes_always_string_obj: 'optional - always interpret opcodes passed in as a string object (defaults to false)',
117
141
  arch: 'optional - architecture returned from objdump --info (defaults to PWN::Plugins::DetectOS.arch)',
118
142
  endian: 'optional - endianess (defaults to :little)'
119
143
  )
@@ -47,6 +47,9 @@ module PWN
47
47
  spinner = TTY::Spinner.new
48
48
  spinner.auto_spin
49
49
 
50
+ max_request_attempts = 3
51
+ tot_request_attempts ||= 1
52
+
50
53
  case http_method
51
54
  when :delete, :get
52
55
  headers[:params] = params
@@ -90,6 +93,18 @@ module PWN
90
93
  end
91
94
 
92
95
  raise e
96
+ rescue IO::TimeoutError => e
97
+ raise e if tot_request_attempts == max_request_attempts
98
+
99
+ puts "\nTCP Connection Unavailable."
100
+ puts "Attempt (#{tot_request_attempts} of #{max_request_attempts}) in 60s"
101
+ 60.downto(1) do
102
+ print '.'
103
+ sleep 1
104
+ end
105
+ tot_request_attempts += 1
106
+
107
+ retry
93
108
  rescue StandardError => e
94
109
  case e.message
95
110
  when '400 Bad Request', '404 Resource Not Found'
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.40'
4
+ VERSION = '0.5.42'
5
5
  end
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.5.40
4
+ version: 0.5.42
5
5
  platform: ruby
6
6
  authors:
7
7
  - 0day Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-27 00:00:00.000000000 Z
11
+ date: 2024-02-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -1164,14 +1164,14 @@ dependencies:
1164
1164
  requirements:
1165
1165
  - - '='
1166
1166
  - !ruby/object:Gem::Version
1167
- version: 2.7.0
1167
+ version: 2.8.0
1168
1168
  type: :runtime
1169
1169
  prerelease: false
1170
1170
  version_requirements: !ruby/object:Gem::Requirement
1171
1171
  requirements:
1172
1172
  - - '='
1173
1173
  - !ruby/object:Gem::Version
1174
- version: 2.7.0
1174
+ version: 2.8.0
1175
1175
  description: https://github.com/0dayinc/pwn/README.md
1176
1176
  email:
1177
1177
  - request.pentest@0dayinc.com