rex-core 0.1.21 → 0.1.25

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1ab976e408acf491f30c2d5ec12fde516b6ceebf75257216a07997dccee92ba5
4
- data.tar.gz: 382f26dd0e86f8245bdbdde3462f5555080a6f85a03b76a7a164ab4b796c7672
3
+ metadata.gz: 92383c2b5e9cf999abfc198c12992d176cfdf262fbd782886ef1ea1a705f2fd6
4
+ data.tar.gz: 584ffd804e8c5b1d3b96c5cf90580553fb12513c958362d93238cf92545c7184
5
5
  SHA512:
6
- metadata.gz: 27ca06a5a3a339a079c2b177dbb034737e1836a2b9a14edfd48accc04912a803c8158eebc6f800425fbcbaccf86abfc22d2a7892cc4650e073927a758cf11c14
7
- data.tar.gz: a4b223838152b1eb302bc3ff52298b60d9ed25f5eb9d920eb6a526607d5490f4fdaa89f8135913c15b66cbce0cf54a6be5b263faf717d299000dcc368491b6fd
6
+ metadata.gz: fc7aa81e629107d66ceefdee7fcde2f7620fd95aff8bb2f163eacd31387835e84f123bdda4666b5e4c6a3390db5a9ddb4a55e8a15850c670ad0610c479ac2816
7
+ data.tar.gz: 5d4b2fd53ec1cb320a5d503d97ff4f478f330368f98c3230cc1918edf1d07a9f950c2bef7d0210074e52ce1ee16097f3e32703b4476cd16d7d3edb651c26e35e
checksums.yaml.gz.sig CHANGED
Binary file
@@ -0,0 +1,45 @@
1
+ name: Verify
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - '*'
7
+ pull_request:
8
+ branches:
9
+ - '*'
10
+
11
+ jobs:
12
+ test:
13
+ runs-on: ubuntu-18.04
14
+ timeout-minutes: 40
15
+
16
+ strategy:
17
+ fail-fast: true
18
+ matrix:
19
+ ruby:
20
+ - 2.6
21
+ - 2.7
22
+ - 3.0
23
+ test_cmd:
24
+ - bundle exec rspec
25
+
26
+ env:
27
+ RAILS_ENV: test
28
+
29
+ name: Ruby ${{ matrix.ruby }} - ${{ matrix.test_cmd }}
30
+ steps:
31
+ - name: Checkout code
32
+ uses: actions/checkout@v2
33
+
34
+ - name: Setup Ruby
35
+ uses: ruby/setup-ruby@v1
36
+ with:
37
+ ruby-version: ${{ matrix.ruby }}
38
+ bundler-cache: true
39
+
40
+ - name: ${{ matrix.test_cmd }}
41
+ run: |
42
+ echo "${CMD}"
43
+ bash -c "${CMD}"
44
+ env:
45
+ CMD: ${{ matrix.test_cmd }}
@@ -1,5 +1,5 @@
1
1
  module Rex
2
2
  module Core
3
- VERSION = "0.1.21"
3
+ VERSION = "0.1.25"
4
4
  end
5
5
  end
@@ -53,6 +53,9 @@ module Rex
53
53
  #
54
54
  def cleanup_abstraction
55
55
  lsock.close if lsock and !lsock.closed?
56
+
57
+ monitor_thread.join if monitor_thread&.alive?
58
+
56
59
  rsock.close if rsock and !rsock.closed?
57
60
 
58
61
  self.lsock = nil
@@ -111,19 +114,36 @@ module Rex
111
114
  #
112
115
  attr_reader :rsock
113
116
 
117
+ module MonitoredRSock
118
+ def close
119
+ @close_requested = true
120
+ @monitor_thread.join
121
+ nil
122
+ end
123
+
124
+ def sysclose
125
+ self.class.instance_method(:close).bind(self).call
126
+ end
127
+
128
+ attr_reader :close_requested
129
+ attr_writer :monitor_thread
130
+ end
131
+
114
132
  protected
115
133
 
116
134
  def monitor_rsock(threadname = 'SocketMonitorRemote')
117
- self.monitor_thread = Rex::ThreadFactory.spawn(threadname, false) do
135
+ rsock.extend(MonitoredRSock)
136
+ rsock.monitor_thread = self.monitor_thread = Rex::ThreadFactory.spawn(threadname, false) do
118
137
  loop do
119
- closed = false
120
- buf = nil
138
+ closed = rsock.nil? || rsock.close_requested
121
139
 
122
- unless rsock
123
- wlog('monitor_rsock: the remote socket is nil, exiting loop')
140
+ if closed
141
+ wlog('monitor_rsock: the remote socket has been closed, exiting loop')
124
142
  break
125
143
  end
126
144
 
145
+ buf = nil
146
+
127
147
  begin
