rex-socket 0.1.9 → 0.1.10
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
- checksums.yaml.gz.sig +0 -0
- data/lib/rex/socket/ssl.rb +165 -0
- data/lib/rex/socket/ssl_tcp.rb +1 -10
- data/lib/rex/socket/ssl_tcp_server.rb +2 -137
- data/lib/rex/socket/version.rb +1 -1
- data.tar.gz.sig +1 -2
- metadata +3 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fcf6a6e83dff71b36d8471c74c9cd1ac8d5820d1
|
4
|
+
data.tar.gz: cdb5388a417cab22de0f4e4dbdfa9c4ff915da69
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a78e51b16de669de260f18f8c61436ee6fcc1a5f7a402d69d431f0fd61887369a645f93104bb1a2ee90b9d172f56b1bac9dccd853119f7b5c054a9d8bd2178e
|
7
|
+
data.tar.gz: f58e3b79734b84962a8aa36f5d01e8a3477cf60b18490507c67590136412e32e3db1e904586e073e58ab60de79db2210c20d33c50ec737c553ff0b8b1b47ccc1
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -0,0 +1,165 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
require 'rex/socket/x509_certificate'
|
3
|
+
require 'timeout'
|
4
|
+
require 'openssl'
|
5
|
+
|
6
|
+
###
|
7
|
+
#
|
8
|
+
# This class provides methods for interacting with an SSL wrapped TCP server. It
|
9
|
+
# implements the StreamServer IO interface.
|
10
|
+
#
|
11
|
+
###
|
12
|
+
module Rex::Socket::Ssl
|
13
|
+
|
14
|
+
module CertProvider
|
15
|
+
|
16
|
+
def self.ssl_generate_subject
|
17
|
+
st = Rex::Text.rand_state
|
18
|
+
loc = Rex::Text.rand_name.capitalize
|
19
|
+
org = Rex::Text.rand_name.capitalize
|
20
|
+
cn = Rex::Text.rand_hostname
|
21
|
+
"US/ST=#{st}/L=#{loc}/O=#{org}/CN=#{cn}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.ssl_generate_issuer
|
25
|
+
org = Rex::Text.rand_name.capitalize
|
26
|
+
cn = Rex::Text.rand_name.capitalize + " " + Rex::Text.rand_name.capitalize
|
27
|
+
"US/O=#{org}/CN=#{cn}"
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Generate a realistic-looking but obstensibly fake SSL
|
32
|
+
# certificate. This matches a typical "snakeoil" cert.
|
33
|
+
#
|
34
|
+
# @return [String, String, Array]
|
35
|
+
def self.ssl_generate_certificate
|
36
|
+
yr = 24*3600*365
|
37
|
+
vf = Time.at(Time.now.to_i - rand(yr * 3) - yr)
|
38
|
+
vt = Time.at(vf.to_i + (rand(9)+1) * yr)
|
39
|
+
subject = ssl_generate_subject
|
40
|
+
issuer = ssl_generate_issuer
|
41
|
+
key = OpenSSL::PKey::RSA.new(2048){ }
|
42
|
+
cert = OpenSSL::X509::Certificate.new
|
43
|
+
cert.version = 2
|
44
|
+
cert.serial = (rand(0xFFFFFFFF) << 32) + rand(0xFFFFFFFF)
|
45
|
+
cert.subject = OpenSSL::X509::Name.new([["C", subject]])
|
46
|
+
cert.issuer = OpenSSL::X509::Name.new([["C", issuer]])
|
47
|
+
cert.not_before = vf
|
48
|
+
cert.not_after = vt
|
49
|
+
cert.public_key = key.public_key
|
50
|
+
|
51
|
+
ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
|
52
|
+
cert.extensions = [
|
53
|
+
ef.create_extension("basicConstraints","CA:FALSE")
|
54
|
+
]
|
55
|
+
ef.issuer_certificate = cert
|
56
|
+
|
57
|
+
cert.sign(key, OpenSSL::Digest::SHA256.new)
|
58
|
+
|
59
|
+
[key, cert, nil]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# This defines the global certificate provider for all consumers of the mixin
|
64
|
+
# Beware that altering this at runtime in one consumer will affect all others
|
65
|
+
# Providers must expose at least the class methods given above accepting the
|
66
|
+
# same calling convention.
|
67
|
+
@@cert_provider = Rex::Socket::Ssl::CertProvider
|
68
|
+
|
69
|
+
def self.cert_provider=(val)
|
70
|
+
@@cert_provider = val
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
# Parse a certificate in unified PEM format that contains a private key and
|
75
|
+
# one or more certificates. The first certificate is the primary, while any
|
76
|
+
# additional certificates are treated as intermediary certificates. This emulates
|
77
|
+
# the behavior of web servers like nginx.
|
78
|
+
#
|
79
|
+
# @param [String] ssl_cert
|
80
|
+
# @return [String, String, Array]
|
81
|
+
def self.ssl_parse_pem(ssl_cert)
|
82
|
+
Rex::Socket::X509Certificate.parse_pem(ssl_cert)
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.ssl_generate_subject
|
86
|
+
@@cert_provider.ssl_generate_subject
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.ssl_generate_issuer
|
90
|
+
@@cert_provider.ssl_generate_issuer
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.ssl_generate_certificate
|
94
|
+
@@cert_provider.ssl_generate_certificate
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
# Shim for the ssl_parse_pem module method
|
99
|
+
#
|
100
|
+
def ssl_parse_pem(ssl_cert)
|
101
|
+
Rex::Socket::Ssl.ssl_parse_pem(ssl_cert)
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
# Shim for the ssl_generate_certificate module method
|
106
|
+
#
|
107
|
+
def ssl_generate_certificate
|
108
|
+
Rex::Socket::Ssl.ssl_generate_certificate
|
109
|
+
end
|
110
|
+
|
111
|
+
#
|
112
|
+
# Create a new ssl context. If +ssl_cert+ is not given, generates a new
|
113
|
+
# key and a leaf certificate with random values.
|
114
|
+
#
|
115
|
+
# @param [Rex::Socket::Parameters] params
|
116
|
+
# @return [::OpenSSL::SSL::SSLContext]
|
117
|
+
def makessl(params)
|
118
|
+
|
119
|
+
if params.ssl_cert
|
120
|
+
key, cert, chain = ssl_parse_pem(params.ssl_cert)
|
121
|
+
else
|
122
|
+
key, cert, chain = ssl_generate_certificate
|
123
|
+
end
|
124
|
+
|
125
|
+
ctx = OpenSSL::SSL::SSLContext.new()
|
126
|
+
ctx.key = key
|
127
|
+
ctx.cert = cert
|
128
|
+
ctx.extra_chain_cert = chain
|
129
|
+
ctx.options = 0
|
130
|
+
|
131
|
+
if params.ssl_cipher
|
132
|
+
ctx.ciphers = params.ssl_cipher
|
133
|
+
end
|
134
|
+
|
135
|
+
# Older versions of OpenSSL do not export the OP_NO_COMPRESSION symbol
|
136
|
+
if defined?(OpenSSL::SSL::OP_NO_COMPRESSION)
|
137
|
+
# enable/disable the SSL/TLS-level compression
|
138
|
+
if params.ssl_compression
|
139
|
+
ctx.options &= ~OpenSSL::SSL::OP_NO_COMPRESSION
|
140
|
+
else
|
141
|
+
ctx.options |= OpenSSL::SSL::OP_NO_COMPRESSION
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
ctx.session_id_context = Rex::Text.rand_text(16)
|
146
|
+
|
147
|
+
return ctx
|
148
|
+
end
|
149
|
+
|
150
|
+
#
|
151
|
+
# This flag determines whether to use the non-blocking openssl
|
152
|
+
# API calls when they are available. This is still buggy on
|
153
|
+
# Linux/Mac OS X, but is required on Windows
|
154
|
+
#
|
155
|
+
def allow_nonblock?(sock=self.sock)
|
156
|
+
avail = sock.respond_to?(:accept_nonblock)
|
157
|
+
if avail and Rex::Compat.is_windows
|
158
|
+
return true
|
159
|
+
end
|
160
|
+
false
|
161
|
+
end
|
162
|
+
|
163
|
+
attr_accessor :sslctx
|
164
|
+
end
|
165
|
+
|
data/lib/rex/socket/ssl_tcp.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# -*- coding: binary -*-
|
2
2
|
require 'rex/socket'
|
3
|
+
require 'openssl'
|
3
4
|
###
|
4
5
|
#
|
5
6
|
# This class provides methods for interacting with an SSL TCP client
|
@@ -9,15 +10,6 @@ require 'rex/socket'
|
|
9
10
|
module Rex::Socket::SslTcp
|
10
11
|
|
11
12
|
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
13
|
|
22
14
|
include Rex::Socket::Tcp
|
23
15
|
|
@@ -31,7 +23,6 @@ begin
|
|
31
23
|
# Creates an SSL TCP instance.
|
32
24
|
#
|
33
25
|
def self.create(hash = {})
|
34
|
-
raise RuntimeError, "No OpenSSL support" if not @@loaded_openssl
|
35
26
|
hash['SSL'] = true
|
36
27
|
self.create_param(Rex::Socket::Parameters.from_hash(hash))
|
37
28
|
end
|
@@ -1,9 +1,8 @@
|
|
1
1
|
# -*- coding: binary -*-
|
2
2
|
require 'rex/socket'
|
3
|
+
require 'rex/socket/ssl'
|
3
4
|
require 'rex/socket/tcp_server'
|
4
5
|
require 'rex/io/stream_server'
|
5
|
-
require 'rex/socket/x509_certificate'
|
6
|
-
require 'timeout'
|
7
6
|
|
8
7
|
###
|
9
8
|
#
|
@@ -13,15 +12,7 @@ require 'timeout'
|
|
13
12
|
###
|
14
13
|
module Rex::Socket::SslTcpServer
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
begin
|
19
|
-
require 'openssl'
|
20
|
-
@@loaded_openssl = true
|
21
|
-
require 'openssl/nonblock'
|
22
|
-
rescue ::Exception
|
23
|
-
end
|
24
|
-
|
15
|
+
include Rex::Socket::Ssl
|
25
16
|
include Rex::Socket::TcpServer
|
26
17
|
|
27
18
|
##
|
@@ -49,7 +40,6 @@ module Rex::Socket::SslTcpServer
|
|
49
40
|
end
|
50
41
|
|
51
42
|
def initsock(params = nil)
|
52
|
-
raise RuntimeError, 'No OpenSSL support' unless @@loaded_openssl
|
53
43
|
|
54
44
|
if params && params.sslctx && params.sslctx.kind_of?(OpenSSL::SSL::SSLContext)
|
55
45
|
self.sslctx = params.sslctx
|
@@ -114,130 +104,5 @@ module Rex::Socket::SslTcpServer
|
|
114
104
|
end
|
115
105
|
end
|
116
106
|
|
117
|
-
#
|
118
|
-
# Parse a certificate in unified PEM format that contains a private key and
|
119
|
-
# one or more certificates. The first certificate is the primary, while any
|
120
|
-
# additional certificates are treated as intermediary certificates. This emulates
|
121
|
-
# the behavior of web servers like nginx.
|
122
|
-
#
|
123
|
-
# @param [String] ssl_cert
|
124
|
-
# @return [String, String, Array]
|
125
|
-
def self.ssl_parse_pem(ssl_cert)
|
126
|
-
Rex::Socket::X509Certificate.parse_pem(ssl_cert)
|
127
|
-
end
|
128
|
-
|
129
|
-
#
|
130
|
-
# Shim for the ssl_parse_pem module method
|
131
|
-
#
|
132
|
-
def ssl_parse_pem(ssl_cert)
|
133
|
-
Rex::Socket::SslTcpServer.ssl_parse_pem(ssl_cert)
|
134
|
-
end
|
135
|
-
|
136
|
-
def self.ssl_generate_subject
|
137
|
-
st = Rex::Text.rand_state
|
138
|
-
loc = Rex::Text.rand_name.capitalize
|
139
|
-
org = Rex::Text.rand_name.capitalize
|
140
|
-
cn = Rex::Text.rand_hostname
|
141
|
-
"US/ST=#{st}/L=#{loc}/O=#{org}/CN=#{cn}"
|
142
|
-
end
|
143
|
-
|
144
|
-
def self.ssl_generate_issuer
|
145
|
-
org = Rex::Text.rand_name.capitalize
|
146
|
-
cn = Rex::Text.rand_name.capitalize + " " + Rex::Text.rand_name.capitalize
|
147
|
-
"US/O=#{org}/CN=#{cn}"
|
148
|
-
end
|
149
|
-
|
150
|
-
#
|
151
|
-
# Generate a realistic-looking but obstensibly fake SSL
|
152
|
-
# certificate. This matches a typical "snakeoil" cert.
|
153
|
-
#
|
154
|
-
# @return [String, String, Array]
|
155
|
-
def self.ssl_generate_certificate
|
156
|
-
yr = 24*3600*365
|
157
|
-
vf = Time.at(Time.now.to_i - rand(yr * 3) - yr)
|
158
|
-
vt = Time.at(vf.to_i + (rand(9)+1) * yr)
|
159
|
-
subject = ssl_generate_subject
|
160
|
-
issuer = ssl_generate_issuer
|
161
|
-
key = OpenSSL::PKey::RSA.new(2048){ }
|
162
|
-
cert = OpenSSL::X509::Certificate.new
|
163
|
-
cert.version = 2
|
164
|
-
cert.serial = (rand(0xFFFFFFFF) << 32) + rand(0xFFFFFFFF)
|
165
|
-
cert.subject = OpenSSL::X509::Name.new([["C", subject]])
|
166
|
-
cert.issuer = OpenSSL::X509::Name.new([["C", issuer]])
|
167
|
-
cert.not_before = vf
|
168
|
-
cert.not_after = vt
|
169
|
-
cert.public_key = key.public_key
|
170
|
-
|
171
|
-
ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
|
172
|
-
cert.extensions = [
|
173
|
-
ef.create_extension("basicConstraints","CA:FALSE")
|
174
|
-
]
|
175
|
-
ef.issuer_certificate = cert
|
176
|
-
|
177
|
-
cert.sign(key, OpenSSL::Digest::SHA256.new)
|
178
|
-
|
179
|
-
[key, cert, nil]
|
180
|
-
end
|
181
|
-
|
182
|
-
#
|
183
|
-
# Shim for the ssl_generate_certificate module method
|
184
|
-
#
|
185
|
-
def ssl_generate_certificate
|
186
|
-
Rex::Socket::SslTcpServer.ssl_generate_certificate
|
187
|
-
end
|
188
|
-
|
189
|
-
#
|
190
|
-
# Create a new ssl context. If +ssl_cert+ is not given, generates a new
|
191
|
-
# key and a leaf certificate with random values.
|
192
|
-
#
|
193
|
-
# @param [Rex::Socket::Parameters] params
|
194
|
-
# @return [::OpenSSL::SSL::SSLContext]
|
195
|
-
def makessl(params)
|
196
|
-
|
197
|
-
if params.ssl_cert
|
198
|
-
key, cert, chain = ssl_parse_pem(params.ssl_cert)
|
199
|
-
else
|
200
|
-
key, cert, chain = ssl_generate_certificate
|
201
|
-
end
|
202
|
-
|
203
|
-
ctx = OpenSSL::SSL::SSLContext.new()
|
204
|
-
ctx.key = key
|
205
|
-
ctx.cert = cert
|
206
|
-
ctx.extra_chain_cert = chain
|
207
|
-
ctx.options = 0
|
208
|
-
|
209
|
-
if params.ssl_cipher
|
210
|
-
ctx.ciphers = params.ssl_cipher
|
211
|
-
end
|
212
|
-
|
213
|
-
# Older versions of OpenSSL do not export the OP_NO_COMPRESSION symbol
|
214
|
-
if defined?(OpenSSL::SSL::OP_NO_COMPRESSION)
|
215
|
-
# enable/disable the SSL/TLS-level compression
|
216
|
-
if params.ssl_compression
|
217
|
-
ctx.options &= ~OpenSSL::SSL::OP_NO_COMPRESSION
|
218
|
-
else
|
219
|
-
ctx.options |= OpenSSL::SSL::OP_NO_COMPRESSION
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
ctx.session_id_context = Rex::Text.rand_text(16)
|
224
|
-
|
225
|
-
return ctx
|
226
|
-
end
|
227
|
-
|
228
|
-
#
|
229
|
-
# This flag determines whether to use the non-blocking openssl
|
230
|
-
# API calls when they are available. This is still buggy on
|
231
|
-
# Linux/Mac OS X, but is required on Windows
|
232
|
-
#
|
233
|
-
def allow_nonblock?(sock=self.sock)
|
234
|
-
avail = sock.respond_to?(:accept_nonblock)
|
235
|
-
if avail and Rex::Compat.is_windows
|
236
|
-
return true
|
237
|
-
end
|
238
|
-
false
|
239
|
-
end
|
240
|
-
|
241
|
-
attr_accessor :sslctx
|
242
107
|
end
|
243
108
|
|
data/lib/rex/socket/version.rb
CHANGED
data.tar.gz.sig
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
|
2
|
-
p��("r*�r�����������7*�=�i�'ƹJs� I�eJ�y�������w�!4���
|
1
|
+
v�\n�¯O�S0�[]E%�%>͎��EOsV@F,��|us�*U�=gFv��H���1���|���Cr�I�����ٴ�8�Ӗ����T�mcn�cD�P���@QŐM{/�*���2��+D��w��h��2p4ff./3�����7��<�Y��S3b<������ҿ@�T&�{!���蠕n>$!3��.aѓQ˩�v]t�c�-��Ek-X[�Z,��鸝qx�M�S��ߋN~X�=L���lW��zb#r4
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rex-socket
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Maloney
|
@@ -88,7 +88,7 @@ cert_chain:
|
|
88
88
|
G+Hmcg1v810agasPdoydE0RTVZgEOOMoQ07qu7JFXVWZ9ZQpHT7qJATWL/b2csFG
|
89
89
|
8mVuTXnyJOKRJA==
|
90
90
|
-----END CERTIFICATE-----
|
91
|
-
date: 2017-
|
91
|
+
date: 2017-12-29 00:00:00.000000000 Z
|
92
92
|
dependencies:
|
93
93
|
- !ruby/object:Gem::Dependency
|
94
94
|
name: bundler
|
@@ -173,6 +173,7 @@ files:
|
|
173
173
|
- lib/rex/socket/parameters.rb
|
174
174
|
- lib/rex/socket/range_walker.rb
|
175
175
|
- lib/rex/socket/ssh_factory.rb
|
176
|
+
- lib/rex/socket/ssl.rb
|
176
177
|
- lib/rex/socket/ssl_tcp.rb
|
177
178
|
- lib/rex/socket/ssl_tcp_server.rb
|
178
179
|
- lib/rex/socket/subnet_walker.rb
|
metadata.gz.sig
CHANGED
Binary file
|