rex 2.0.12 → 2.0.13
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/lib/rex/socket/ssl_tcp.rb +19 -3
- data/lib/rex/socket/ssl_tcp.rb.orig +382 -0
- data/lib/rex/socket/ssl_tcp.rb.rej +20 -0
- data/rex.gemspec +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6b070e82fb2868e31cbd07cbf52d3e5e294a63a1
|
4
|
+
data.tar.gz: 667ed54cd31a53ea86911a73267d60d926e9b6a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4799124f1fb4c5cd9572ab89dbca7043d25e9ccf9dbbad6cc6dbc3f05793359587ff49088a37cc2af89fc8dd9824ef890c4adf16034f5b830f10e96569bddcd8
|
7
|
+
data.tar.gz: c0d28780954a399dc708c7e8522b617d37fb67ce64dd000ca3feb7b45e13b3661ecf7499db26944249b3a6659da9d4708de563aa134eed16b6afd3a91e131c31
|
data/lib/rex/socket/ssl_tcp.rb
CHANGED
@@ -50,6 +50,22 @@ begin
|
|
50
50
|
#
|
51
51
|
##
|
52
52
|
|
53
|
+
def self.system_ssl_methods
|
54
|
+
ssl_context = OpenSSL::SSL::SSLContext
|
55
|
+
if ssl_context.const_defined? :METHODS_MAP
|
56
|
+
ssl_context.const_get(:METHODS_MAP).keys
|
57
|
+
else
|
58
|
+
ssl_context::METHODS
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.supported_ssl_methods
|
63
|
+
@@methods ||= ['Auto', 'TLS'] + system_ssl_methods
|
64
|
+
.reject { |method| method.match(/server|client/) }
|
65
|
+
.select {|m| OpenSSL::SSL::SSLContext.new(m) && true rescue false} \
|
66
|
+
.map {|m| m.to_s.sub(/v/, '').sub('_', '.')}
|
67
|
+
end
|
68
|
+
|
53
69
|
#
|
54
70
|
# Initializes the SSL socket.
|
55
71
|
#
|
@@ -79,8 +95,9 @@ begin
|
|
79
95
|
end
|
80
96
|
|
81
97
|
# Raise an error if no selected versions are supported
|
82
|
-
|
83
|
-
raise ArgumentError,
|
98
|
+
unless Rex::Socket::SslTcp.system_ssl_methods.include? version
|
99
|
+
raise ArgumentError,
|
100
|
+
"This version of Ruby does not support the requested SSL/TLS version #{params.ssl_version}"
|
84
101
|
end
|
85
102
|
|
86
103
|
# Try intializing the socket with this SSL/TLS version
|
@@ -366,4 +383,3 @@ rescue LoadError
|
|
366
383
|
end
|
367
384
|
|
368
385
|
end
|
369
|
-
|
@@ -0,0 +1,382 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
require 'rex/socket'
|
3
|
+
###
|
4
|
+
#
|
5
|
+
# This class provides methods for interacting with an SSL TCP client
|
6
|
+
# connection.
|
7
|
+
#
|
8
|
+
###
|
9
|
+
module Rex::Socket::SslTcp
|
10
|
+
|
11
|
+
begin
|
12
|
+
@@loaded_openssl = false
|
13
|
+
|
14
|
+
begin
|
15
|
+
require 'openssl'
|
16
|
+
@@loaded_openssl = true
|
17
|
+
require 'openssl/nonblock'
|
18
|
+
rescue ::Exception
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
include Rex::Socket::Tcp
|
23
|
+
|
24
|
+
##
|
25
|
+
#
|
26
|
+
# Factory
|
27
|
+
#
|
28
|
+
##
|
29
|
+
|
30
|
+
#
|
31
|
+
# Creates an SSL TCP instance.
|
32
|
+
#
|
33
|
+
def self.create(hash = {})
|
34
|
+
raise RuntimeError, "No OpenSSL support" if not @@loaded_openssl
|
35
|
+
hash['SSL'] = true
|
36
|
+
self.create_param(Rex::Socket::Parameters.from_hash(hash))
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# Set the SSL flag to true and call the base class's create_param routine.
|
41
|
+
#
|
42
|
+
def self.create_param(param)
|
43
|
+
param.ssl = true
|
44
|
+
Rex::Socket::Tcp.create_param(param)
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
#
|
49
|
+
# Class initialization
|
50
|
+
#
|
51
|
+
##
|
52
|
+
|
53
|
+
#
|
54
|
+
# Initializes the SSL socket.
|
55
|
+
#
|
56
|
+
def initsock(params = nil)
|
57
|
+
super
|
58
|
+
|
59
|
+
# Default to SSLv23 (automatically negotiate)
|
60
|
+
version = :SSLv23
|
61
|
+
|
62
|
+
# Let the caller specify a particular SSL/TLS version
|
63
|
+
if params
|
64
|
+
case params.ssl_version
|
65
|
+
when 'SSL2', :SSLv2
|
66
|
+
version = :SSLv2
|
67
|
+
# 'TLS' will be the new name for autonegotation with newer versions of OpenSSL
|
68
|
+
when 'SSL23', :SSLv23, 'TLS'
|
69
|
+
version = :SSLv23
|
70
|
+
when 'SSL3', :SSLv3
|
71
|
+
version = :SSLv3
|
72
|
+
when 'TLS1','TLS1.0', :TLSv1
|
73
|
+
version = :TLSv1
|
74
|
+
when 'TLS1.1', :TLSv1_1
|
75
|
+
version = :TLSv1_1
|
76
|
+
when 'TLS1.2', :TLSv1_2
|
77
|
+
version = :TLSv1_2
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Raise an error if no selected versions are supported
|
82
|
+
if ! ssl_versions.include? version
|
83
|
+
raise ArgumentError, 'The system OpenSSL does not support the requested SSL/TLS version'
|
84
|
+
end
|
85
|
+
|
86
|
+
# Try intializing the socket with this SSL/TLS version
|
87
|
+
# This will throw an exception if it fails
|
88
|
+
initsock_with_ssl_version(params, version)
|
89
|
+
|
90
|
+
# Track the SSL version
|
91
|
+
self.ssl_negotiated_version = version
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
# List of available SSL versions
|
96
|
+
#
|
97
|
+
# Fix for:
|
98
|
+
# rex/socket/ssl_tcp.rb:82: warning: constant OpenSSL::SSL::SSLContext::METHODS is deprecated
|
99
|
+
def ssl_versions
|
100
|
+
ssl_context = OpenSSL::SSL::SSLContext
|
101
|
+
if ssl_context.const_defined?(:METHODS_MAP)
|
102
|
+
ssl_context.const_get(:METHODS_MAP).keys
|
103
|
+
else
|
104
|
+
ssl_context::METHODS.reject { |method| method.match(/server|client/) }
|
105
|
+
end.sort.reverse
|
106
|
+
end
|
107
|
+
|
108
|
+
def initsock_with_ssl_version(params, version)
|
109
|
+
# Build the SSL connection
|
110
|
+
self.sslctx = OpenSSL::SSL::SSLContext.new(version)
|
111
|
+
|
112
|
+
# Configure the SSL context
|
113
|
+
# TODO: Allow the user to specify the verify mode callback
|
114
|
+
# Valid modes:
|
115
|
+
# VERIFY_CLIENT_ONCE
|
116
|
+
# VERIFY_FAIL_IF_NO_PEER_CERT
|
117
|
+
# VERIFY_NONE
|
118
|
+
# VERIFY_PEER
|
119
|
+
if params.ssl_verify_mode
|
120
|
+
self.sslctx.verify_mode = OpenSSL::SSL.const_get("VERIFY_#{params.ssl_verify_mode}".intern)
|
121
|
+
else
|
122
|
+
# Could also do this as graceful faildown in case a passed verify_mode is not supported
|
123
|
+
self.sslctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
124
|
+
end
|
125
|
+
|
126
|
+
self.sslctx.options = OpenSSL::SSL::OP_ALL
|
127
|
+
|
128
|
+
if params.ssl_cipher
|
129
|
+
self.sslctx.ciphers = params.ssl_cipher
|
130
|
+
end
|
131
|
+
|
132
|
+
# Set the verification callback
|
133
|
+
self.sslctx.verify_callback = Proc.new do |valid, store|
|
134
|
+
self.peer_verified = valid
|
135
|
+
true
|
136
|
+
end
|
137
|
+
|
138
|
+
# Tie the context to a socket
|
139
|
+
self.sslsock = OpenSSL::SSL::SSLSocket.new(self, self.sslctx)
|
140
|
+
|
141
|
+
# Force a negotiation timeout
|
142
|
+
begin
|
143
|
+
Timeout.timeout(params.timeout) do
|
144
|
+
if not allow_nonblock?
|
145
|
+
self.sslsock.connect
|
146
|
+
else
|
147
|
+
begin
|
148
|
+
self.sslsock.connect_nonblock
|
149
|
+
# Ruby 1.8.7 and 1.9.0/1.9.1 uses a standard Errno
|
150
|
+
rescue ::Errno::EAGAIN, ::Errno::EWOULDBLOCK
|
151
|
+
IO::select(nil, nil, nil, 0.10)
|
152
|
+
retry
|
153
|
+
|
154
|
+
# Ruby 1.9.2+ uses IO::WaitReadable/IO::WaitWritable
|
155
|
+
rescue ::Exception => e
|
156
|
+
if ::IO.const_defined?('WaitReadable') and e.kind_of?(::IO::WaitReadable)
|
157
|
+
IO::select( [ self.sslsock ], nil, nil, 0.10 )
|
158
|
+
retry
|
159
|
+
end
|
160
|
+
|
161
|
+
if ::IO.const_defined?('WaitWritable') and e.kind_of?(::IO::WaitWritable)
|
162
|
+
IO::select( nil, [ self.sslsock ], nil, 0.10 )
|
163
|
+
retry
|
164
|
+
end
|
165
|
+
|
166
|
+
raise e
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
rescue ::Timeout::Error
|
172
|
+
raise Rex::ConnectionTimeout.new(params.peerhost, params.peerport)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
##
|
177
|
+
#
|
178
|
+
# Stream mixin implementations
|
179
|
+
#
|
180
|
+
##
|
181
|
+
|
182
|
+
#
|
183
|
+
# Writes data over the SSL socket.
|
184
|
+
#
|
185
|
+
def write(buf, opts = {})
|
186
|
+
return sslsock.write(buf) if not allow_nonblock?
|
187
|
+
|
188
|
+
total_sent = 0
|
189
|
+
total_length = buf.length
|
190
|
+
block_size = 16384
|
191
|
+
retry_time = 0.5
|
192
|
+
|
193
|
+
begin
|
194
|
+
while( total_sent < total_length )
|
195
|
+
s = Rex::ThreadSafe.select( nil, [ self.sslsock ], nil, 0.25 )
|
196
|
+
if( s == nil || s[0] == nil )
|
197
|
+
next
|
198
|
+
end
|
199
|
+
data = buf[total_sent, block_size]
|
200
|
+
sent = sslsock.write_nonblock( data )
|
201
|
+
if sent > 0
|
202
|
+
total_sent += sent
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
rescue ::IOError, ::Errno::EPIPE
|
207
|
+
return nil
|
208
|
+
|
209
|
+
# Ruby 1.8.7 and 1.9.0/1.9.1 uses a standard Errno
|
210
|
+
rescue ::Errno::EAGAIN, ::Errno::EWOULDBLOCK
|
211
|
+
# Sleep for a half a second, or until we can write again
|
212
|
+
Rex::ThreadSafe.select( nil, [ self.sslsock ], nil, retry_time )
|
213
|
+
# Decrement the block size to handle full sendQs better
|
214
|
+
block_size = 1024
|
215
|
+
# Try to write the data again
|
216
|
+
retry
|
217
|
+
|
218
|
+
# Ruby 1.9.2+ uses IO::WaitReadable/IO::WaitWritable
|
219
|
+
rescue ::Exception => e
|
220
|
+
if ::IO.const_defined?('WaitReadable') and e.kind_of?(::IO::WaitReadable)
|
221
|
+
IO::select( [ self.sslsock ], nil, nil, retry_time )
|
222
|
+
retry
|
223
|
+
end
|
224
|
+
|
225
|
+
if ::IO.const_defined?('WaitWritable') and e.kind_of?(::IO::WaitWritable)
|
226
|
+
IO::select( nil, [ self.sslsock ], nil, retry_time )
|
227
|
+
retry
|
228
|
+
end
|
229
|
+
|
230
|
+
# Another form of SSL error, this is always fatal
|
231
|
+
if e.kind_of?(::OpenSSL::SSL::SSLError)
|
232
|
+
return nil
|
233
|
+
end
|
234
|
+
|
235
|
+
# Bubble the event up to the caller otherwise
|
236
|
+
raise e
|
237
|
+
end
|
238
|
+
|
239
|
+
total_sent
|
240
|
+
end
|
241
|
+
|
242
|
+
#
|
243
|
+
# Reads data from the SSL socket.
|
244
|
+
#
|
245
|
+
def read(length = nil, opts = {})
|
246
|
+
if not allow_nonblock?
|
247
|
+
length = 16384 unless length
|
248
|
+
begin
|
249
|
+
return sslsock.sysread(length)
|
250
|
+
rescue ::IOError, ::Errno::EPIPE, ::OpenSSL::SSL::SSLError
|
251
|
+
return nil
|
252
|
+
end
|
253
|
+
return
|
254
|
+
end
|
255
|
+
|
256
|
+
|
257
|
+
begin
|
258
|
+
while true
|
259
|
+
s = Rex::ThreadSafe.select( [ self.sslsock ], nil, nil, 0.10 )
|
260
|
+
if( s == nil || s[0] == nil )
|
261
|
+
next
|
262
|
+
end
|
263
|
+
return sslsock.read_nonblock( length )
|
264
|
+
end
|
265
|
+
|
266
|
+
rescue ::IOError, ::Errno::EPIPE
|
267
|
+
return nil
|
268
|
+
|
269
|
+
# Ruby 1.8.7 and 1.9.0/1.9.1 uses a standard Errno
|
270
|
+
rescue ::Errno::EAGAIN, ::Errno::EWOULDBLOCK
|
271
|
+
# Sleep for a tenth a second, or until we can read again
|
272
|
+
Rex::ThreadSafe.select( [ self.sslsock ], nil, nil, 0.10 )
|
273
|
+
# Decrement the block size to handle full sendQs better
|
274
|
+
block_size = 1024
|
275
|
+
# Try to write the data again
|
276
|
+
retry
|
277
|
+
|
278
|
+
# Ruby 1.9.2+ uses IO::WaitReadable/IO::WaitWritable
|
279
|
+
rescue ::Exception => e
|
280
|
+
if ::IO.const_defined?('WaitReadable') and e.kind_of?(::IO::WaitReadable)
|
281
|
+
IO::select( [ self.sslsock ], nil, nil, 0.5 )
|
282
|
+
retry
|
283
|
+
end
|
284
|
+
|
285
|
+
if ::IO.const_defined?('WaitWritable') and e.kind_of?(::IO::WaitWritable)
|
286
|
+
IO::select( nil, [ self.sslsock ], nil, 0.5 )
|
287
|
+
retry
|
288
|
+
end
|
289
|
+
|
290
|
+
# Another form of SSL error, this is always fatal
|
291
|
+
if e.kind_of?(::OpenSSL::SSL::SSLError)
|
292
|
+
return nil
|
293
|
+
end
|
294
|
+
|
295
|
+
raise e
|
296
|
+
end
|
297
|
+
|
298
|
+
end
|
299
|
+
|
300
|
+
|
301
|
+
#
|
302
|
+
# Closes the SSL socket.
|
303
|
+
#
|
304
|
+
def close
|
305
|
+
sslsock.close rescue nil
|
306
|
+
super
|
307
|
+
end
|
308
|
+
|
309
|
+
#
|
310
|
+
# Ignore shutdown requests
|
311
|
+
#
|
312
|
+
def shutdown(how=0)
|
313
|
+
# Calling shutdown() on an SSL socket can lead to bad things
|
314
|
+
# Cause of http://metasploit.com/dev/trac/ticket/102
|
315
|
+
end
|
316
|
+
|
317
|
+
#
|
318
|
+
# Access to peer cert
|
319
|
+
#
|
320
|
+
def peer_cert
|
321
|
+
sslsock.peer_cert if sslsock
|
322
|
+
end
|
323
|
+
|
324
|
+
#
|
325
|
+
# Access to peer cert chain
|
326
|
+
#
|
327
|
+
def peer_cert_chain
|
328
|
+
sslsock.peer_cert_chain if sslsock
|
329
|
+
end
|
330
|
+
|
331
|
+
#
|
332
|
+
# Access to the current cipher
|
333
|
+
#
|
334
|
+
def cipher
|
335
|
+
sslsock.cipher if sslsock
|
336
|
+
end
|
337
|
+
|
338
|
+
#
|
339
|
+
# Prevent a sysread from the bare socket
|
340
|
+
#
|
341
|
+
def sysread(*args)
|
342
|
+
raise RuntimeError, "Invalid sysread() call on SSL socket"
|
343
|
+
end
|
344
|
+
|
345
|
+
#
|
346
|
+
# Prevent a sysread from the bare socket
|
347
|
+
#
|
348
|
+
def syswrite(*args)
|
349
|
+
raise RuntimeError, "Invalid syswrite() call on SSL socket"
|
350
|
+
end
|
351
|
+
|
352
|
+
#
|
353
|
+
# This flag determines whether to use the non-blocking openssl
|
354
|
+
# API calls when they are available. This is still buggy on
|
355
|
+
# Linux/Mac OS X, but is required on Windows
|
356
|
+
#
|
357
|
+
def allow_nonblock?
|
358
|
+
avail = self.sslsock.respond_to?(:accept_nonblock)
|
359
|
+
if avail and Rex::Compat.is_windows
|
360
|
+
return true
|
361
|
+
end
|
362
|
+
false
|
363
|
+
end
|
364
|
+
|
365
|
+
attr_reader :peer_verified # :nodoc:
|
366
|
+
attr_reader :ssl_negotiated_version # :nodoc:
|
367
|
+
attr_accessor :sslsock, :sslctx, :sslhash # :nodoc:
|
368
|
+
|
369
|
+
def type?
|
370
|
+
return 'tcp-ssl'
|
371
|
+
end
|
372
|
+
|
373
|
+
protected
|
374
|
+
|
375
|
+
attr_writer :peer_verified # :nodoc:
|
376
|
+
attr_writer :ssl_negotiated_version # :nodoc:
|
377
|
+
|
378
|
+
|
379
|
+
rescue LoadError
|
380
|
+
end
|
381
|
+
|
382
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
***************
|
2
|
+
*** 79,86 ****
|
3
|
+
end
|
4
|
+
|
5
|
+
# Raise an error if no selected versions are supported
|
6
|
+
- if ! OpenSSL::SSL::SSLContext::METHODS.include? version
|
7
|
+
- raise ArgumentError, 'The system OpenSSL does not support the requested SSL/TLS version'
|
8
|
+
end
|
9
|
+
|
10
|
+
# Try intializing the socket with this SSL/TLS version
|
11
|
+
--- 95,103 ----
|
12
|
+
end
|
13
|
+
|
14
|
+
# Raise an error if no selected versions are supported
|
15
|
+
+ unless Rex::Socket::SslTcp.system_ssl_methods.include? version
|
16
|
+
+ raise ArgumentError,
|
17
|
+
+ "This version of Ruby does not support the requested SSL/TLS version #{params.ssl_version}"
|
18
|
+
end
|
19
|
+
|
20
|
+
# Try intializing the socket with this SSL/TLS version
|
data/rex.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- HD Moore
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2018-11-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: jsobfu
|
@@ -655,6 +655,8 @@ files:
|
|
655
655
|
- lib/rex/socket/parameters.rb
|
656
656
|
- lib/rex/socket/range_walker.rb
|
657
657
|
- lib/rex/socket/ssl_tcp.rb
|
658
|
+
- lib/rex/socket/ssl_tcp.rb.orig
|
659
|
+
- lib/rex/socket/ssl_tcp.rb.rej
|
658
660
|
- lib/rex/socket/ssl_tcp_server.rb
|
659
661
|
- lib/rex/socket/subnet_walker.rb
|
660
662
|
- lib/rex/socket/switch_board.rb
|
@@ -736,8 +738,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
736
738
|
version: '0'
|
737
739
|
requirements: []
|
738
740
|
rubyforge_project:
|
739
|
-
rubygems_version: 2.6.
|
741
|
+
rubygems_version: 2.6.14
|
740
742
|
signing_key:
|
741
743
|
specification_version: 4
|
742
744
|
summary: Ruby Exploitation Library
|
743
745
|
test_files: []
|
746
|
+
has_rdoc:
|