128
148
  s = Rex::ThreadSafe.select([rsock], nil, nil, 0.2)
129
149
  next if s.nil? || s[0].nil?
@@ -159,10 +179,10 @@ module Rex
159
179
  # Using syswrite() breaks SSL streams.
160
180
  sent = write(data)
161
181
 
162
- # sf: Only remove the data off the queue is write was successfull.
163
- # This way we naturally perform a resend if a failure occured.
182
+ # sf: Only remove the data off the queue is write was successful.
183
+ # This way we naturally perform a resend if a failure occurred.
164
184
  # Catches an edge case with meterpreter TCP channels where remote send
165
- # failes gracefully and a resend is required.
185
+ # fails gracefully and a resend is required.
166
186
  if sent.nil?
167
187
  closed = true
168
188
  wlog('monitor_rsock: failed writing, socket must be dead')
@@ -182,14 +202,18 @@ module Rex
182
202
 
183
203
  begin
184
204
  close_write if respond_to?('close_write')
185
- rescue IOError
205
+ rescue StandardError
186
206
  end
207
+
187
208
  break
188
209
  end
210
+
211
+ rsock.sysclose
189
212
  end
190
213
  end
191
214
 
192
215
  attr_accessor :monitor_thread
193
216
  attr_writer :lsock, :rsock
194
217
  end
195
- end; end
218
+ end
219
+ end
@@ -1,228 +1,208 @@
1
1
  # -*- coding: binary -*-
2
- require 'thread'
3
2
 
4
3
  module Rex
5
- module IO
6
-
7
- ###
8
- #
9
- # This mixin provides the framework and interface for implementing a streaming
10
- # server that can listen for and accept stream client connections. Stream
11
- # servers extend this class and are required to implement the following
12
- # methods:
13
- #
14
- # accept
15
- # fd
16
- #
17
- ###
18
- module StreamServer
19
-
20
- ##
21
- #
22
- # Abstract methods
23
- #
24
- ##
25
-
26
- ##
27
- #
28
- # Default server monitoring and client management implementation follows
29
- # below.
30
- #
31
- ##
32
-
33
- #
34
- # This callback is notified when a client connects.
35
- #
36
- def on_client_connect(client)
37
- if (on_client_connect_proc)
38
- on_client_connect_proc.call(client)
39
- end
40
- end
41
-
42
- #
43
- # This callback is notified when a client connection has data that needs to
44
- # be processed.
45
- #
46
- def on_client_data(client)
47
- if (on_client_data_proc)
48
- on_client_data_proc.call(client)
49
- end
50
- end
51
-
52
- #
53
- # This callback is notified when a client connection has closed.
54
- #
55
- def on_client_close(client)
56
- if (on_client_close_proc)
57
- on_client_close_proc.call(client)
58
- end
59
- end
60
-
61
- #
62
- # Start monitoring the listener socket for connections and keep track of
63
- # all client connections.
64
- #
65
- def start
66
- self.clients = []
67
- self.client_waiter = ::Queue.new
68
-
69
- self.listener_thread = Rex::ThreadFactory.spawn("StreamServerListener", false) {
70
- monitor_listener
71
- }
72
- self.clients_thread = Rex::ThreadFactory.spawn("StreamServerClientMonitor", false) {
73
- monitor_clients
74
- }
75
- end
76
-
77
- #
78
- # Terminates the listener monitoring threads and closes all active clients.
79
- #
80
- def stop
81
- self.listener_thread.kill
82
- self.clients_thread.kill
83
-
84
- self.clients.each { |cli|
85
- close_client(cli)
86
- }
87
- end
4
+ module IO
5
+ ###
6
+ #
7
+ # This mixin provides the framework and interface for implementing a streaming
8
+ # server that can listen for and accept stream client connections. Stream
9
+ # servers extend this class and are required to implement the following
10
+ # methods:
11
+ #
12
+ # accept
13
+ # fd
14
+ #
15
+ ###
16
+ module StreamServer
17
+ ##
18
+ #
19
+ # Abstract methods
20
+ #
21
+ ##
22
+
23
+ ##
24
+ #
25
+ # Default server monitoring and client management implementation follows
26
+ # below.
27
+ #
28
+ ##
29
+
30
+ #
31
+ # This callback is notified when a client connects.
32
+ #
33
+ def on_client_connect(client)
34
+ on_client_connect_proc.call(client) if on_client_connect_proc
35
+ end
88
36
 
89
- #
90
- # This method closes a client connection and cleans up the resources
91
- # associated with it.
92
- #
93
- def close_client(client)
94
- if (client)
95
- detach_client(client)
96
-
97
- begin
98
- client.close
99
- rescue IOError
37
+ #
38
+ # This callback is notified when a client connection has data that needs to
39
+ # be processed.
40
+ #
41
+ def on_client_data(client)
42
+ on_client_data_proc.call(client) if on_client_data_proc
100
43
  end
