rex-core 0.1.1 → 0.1.2

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.
@@ -0,0 +1,205 @@
1
+ # -*- coding: binary -*-
2
+
3
+ require 'socket'
4
+ require 'fcntl'
5
+
6
+ module Rex
7
+ module IO
8
+
9
+ ###
10
+ #
11
+ # This class provides an abstraction to a stream based
12
+ # connection through the use of a streaming socketpair.
13
+ #
14
+ ###
15
+ module SocketAbstraction
16
+
17
+ ###
18
+ #
19
+ # Extension information for required Stream interface.
20
+ #
21
+ ###
22
+ module Ext
23
+
24
+ #
25
+ # Initializes peer information.
26
+ #
27
+ def initinfo(peer,local)
28
+ @peer = peer
29
+ @local = local
30
+ end
31
+
32
+ #
33
+ # Symbolic peer information.
34
+ #
35
+ def peerinfo
36
+ (@peer || "Remote Pipe")
37
+ end
38
+
39
+ #
40
+ # Symbolic local information.
41
+ #
42
+ def localinfo
43
+ (@local || "Local Pipe")
44
+ end
45
+ end
46
+
47
+ #
48
+ # Override this method to init the abstraction
49
+ #
50
+ def initialize_abstraction
51
+ self.lsock, self.rsock = Rex::Compat.pipe
52
+ end
53
+
54
+ #
55
+ # This method cleans up the abstraction layer.
56
+ #
57
+ def cleanup_abstraction
58
+ self.lsock.close if (self.lsock and !self.lsock.closed?)
59
+ self.rsock.close if (self.rsock and !self.rsock.closed?)
60
+
61
+ self.lsock = nil
62
+ self.rsock = nil
63
+ end
64
+
65
+ #
66
+ # Low-level write to the local side.
67
+ #
68
+ def syswrite(buffer)
69
+ lsock.syswrite(buffer)
70
+ end
71
+
72
+ #
73
+ # Low-level read from the local side.
74
+ #
75
+ def sysread(length)
76
+ lsock.sysread(length)
77
+ end
78
+
79
+ #
80
+ # Shuts down the local side of the stream abstraction.
81
+ #
82
+ def shutdown(how)
83
+ lsock.shutdown(how)
84
+ end
85
+
86
+ #
87
+ # Closes both sides of the stream abstraction.
88
+ #
89
+ def close
90
+ cleanup_abstraction
91
+ super
92
+ end
93
+
94
+ #
95
+ # Symbolic peer information.
96
+ #
97
+ def peerinfo
98
+ "Remote-side of Pipe"
99
+ end
100
+
101
+ #
102
+ # Symbolic local information.
103
+ #
104
+ def localinfo
105
+ "Local-side of Pipe"
106
+ end
107
+
108
+ #
109
+ # The left side of the stream.
110
+ #
111
+ attr_reader :lsock
112
+ #
113
+ # The right side of the stream.
114
+ #
115
+ attr_reader :rsock
116
+
117
+ protected
118
+
119
+ def monitor_rsock(threadname = "SocketMonitorRemote")
120
+ self.monitor_thread = Rex::ThreadFactory.spawn(threadname, false) {
121
+ loop do
122
+ closed = false
123
+ buf = nil
124
+
125
+ if not self.rsock
126
+ wlog("monitor_rsock: the remote socket is nil, exiting loop")
127
+ break
128
+ end
129
+
130
+ begin
131
+ s = Rex::ThreadSafe.select( [ self.rsock ], nil, nil, 0.2 )
132
+ if( s == nil || s[0] == nil )
133
+ next
134
+ end
135
+ rescue Exception => e
136
+ wlog("monitor_rsock: exception during select: #{e.class} #{e}")
137
+ closed = true
138
+ end
139
+
140
+ if( closed == false )
141
+ begin
142
+ buf = self.rsock.sysread( 32768 )
143
+ if buf == nil
144
+ closed = true
145
+ wlog("monitor_rsock: closed remote socket due to nil read")
146
+ end
147
+ rescue EOFError => e
148
+ closed = true
149
+ dlog("monitor_rsock: EOF in rsock")
150
+ rescue ::Exception => e
151
+ closed = true
152
+ wlog("monitor_rsock: exception during read: #{e.class} #{e}")
153
+ end
154
+ end
155
+
156
+ if( closed == false )
157
+ total_sent = 0
158
+ total_length = buf.length
159
+ while( total_sent < total_length )
160
+ begin
161
+ data = buf[total_sent, buf.length]
162
+
163
+ # Note that this must be write() NOT syswrite() or put() or anything like it.
164
+ # Using syswrite() breaks SSL streams.
165
+ sent = self.write( data )
166
+
167
+ # sf: Only remove the data off the queue is write was successfull.
168
+ # This way we naturally perform a resend if a failure occured.
169
+ # Catches an edge case with meterpreter TCP channels where remote send
170
+ # failes gracefully and a resend is required.
171
+ if (sent.nil?)
172
+ closed = true
173
+ wlog("monitor_rsock: failed writing, socket must be dead")
174
+ break
175
+ elsif (sent > 0)
176
+ total_sent += sent
177
+ end
178
+ rescue ::IOError, ::EOFError => e
179
+ closed = true
180
+ wlog("monitor_rsock: exception during write: #{e.class} #{e}")
181
+ break
182
+ end
183
+ end
184
+ end
185
+
186
+ if( closed )
187
+ begin
188
+ self.close_write if self.respond_to?('close_write')
189
+ rescue IOError
190
+ end
191
+ break
192
+ end
193
+ end
194
+ }
195
+ end
196
+
197
+ protected
198
+ attr_accessor :monitor_thread
199
+ attr_writer :lsock
200
+ attr_writer :rsock
201
+
202
+ end
203
+
204
+ end; end
205
+
@@ -0,0 +1,312 @@
1
+ # -*- coding: binary -*-
2
+ require 'rex/sync/thread_safe'
3
+
4
+ module Rex
5
+ module IO
6
+
7
+ ###
8
+ #
9
+ # This mixin is an abstract representation of a streaming connection. Streams
10
+ # extend classes that must implement the following methods:
11
+ #
12
+ # syswrite(buffer)
13
+ # sysread(length)
14
+ # shutdown(how)
15
+ # close
16
+ # peerinfo
17
+ # localinfo
18
+ #
19
+ ###
20
+ module Stream
21
+
22
+ ##
23
+ #
24
+ # Abstract methods
25
+ #
26
+ ##
27
+
28
+ #
29
+ # This method writes the supplied buffer to the stream. This method
30
+ # intelligent reduces the size of supplied buffers so that ruby doesn't get
31
+ # into a potential global thread blocking state when used on blocking
32
+ # sockets. That is, this method will send the supplied buffer in chunks
33
+ # of, at most, 32768 bytes.
34
+ #
35
+ def write(buf, opts = {})
36
+ total_sent = 0
37
+ total_length = buf.length
38
+ block_size = 32768
39
+
40
+ begin
41
+ while( total_sent < total_length )
42
+ s = Rex::ThreadSafe.select( nil, [ fd ], nil, 0.2 )
43
+ if( s == nil || s[0] == nil )
44
+ next
45
+ end
46
+ data = buf[total_sent, block_size]
47
+ sent = fd.write_nonblock( data )
48
+ if sent > 0
49
+ total_sent += sent
50
+ end
51
+ end
52
+ rescue ::Errno::EAGAIN, ::Errno::EWOULDBLOCK
53
+ # Sleep for a half a second, or until we can write again
54
+ Rex::ThreadSafe.select( nil, [ fd ], nil, 0.5 )
55
+ # Decrement the block size to handle full sendQs better
56
+ block_size = 1024
57
+ # Try to write the data again
58
+ retry
59
+ rescue ::IOError, ::Errno::EPIPE
60
+ return nil
61
+ end
62
+
63
+ total_sent
64
+ end
65
+
66
+ #
67
+ # This method reads data of the supplied length from the stream.
68
+ #
69
+ def read(length = nil, opts = {})
70
+
71
+ begin
72
+ return fd.read_nonblock( length )
73
+ rescue ::Errno::EAGAIN, ::Errno::EWOULDBLOCK
74
+ # Sleep for a half a second, or until we can read again
75
+ Rex::ThreadSafe.select( [ fd ], nil, nil, 0.5 )
76
+ # Decrement the block size to handle full sendQs better
77
+ retry
78
+ rescue ::IOError, ::Errno::EPIPE
79
+ return nil
80
+ end
81
+ end
82
+
83
+ #
84
+ # Polls the stream to see if there is any read data available. Returns
85
+ # true if data is available for reading, otherwise false is returned.
86
+ #
87
+ def has_read_data?(timeout = nil)
88
+
89
+ # Allow a timeout of "0" that waits almost indefinitely for input, this
90
+ # mimics the behavior of Rex::ThreadSafe.select() and fixes some corner
91
+ # cases of unintentional no-wait timeouts.
92
+ timeout = 3600 if (timeout and timeout == 0)
93
+
94
+ begin
95
+ if ((rv = ::IO.select([ fd ], nil, nil, timeout)) and
96
+ (rv[0]) and
97
+ (rv[0][0] == fd))
98
+ true
99
+ else
100
+ false
101
+ end
102
+ rescue ::Errno::EBADF, ::Errno::ENOTSOCK
103
+ raise ::EOFError
104
+ rescue StreamClosedError, ::IOError, ::EOFError, ::Errno::EPIPE
105
+ # Return false if the socket is dead
106
+ return false
107
+ end
108
+ end
109
+
110
+ #
111
+ # This method returns the selectable file descriptor, or self by default.
112
+ #
113
+ def fd
114
+ self
115
+ end
116
+
117
+ ##
118
+ #
119
+ # Common methods
120
+ #
121
+ ##
122
+
123
+ #
124
+ # This method writes the supplied buffer to the stream by calling the write
125
+ # routine.
126
+ #
127
+ def <<(buf)
128
+ return write(buf.to_s)
129
+ end
130
+
131
+ #
132
+ # This method calls get_once() to read pending data from the socket
133
+ #
134
+ def >>
135
+ get_once
136
+ end
137
+
138
+ #
139
+ # This method writes to the stream, optionally timing out after a period of
140
+ # time.
141
+ #
142
+ def timed_write(buf, wait = def_write_timeout, opts = {})
143
+ if (wait and wait > 0)
144
+ Timeout.timeout(wait) {
145
+ return write(buf, opts)
146
+ }
147
+ else
148
+ return write(buf, opts)
149
+ end
150
+ end
151
+
152
+ #
153
+ # This method reads from the stream, optionally timing out after a period
154
+ # of time.
155
+ #
156
+ def timed_read(length = nil, wait = def_read_timeout, opts = {})
157
+ if (wait and wait > 0)
158
+ Timeout.timeout(wait) {
159
+ return read(length, opts)
160
+ }
161
+ else
162
+ return read(length, opts)
163
+ end
164
+ end
165
+
166
+ #
167
+ # This method writes the full contents of the supplied buffer, optionally
168
+ # with a timeout.
169
+ #
170
+ def put(buf, opts = {})
171
+ return 0 if (buf == nil or buf.length == 0)
172
+
173
+ send_len = buf.length
174
+ send_idx = 0
175
+ wait = opts['Timeout'] || 0
176
+
177
+ # Keep writing until our send length drops to zero
178
+ while (send_idx < send_len)
179
+ curr_len = timed_write(buf[send_idx, buf.length-send_idx], wait, opts)
180
+
181
+ # If the write operation failed due to an IOError, then we fail.
182
+ return buf.length - send_len if (curr_len == nil)
183
+
184
+ send_len -= curr_len
185
+ send_idx += curr_len
186
+ end
187
+
188
+ return buf.length - send_len
189
+ end
190
+
191
+
192
+ #
193
+ # This method emulates the behavior of Pex::Socket::Recv in MSF2
194
+ #
195
+ def get_once(length = -1, timeout = def_read_timeout)
196
+
197
+ if (has_read_data?(timeout) == false)
198
+ return nil
199
+ end
200
+
201
+ bsize = (length == -1) ? def_block_size : length
202
+ data = read(bsize)
203
+ raise EOFError if data.nil?
204
+ data
205
+ end
206
+
207
+ #
208
+ # This method reads as much data as it can from the wire given a maximum
209
+ # timeout.
210
+ #
211
+ def get(timeout = nil, ltimeout = def_read_loop_timeout, opts = {})
212
+ # For those people who are used to being able to use a negative timeout!
213
+ if (timeout and timeout.to_i < 0)
214
+ timeout = nil
215
+ end
216
+
217
+ # No data in the first place? bust.
218
+ if (has_read_data?(timeout) == false)
219
+ return nil
220
+ end
221
+
222
+ buf = ""
223
+ lps = 0
224
+ eof = false
225
+
226
+ # Keep looping until there is no more data to be gotten..
227
+ while (has_read_data?(ltimeout) == true)
228
+ # Catch EOF errors so that we can handle them properly.
229
+ begin
230
+ temp = read(def_block_size)
231
+ rescue EOFError
232
+ eof = true
233
+ end
234
+
235
+ # If we read zero bytes and we had data, then we've hit EOF
236
+ if (temp and temp.length == 0)
237
+ eof = true
238
+ end
239
+
240
+ # If we reached EOF and there are no bytes in the buffer we've been
241
+ # reading into, then throw an EOF error.
242
+ if (eof)
243
+ # If we've already read at least some data, then it's time to
244
+ # break out and let it be processed before throwing an EOFError.
245
+ if (buf.length > 0)
246
+ break
247
+ else
248
+ raise EOFError
249
+ end
250
+ end
251
+
252
+ break if (temp == nil or temp.empty? == true)
253
+
254
+ buf += temp
255
+ lps += 1
256
+
257
+ break if (lps >= def_max_loops)
258
+ end
259
+
260
+ # Return the entire buffer we read in
261
+ return buf
262
+ end
263
+
264
+ ##
265
+ #
266
+ # Defaults
267
+ #
268
+ ##
269
+
270
+ #
271
+ # The default number of seconds to wait for a write operation to timeout.
272
+ #
273
+ def def_write_timeout
274
+ 10
275
+ end
276
+
277
+ #
278
+ # The default number of seconds to wait for a read operation to timeout.
279
+ #
280
+ def def_read_timeout
281
+ 10
282
+ end
283
+
284
+ #
285
+ # The default number of seconds to wait while in a read loop after read
286
+ # data has been found.
287
+ #
288
+ def def_read_loop_timeout
289
+ 0.1
290
+ end
291
+
292
+ #
293
+ # The maximum number of read loops to perform before returning to the
294
+ # caller.
295
+ #
296
+ def def_max_loops
297
+ 1024
298
+ end
299
+
300
+ #
301
+ # The default block size to read in chunks from the wire.
302
+ #
303
+ def def_block_size
304
+ 16384
305
+ end
306
+
307
+ protected
308
+
309
+ end
310
+
311
+ end end
312
+