rex-socket 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,132 @@
1
+ # -*- coding: binary -*-
2
+ require 'rex/socket'
3
+
4
+ ###
5
+ #
6
+ # This class provides methods for interacting with a IP socket.
7
+ #
8
+ ###
9
+ module Rex::Socket::Ip
10
+
11
+ include Rex::Socket
12
+
13
+ ##
14
+ #
15
+ # Factory
16
+ #
17
+ ##
18
+
19
+ #
20
+ # Creates the client using the supplied hash.
21
+ #
22
+ def self.create(hash = {})
23
+ hash['Proto'] = 'ip'
24
+ self.create_param(Rex::Socket::Parameters.from_hash(hash))
25
+ end
26
+
27
+ #
28
+ # Wrapper around the base socket class' creation method that automatically
29
+ # sets the parameter's protocol to IP.
30
+ #
31
+ def self.create_param(param)
32
+ param.proto = 'ip'
33
+ Rex::Socket.create_param(param)
34
+ end
35
+
36
+ ##
37
+ #
38
+ # IP connected state methods
39
+ #
40
+ ##
41
+
42
+ #
43
+ # Write the supplied datagram to the connected IP socket.
44
+ #
45
+ def write(gram)
46
+ raise RuntimeError, "IP sockets must use sendto(), not write()"
47
+ end
48
+
49
+ alias put write
50
+
51
+ #
52
+ # Read a datagram from the IP socket.
53
+ #
54
+ def read(length = 65535)
55
+ raise RuntimeError, "IP sockets must use recvfrom(), not read()"
56
+ end
57
+
58
+ ##
59
+ #
60
+ # IP non-connected state methods
61
+ #
62
+ ##
63
+
64
+ #
65
+ # Sends a datagram to the supplied host:port with optional flags.
66
+ #
67
+ def sendto(gram, peerhost, flags = 0)
68
+ dest = ::Socket.pack_sockaddr_in(0, peerhost)
69
+
70
+ # Some BSDs require byteswap for len and offset
71
+ if(
72
+ Rex::Compat.is_freebsd or
73
+ Rex::Compat.is_netbsd or
74
+ Rex::Compat.is_bsdi or
75
+ Rex::Compat.is_macosx
76
+ )
77
+ gram=gram.dup
78
+ # Note that these are *intentionally* host order for BSD support
79
+ gram[2,2]=gram[2,2].unpack("n").pack("s")
80
+ gram[6,2]=gram[6,2].unpack("n").pack("s")
81
+ end
82
+
83
+ begin
84
+ send(gram, flags, dest)
85
+ rescue ::Errno::EHOSTUNREACH,::Errno::ENETDOWN,::Errno::ENETUNREACH,::Errno::ENETRESET,::Errno::EHOSTDOWN,::Errno::EACCES,::Errno::EINVAL,::Errno::EADDRNOTAVAIL
86
+ return nil
87
+ end
88
+
89
+ end
90
+
91
+ #
92
+ # Receives a datagram and returns the data and host of the requestor
93
+ # as [ data, host ].
94
+ #
95
+ def recvfrom(length = 65535, timeout=def_read_timeout)
96
+ begin
97
+ if ((rv = ::IO.select([ fd ], nil, nil, timeout)) and
98
+ (rv[0]) and (rv[0][0] == fd)
99
+ )
100
+ data, saddr = super(length)
101
+ af, host = Rex::Socket.from_sockaddr(saddr)
102
+
103
+ return [ data, host ]
104
+ else
105
+ return [ '', nil ]
106
+ end
107
+ rescue Exception
108
+ return [ '', nil ]
109
+ end
110
+ end
111
+
112
+ #
113
+ # Calls recvfrom and only returns the data
114
+ #
115
+ def get(timeout=nil)
116
+ data, saddr = recvfrom(65535, timeout)
117
+ return data
118
+ end
119
+
120
+ #
121
+ # The default number of seconds to wait for a read operation to timeout.
122
+ #
123
+ def def_read_timeout
124
+ 10
125
+ end
126
+
127
+ def type?
128
+ return 'ip'
129
+ end
130
+
131
+ end
132
+
@@ -0,0 +1,372 @@
1
+ # -*- coding: binary -*-
2
+ require 'rex/socket'
3
+
4
+ ###
5
+ #
6
+ # This class represents the set of parameters that are used to create
7
+ # a socket, whether it be a server or client socket.
8
+ #
9
+ # @example
10
+ # nsock = Rex::Socket::Tcp.create(
11
+ # 'PeerHost' => opts['RHOST'] || rhost,
12
+ # 'PeerPort' => (opts['RPORT'] || rport).to_i,
13
+ # 'LocalHost' => opts['CHOST'] || chost || "0.0.0.0",
14
+ # 'LocalPort' => (opts['CPORT'] || cport || 0).to_i,
15
+ # 'SSL' => dossl,
16
+ # 'SSLVersion'=> opts['SSLVersion'] || ssl_version,
17
+ # 'Proxies' => proxies,
18
+ # 'Timeout' => (opts['ConnectTimeout'] || connect_timeout || 10).to_i,
19
+ # 'Context' =>
20
+ # {
21
+ # 'Msf' => framework,
22
+ # 'MsfExploit' => self,
23
+ # })
24
+ #
25
+ ###
26
+ class Rex::Socket::Parameters
27
+
28
+ ##
29
+ #
30
+ # Factory
31
+ #
32
+ ##
33
+
34
+ #
35
+ # Creates an instance of the Parameters class using the supplied hash.
36
+ #
37
+ def self.from_hash(hash)
38
+ return self.new(hash)
39
+ end
40
+
41
+ ##
42
+ #
43
+ # Constructor
44
+ #
45
+ ##
46
+
47
+ #
48
+ # Initializes the attributes from the supplied hash. The following hash
49
+ # keys can be specified.
50
+ #
51
+ # @option hash [String] 'PeerHost' The remote host to connect to
52
+ # @option hash [String] 'PeerAddr' (alias for 'PeerHost')
53
+ # @option hash [Fixnum] 'PeerPort' The remote port to connect to
54
+ # @option hash [String] 'LocalHost' The local host to communicate from, if any
55
+ # @option hash [String] 'LocalPort' The local port to communicate from, if any
56
+ # @option hash [Bool] 'Bool' Create a bare socket
57
+ # @option hash [Bool] 'Server' Whether or not this should be a server
58
+ # @option hash [Bool] 'SSL' Whether or not SSL should be used
59
+ # @option hash [OpenSSL::SSL::SSLContext] 'SSLContext' Use a pregenerated SSL Context
60
+ # @option hash [String] 'SSLVersion' Specify Auto, SSL2, SSL3, or TLS1 (Auto is
61
+ # default)
62
+ # @option hash [String] 'SSLCert' A file containing an SSL certificate (for
63
+ # server sockets)
64
+ # @option hash [String] 'SSLCipher' see {#ssl_cipher}
65
+ # @option hash [Bool] 'SSLCompression' enable SSL-level compression where available
66
+ # @option hash [String] 'SSLVerifyMode' SSL certificate verification
67
+ # mechanism. One of 'NONE' (default), 'CLIENT_ONCE', 'FAIL_IF_NO_PEER_CERT ', 'PEER'
68
+ # @option hash [String] 'Proxies' List of proxies to use.
69
+ # @option hash [String] 'Proto' The underlying protocol to use.
70
+ # @option hash [String] 'IPv6' Force the use of IPv6.
71
+ # @option hash [String] 'Comm' The underlying {Comm} object to use to create
72
+ # the socket for this parameter set.
73
+ # @option hash [Hash] 'Context' A context hash that can allow users of
74
+ # this parameter class instance to determine who is responsible for
75
+ # requesting that a socket be created.
76
+ # @option hash [String] 'Retries' The number of times a connection should be
77
+ # retried.
78
+ # @option hash [Fixnum] 'Timeout' The number of seconds before a connection
79
+ # should time out
80
+ def initialize(hash)
81
+ if (hash['PeerHost'])
82
+ self.peerhost = hash['PeerHost']
83
+ elsif (hash['PeerAddr'])
84
+ self.peerhost = hash['PeerAddr']
85
+ else
86
+ self.peerhost = nil
87
+ end
88
+
89
+ if (hash['LocalHost'])
90
+ self.localhost = hash['LocalHost']
91
+ elsif (hash['LocalAddr'])
92
+ self.localhost = hash['LocalAddr']
93
+ else
94
+ self.localhost = '0.0.0.0'
95
+ end
96
+
97
+ if (hash['PeerPort'])
98
+ self.peerport = hash['PeerPort'].to_i
99
+ else
100
+ self.peerport = 0
101
+ end
102
+
103
+ if (hash['LocalPort'])
104
+ self.localport = hash['LocalPort'].to_i
105
+ else
106
+ self.localport = 0
107
+ end
108
+
109
+ if (hash['Bare'])
110
+ self.bare = hash['Bare']
111
+ else
112
+ self.bare = false
113
+ end
114
+
115
+ if (hash['SSL'] and hash['SSL'].to_s =~ /^(t|y|1)/i)
116
+ self.ssl = true
117
+ else
118
+ self.ssl = false
119
+ end
120
+
121
+ if hash['SSLContext']
122
+ self.sslctx = hash['SSLContext']
123
+ end
124
+
125
+ supported_ssl_versions = ['Auto', 'SSL2', 'SSL23', 'TLS1', 'SSL3', :Auto, :SSLv2, :SSLv3, :SSLv23, :TLSv1]
126
+ if (hash['SSLVersion'] and supported_ssl_versions.include? hash['SSLVersion'])
127
+ self.ssl_version = hash['SSLVersion']
128
+ end
129
+
130
+ supported_ssl_verifiers = %W{CLIENT_ONCE FAIL_IF_NO_PEER_CERT NONE PEER}
131
+ if (hash['SSLVerifyMode'] and supported_ssl_verifiers.include? hash['SSLVerifyMode'])
132
+ self.ssl_verify_mode = hash['SSLVerifyMode']
133
+ end
134
+
135
+ if hash['SSLCompression']
136
+ self.ssl_compression = hash['SSLCompression']
137
+ end
138
+
139
+ if (hash['SSLCipher'])
140
+ self.ssl_cipher = hash['SSLCipher']
141
+ end
142
+
143
+ if (hash['SSLCert'] and ::File.file?(hash['SSLCert']))
144
+ begin
145
+ self.ssl_cert = ::File.read(hash['SSLCert'])
146
+ rescue ::Exception => e
147
+ elog("Failed to read cert: #{e.class}: #{e}", LogSource)
148
+ end
149
+ end
150
+
151
+ if hash['Proxies']
152
+ self.proxies = hash['Proxies'].split('-').map{|a| a.strip}.map{|a| a.split(':').map{|b| b.strip}}
153
+ end
154
+
155
+ # The protocol this socket will be using
156
+ if (hash['Proto'])
157
+ self.proto = hash['Proto'].downcase
158
+ else
159
+ self.proto = 'tcp'
160
+ end
161
+
162
+ # Whether or not the socket should be a server
163
+ self.server = hash['Server'] || false
164
+
165
+ # The communication subsystem to use to create the socket
166
+ self.comm = hash['Comm']
167
+
168
+ # The context that was passed in, if any.
169
+ self.context = hash['Context'] || {}
170
+
171
+ # If no comm was supplied, try to use the comm that is best fit to
172
+ # handle the provided host based on the current routing table.
173
+ if( self.server )
174
+ if (self.comm == nil and self.localhost)
175
+ self.comm = Rex::Socket::SwitchBoard.best_comm(self.localhost)
176
+ end
177
+ else
178
+ if (self.comm == nil and self.peerhost)
179
+ self.comm = Rex::Socket::SwitchBoard.best_comm(self.peerhost)
180
+ end
181
+ end
182
+
183
+ # If we still haven't found a comm, we default to the local comm.
184
+ self.comm = Rex::Socket::Comm::Local if (self.comm == nil)
185
+
186
+ # If we are a UDP server, turn off the server flag as it was only set when
187
+ # creating the UDP socket in order to avail of the switch board above.
188
+ if( self.server and self.proto == 'udp' )
189
+ self.server = false
190
+ end
191
+
192
+ # The number of connection retries to make (client only)
193
+ if hash['Retries']
194
+ self.retries = hash['Retries'].to_i
195
+ else
196
+ self.retries = 0
197
+ end
198
+
199
+ # The number of seconds before a connect attempt times out (client only)
200
+ if hash['Timeout']
201
+ self.timeout = hash['Timeout'].to_i
202
+ else
203
+ self.timeout = 5
204
+ end
205
+
206
+ # Whether to force IPv6 addressing
207
+ self.v6 = hash['IPv6'] || false
208
+ end
209
+
210
+ ##
211
+ #
212
+ # Conditionals
213
+ #
214
+ ##
215
+
216
+ #
217
+ # Returns true if this represents parameters for a server.
218
+ #
219
+ def server?
220
+ return (server == true)
221
+ end
222
+
223
+ #
224
+ # Returns true if this represents parameters for a client.
225
+ #
226
+ def client?
227
+ return (server == false)
228
+ end
229
+
230
+ #
231
+ # Returns true if the protocol for the parameters is TCP.
232
+ #
233
+ def tcp?
234
+ return (proto == 'tcp')
235
+ end
236
+
237
+ #
238
+ # Returns true if the protocol for the parameters is UDP.
239
+ #
240
+ def udp?
241
+ return (proto == 'udp')
242
+ end
243
+
244
+ #
245
+ # Returns true if the protocol for the parameters is IP.
246
+ #
247
+ def ip?
248
+ return (proto == 'ip')
249
+ end
250
+
251
+ #
252
+ # Returns true if the socket is a bare socket that does not inherit from
253
+ # any extended Rex classes.
254
+ #
255
+ def bare?
256
+ return (bare == true)
257
+ end
258
+
259
+ #
260
+ # Returns true if SSL has been requested.
261
+ #
262
+ def ssl?
263
+ return ssl
264
+ end
265
+
266
+ #
267
+ # Returns true if IPv6 has been enabled
268
+ #
269
+ def v6?
270
+ return v6
271
+ end
272
+
273
+
274
+ ##
275
+ #
276
+ # Attributes
277
+ #
278
+ ##
279
+
280
+ # The remote host information, equivalent to the PeerHost parameter hash
281
+ # key.
282
+ # @return [String]
283
+ attr_accessor :peerhost
284
+
285
+ # The remote port. Equivalent to the PeerPort parameter hash key.
286
+ # @return [Fixnum]
287
+ attr_accessor :peerport
288
+
289
+ # The local host. Equivalent to the LocalHost parameter hash key.
290
+ # @return [String]
291
+ attr_accessor :localhost
292
+
293
+ # The local port. Equivalent to the LocalPort parameter hash key.
294
+ # @return [Fixnum]
295
+ attr_accessor :localport
296
+
297
+ # The protocol to to use, such as TCP. Equivalent to the Proto parameter
298
+ # hash key.
299
+ # @return [String]
300
+ attr_accessor :proto
301
+
302
+ # Whether or not this is a server. Equivalent to the Server parameter
303
+ # hash key.
304
+ # @return [Bool]
305
+ attr_accessor :server
306
+
307
+ # The {Comm} instance that should be used to create the underlying socket.
308
+ # @return [Comm]
309
+ attr_accessor :comm
310
+
311
+ # The context hash that was passed in to the structure. (default: {})
312
+ # @return [Hash]
313
+ attr_accessor :context
314
+
315
+ # The number of attempts that should be made.
316
+ # @return [Fixnum]
317
+ attr_accessor :retries
318
+
319
+ # The number of seconds before a connection attempt should time out.
320
+ # @return [Fixnum]
321
+ attr_accessor :timeout
322
+
323
+ # Whether or not this is a bare (non-extended) socket instance that should
324
+ # be created.
325
+ # @return [Bool]
326
+ attr_accessor :bare
327
+
328
+ # Whether or not SSL should be used to wrap the connection.
329
+ # @return [Bool]
330
+ attr_accessor :ssl
331
+
332
+ # Pre configured SSL Context to use
333
+ # @return [OpenSSL::SSL::SSLContext]
334
+ attr_accessor :sslctx
335
+
336
+ # What version of SSL to use (Auto, SSL2, SSL3, SSL23, TLS1)
337
+ # @return [String,Symbol]
338
+ attr_accessor :ssl_version
339
+
340
+ # What specific SSL Cipher(s) to use, may be a string containing the cipher
341
+ # name or an array of strings containing cipher names e.g.
342
+ # ["DHE-RSA-AES256-SHA", "DHE-DSS-AES256-SHA"]
343
+ # @return [String,Array]
344
+ attr_accessor :ssl_cipher
345
+
346
+ # The SSL certificate, in pem format, stored as a string. See
347
+ # {Rex::Socket::SslTcpServer#makessl}
348
+ # @return [String]
349
+ attr_accessor :ssl_cert
350
+
351
+ # Enables SSL/TLS-level compression
352
+ # @return [Bool]
353
+ attr_accessor :ssl_compression
354
+
355
+ #
356
+ # The SSL context verification mechanism
357
+ #
358
+ attr_accessor :ssl_verify_mode
359
+
360
+ #
361
+ # Whether we should use IPv6
362
+ # @return [Bool]
363
+ attr_accessor :v6
364
+
365
+
366
+ # List of proxies to use
367
+ # @return [String]
368
+ attr_accessor :proxies
369
+
370
+ alias peeraddr peerhost
371
+ alias localaddr localhost
372
+ end