101
- end
102
- end
103
44
 
104
- #
105
- # Detach a client. You are now responsible for it, not us
106
- #
107
- def detach_client(client)
108
- self.clients.delete(client)
109
- end
45
+ #
46
+ # This callback is notified when a client connection has closed.
47
+ #
48
+ def on_client_close(client)
49
+ on_client_close_proc.call(client) if on_client_close_proc
50
+ end
110
51
 
111
- #
112
- # This method waits on the server listener thread
113
- #
114
- def wait
115
- self.listener_thread.join if self.listener_thread
116
- end
52
+ #
53
+ # Start monitoring the listener socket for connections and keep track of
54
+ # all client connections.
55
+ #
56
+ def start
57
+ self.clients = []
58
+ self.client_waiter = ::Queue.new
117
59
 
118
- ##
119
- #
120
- # Callback procedures.
121
- #
122
- ##
123
-
124
- #
125
- # This callback procedure can be set and will be called when new clients
126
- # connect.
127
- #
128
- attr_accessor :on_client_connect_proc
129
- #
130
- # This callback procedure can be set and will be called when clients
131
- # have data to be processed.
132
- #
133
- attr_accessor :on_client_data_proc
134
- #
135
- # This callback procedure can be set and will be called when a client
136
- # disconnects from the server.
137
- #
138
- attr_accessor :on_client_close_proc
139
-
140
- attr_accessor :clients # :nodoc:
141
- attr_accessor :listener_thread, :clients_thread # :nodoc:
142
- attr_accessor :client_waiter
143
-
144
- protected
145
-
146
- #
147
- # This method monitors the listener socket for new connections and calls
148
- # the +on_client_connect+ callback routine.
149
- #
150
- def monitor_listener
151
-
152
- while true
153
- begin
154
- cli = accept
155
- if not cli
156
- elog("The accept() returned nil in stream server listener monitor: #{fd.inspect}")
157
- ::IO.select(nil, nil, nil, 0.10)
158
- next
60
+ self.listener_thread = Rex::ThreadFactory.spawn('StreamServerListener', false) do
61
+ monitor_listener
159
62
  end
63
+ self.clients_thread = Rex::ThreadFactory.spawn('StreamServerClientMonitor', false) do
64
+ monitor_clients
65
+ end
66
+ end
160
67
 
161
- # Append to the list of clients
162
- self.clients << cli
68
+ #
69
+ # Terminates the listener monitoring threads and closes all active clients.
70
+ #
71
+ def stop
72
+ listener_thread.kill
73
+ clients_thread.kill
163
74
 
164
- # Initialize the connection processing
165
- on_client_connect(cli)
75
+ clients.each do |cli|
76
+ close_client(cli)
77
+ end
78
+ end
166
79
 
167
- # Notify the client monitor
168
- self.client_waiter.push(cli)
80
+ #
81
+ # This method closes a client connection and cleans up the resources
82
+ # associated with it.
83
+ #
84
+ def close_client(client)
85
+ if client
86
+ detach_client(client)
87
+
88
+ begin
89
+ client.close
90
+ rescue IOError
91
+ end
92
+ end
93
+ end
169
94
 
170
- # Skip exceptions caused by accept() [ SSL ]
171
- rescue ::EOFError, ::Errno::ECONNRESET, ::Errno::ENOTCONN, ::Errno::ECONNABORTED
172
- rescue ::Interrupt
173
- raise $!
174
- rescue ::Exception
175
- elog("Error in stream server server monitor: #{$!}")
176
- rlog(ExceptionCallStack)
177
- break
95
+ #
96
+ # Detach a client. You are now responsible for it, not us
97
+ #
98
+ def detach_client(client)
99
+ clients.delete(client)
178
100
  end
179
- end
180
- end
181
101
 
182
- #
183
- # This method monitors client connections for data and calls the
184
- # +on_client_data+ routine when new data arrives.
185
- #
186
- def monitor_clients
187
- begin
188
-
189
- # Wait for a notify if our client list is empty
190
- if (clients.length == 0)
191
- self.client_waiter.pop
192
- next
102
+ #
103
+ # This method waits on the server listener thread
104
+ #
105
+ def wait
106
+ listener_thread.join if listener_thread
193
107
  end
194
108
 
195
- sd = Rex::ThreadSafe.select(clients, nil, nil, nil)
109
+ ##
110
+ #
111
+ # Callback procedures.
112
+ #
113
+ ##
114
+
115
+ #
116
+ # This callback procedure can be set and will be called when new clients
117
+ # connect.
118
+ #
119
+ attr_accessor :on_client_connect_proc
120
+ #
121
+ # This callback procedure can be set and will be called when clients
122
+ # have data to be processed.
123
+ #
124
+ attr_accessor :on_client_data_proc
125
+ #
126
+ # This callback procedure can be set and will be called when a client
127
+ # disconnects from the server.
128
+ #
129
+ attr_accessor :on_client_close_proc
130
+
131
+ attr_accessor :clients, :listener_thread, :clients_thread, :client_waiter # :nodoc: # :nodoc:
132
+
133
+ protected
134
+
135
+ #
136
+ # This method monitors the listener socket for new connections and calls
137
+ # the +on_client_connect+ callback routine.
138
+ #
139
+ def monitor_listener
140
+ while true
141
+ begin
142
+ cli = accept
143
+ unless cli
144
+ elog('The accept() returned nil in stream server listener monitor')
145
+ ::IO.select(nil, nil, nil, 0.10)
146
+ next
147
+ end
148
+
149
+ # Append to the list of clients
150
+ clients << cli
151
+
152
+ # Initialize the connection processing
153
+ on_client_connect(cli)
154
+
155
+ # Notify the client monitor
156
+ client_waiter.push(cli)
157
+
158
+ # Skip exceptions caused by accept() [ SSL ]
159
+ rescue ::EOFError, ::Errno::ECONNRESET, ::Errno::ENOTCONN, ::Errno::ECONNABORTED
160
+ rescue ::Interrupt
161
+ raise $!
162
+ rescue ::Exception
163
+ elog("Error in stream server server monitor: #{$!}")
164
+ rlog(ExceptionCallStack)
165
+ break
166
+ end
167
+ end
168
+ end
196
169
 
197
- sd[0].each { |cfd|
170
+ #
171
+ # This method monitors client connections for data and calls the
172
+ # +on_client_data+ routine when new data arrives.
173
+ #
174
+ def monitor_clients
198
175
  begin
199
- on_client_data(cfd) if clients.include? cfd
200
- rescue ::EOFError, ::Errno::ECONNRESET, ::Errno::ENOTCONN, ::Errno::ECONNABORTED
201
- on_client_close(cfd)
202
- close_client(cfd)
176
+ # Wait for a notify if our client list is empty
177
+ if clients.length == 0
178
+ client_waiter.pop
179
+ next
180
+ end
181
+
182
+ sd = Rex::ThreadSafe.select(clients, nil, nil, nil)
183
+
184
+ sd[0].each do |cfd|
185
+ on_client_data(cfd) if clients.include? cfd
186
+ rescue ::EOFError, ::Errno::ECONNRESET, ::Errno::ENOTCONN, ::Errno::ECONNABORTED
187
+ on_client_close(cfd)
188
+ close_client(cfd)
189
+ rescue ::Interrupt
190
+ raise $!
191
+ rescue ::Exception
192
+ close_client(cfd)
193
+ elog("Error in stream server client monitor: #{$!}")
194
+ rlog(ExceptionCallStack)
195
+ end
196
+ rescue ::Rex::StreamClosedError => e
197
+ # Remove the closed stream from the list
198
+ detach_client(e.stream)
203
199
  rescue ::Interrupt
204
200
  raise $!
205
201
  rescue ::Exception
206
- close_client(cfd)
207
202
  elog("Error in stream server client monitor: #{$!}")
208
203
  rlog(ExceptionCallStack)
209
-
210
- end
211
- }
212
-
213
- rescue ::Rex::StreamClosedError => e
214
- # Remove the closed stream from the list
215
- detach_client(e.stream)
216
- rescue ::Interrupt
217
- raise $!
218
- rescue ::Exception
219
- elog("Error in stream server client monitor: #{$!}")
220
- rlog(ExceptionCallStack)
221
- end while true
204
+ end while true
205
+ end
206
+ end
222
207
  end
223
-
224
208
  end
225
-
226
- end
227
- end
228
-
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rex-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.21
4
+ version: 0.1.25
5
5
  platform: ruby
6
6
  authors:
7
7
  - Metasploit Hackers
@@ -93,7 +93,7 @@ cert_chain:
93
93
  EknWpNgVhohbot1lfVAMmIhdtOVaRVcQQixWPwprDj/ydB8ryDMDosIMcw+fkoXU
94
94
  9GJsSaSRRYQ9UUkVL27b64okU8D48m8=
95
95
  -----END CERTIFICATE-----
96
- date: 2022-01-25 00:00:00.000000000 Z
96
+ date: 2022-01-26 00:00:00.000000000 Z
97
97
  dependencies:
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: rake
@@ -132,6 +132,7 @@ executables: []
132
132
  extensions: []
133
133
  extra_rdoc_files: []
134
134
  files:
135
+ - ".github/workflows/verify.yml"
135
136
  - ".gitignore"
136
137
  - ".rspec"
137
138
  - ".travis.yml"
metadata.gz.sig CHANGED
Binary file