metasploit-aggregator 0.1.0 → 0.1.1

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
  SHA1:
3
- metadata.gz: a9372e340df896a27d4b2f7f78483a985d47a4c3
4
- data.tar.gz: 38f3826e72c3e64d52e3221bda925ed6acf3d1cb
3
+ metadata.gz: aac104842b24e3ca148b53fec7496fdd91f05cbe
4
+ data.tar.gz: fe6729af2bc28c2a0a3d2d27e41b55501cff5bb6
5
5
  SHA512:
6
- metadata.gz: 460b198d3544822741d05bf0a9d83a1118dc69776078264bd885c2a283f41f3abe74f3f46a89775ba956103d61592c9931cde027fc84db6e4f8f2a51f5fa5a7e
7
- data.tar.gz: 3a86873da6b43255e30ce5c0d7fa5221ee76ea12dbfc78ed59eb443242410fcebcd2b2417367e1533a7dbe6391cfc725eefe2adb54fd1326c15d8f4eb6a5abe5
6
+ metadata.gz: 7bdd018ad0bdae6925db322e986eced83c1a904f9ba09671b715496271b7d6642a671b9abdcc59626249751579dd94bc966cefac6490a803424f40e21684c822
7
+ data.tar.gz: 321958012678ee3f900c9f2675bcbe721571d3def92906b136a1cdfea68ec96552a1d7953b2e1f0d7c7985f3f3f45a6cc36c72f7efc7ee2a21471ada2615f8bc
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/bin/msfaggregator CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'bundler/setup'
4
- require 'msf/aggregator'
5
- require 'msf/aggregator/cable'
6
- require 'msf/aggregator/logger'
4
+ require 'metasploit/aggregator'
5
+ require 'metasploit/aggregator/cable'
6
+ require 'metasploit/aggregator/logger'
7
7
 
8
8
  admin_host = '127.0.0.1'
9
9
  admin_port = 2447
@@ -13,8 +13,8 @@ remote_console = '127.0.0.1'
13
13
  # cert_string = File.new(cert_file).read
14
14
  cert_string = nil
15
15
 
16
- # server = Msf::Aggregator::Server.new('127.0.0.1', 1337)
17
- server = Msf::Aggregator::MsgPackServer.new(admin_host, admin_port)
16
+ # server = Metasploit::Aggregator::Server.new('127.0.0.1', 1337)
17
+ server = Metasploit::Aggregator::MsgPackServer.new(admin_host, admin_port)
18
18
  server.start
19
19
  Logger.log "Starting administration service on #{admin_host}:#{admin_port}"
20
20
 
@@ -3,14 +3,16 @@ require 'openssl'
3
3
  require 'thread'
4
4
  require 'msgpack'
5
5
  require 'msgpack/rpc'
6
+ require 'securerandom'
6
7
 
7
- require 'msf/aggregator/version'
8
- require 'msf/aggregator/cable'
9
- require 'msf/aggregator/connection_manager'
10
- require 'msf/aggregator/https_forwarder'
11
- require 'msf/aggregator/logger'
8
+ require 'metasploit/aggregator/version'
9
+ require 'metasploit/aggregator/cable'
10
+ require 'metasploit/aggregator/connection_manager'
11
+ require 'metasploit/aggregator/https_forwarder'
12
+ require 'metasploit/aggregator/http'
13
+ require 'metasploit/aggregator/logger'
12
14
 
13
- module Msf
15
+ module Metasploit
14
16
  module Aggregator
15
17
 
16
18
  class Service
@@ -31,7 +33,7 @@ module Msf
31
33
  # sets forwarding for a specific session to promote
32
34
  # that session for local use, obtained sessions are
33
35
  # not reported in getSessions
34
- def obtain_session(payload, lhost, lport)
36
+ def obtain_session(payload, uuid)
35
37
  # index for impl
36
38
  end
37
39
 
@@ -51,7 +53,11 @@ module Msf
51
53
  # index for impl
52
54
  end
53
55
 
54
- def register_default(lhost, lport, payload_list)
56
+ def register_default(uuid, payload_list)
57
+ # index for impl
58
+ end
59
+
60
+ def default
55
61
  # index for impl
56
62
  end
57
63
 
@@ -60,9 +66,15 @@ module Msf
60
66
  def available_addresses
61
67
  # index for impl
62
68
  end
69
+
70
+ # register the object to pass request from cables to
71
+ def register_response_channel(requester)
72
+
73
+ end
63
74
  end
64
75
 
65
76
  class ServerProxy < Service
77
+ attr_reader :uuid
66
78
  @host = @port = @socket = nil
67
79
  @response_queue = []
68
80
 
@@ -70,6 +82,7 @@ module Msf
70
82
  @host = host
71
83
  @port = port
72
84
  @client = MessagePack::RPC::Client.new(@host, @port)
85
+ @uuid = SecureRandom.uuid
73
86
  end
74
87
 
75
88
  def available?
@@ -91,8 +104,8 @@ module Msf
91
104
  end
92
105
 
93
106
 
94
- def obtain_session(payload, lhost, lport)
95
- @client.call(:obtain_session, payload, lhost, lport)
107
+ def obtain_session(payload, uuid)
108
+ @client.call(:obtain_session, payload, uuid)
96
109
  rescue MessagePack::RPC::TimeoutError => e
97
110
  Logger.log(e.to_s)
98
111
  end
@@ -115,8 +128,14 @@ module Msf
115
128
  Logger.log(e.to_s)
116
129
  end
117
130
 
118
- def register_default(lhost, lport, payload_list)
119
- @client.call(:register_default, lhost, lport, payload_list)
131
+ def register_default(uuid, payload_list)
132
+ @client.call(:register_default, uuid, payload_list)
133
+ rescue MessagePack::RPC::TimeoutError => e
134
+ Logger.log(e.to_s)
135
+ end
136
+
137
+ def default
138
+ @client.call(:default)
120
139
  rescue MessagePack::RPC::TimeoutError => e
121
140
  Logger.log(e.to_s)
122
141
  end
@@ -129,6 +148,39 @@ module Msf
129
148
 
130
149
  def stop
131
150
  @client.close
151
+ @client = nil
152
+ @listening_thread.join if @listening_thread
153
+ end
154
+
155
+ def register_response_channel(requester)
156
+ unless requester.kind_of? Metasploit::Aggregator::Http::Requester
157
+ raise ArgumentError("response channel class invalid")
158
+ end
159
+ @response_io = requester
160
+ start_responding
161
+ end
162
+
163
+ def start_responding
164
+ @listening_thread = Thread.new do
165
+ @listener_client = MessagePack::RPC::Client.new(@host, @port) unless @listener_client
166
+ while @client
167
+ begin
168
+ sleep 0.1 # polling for now need
169
+ result, result_obj, session_id, response_obj = nil
170
+ result = @listener_client.call(:request, @uuid)
171
+ next unless result # just continue to poll if no request is found
172
+ result_obj = Metasploit::Aggregator::Http::Request.from_msgpack(result)
173
+ session_id = Metasploit::Aggregator::Http::Request.parse_uri(result_obj)
174
+ response_obj = @response_io.process_request(result_obj)
175
+ @listener_client.call(:respond, session_id, response_obj.to_msgpack)
176
+ rescue MessagePack::RPC::TimeoutError
177
+ next
178
+ rescue
179
+ Logger.log $!
180
+ end
181
+ end
182
+ @listener_client.close
183
+ end
132
184
  end
133
185
  end # ServerProxy
134
186
 
@@ -137,10 +189,11 @@ module Msf
137
189
 
138
190
  def initialize
139
191
  @manager = nil
192
+ @router = Router.instance
140
193
  end
141
194
 
142
195
  def start
143
- @manager = Msf::Aggregator::ConnectionManager.new
196
+ @manager = Metasploit::Aggregator::ConnectionManager.new
144
197
  true
145
198
  end
146
199
 
@@ -156,11 +209,11 @@ module Msf
156
209
  @manager.cables
157
210
  end
158
211
 
159
- def obtain_session(payload, rhost, rport)
212
+ def obtain_session(payload, uuid)
160
213
  # return session object details or UUID/uri
161
214
  # forwarding will cause new session creation on the console
162
215
  # TODO: check and set lock on payload requested see note below in register_default
163
- @manager.register_forward(rhost, rport, [ payload ])
216
+ @manager.register_forward(uuid, [ payload ])
164
217
  true # update later to return if lock obtained
165
218
  end
166
219
 
@@ -190,13 +243,18 @@ module Msf
190
243
  end
191
244
  end
192
245
 
193
- def register_default(lhost, lport, payload_list)
246
+ def register_default(uuid, payload_list)
194
247
  # add this payload list to each forwarder for this remote console
195
248
  # TODO: consider adding boolean param to ConnectionManager.register_forward to 'lock'
196
- @manager.register_forward(lhost, lport, payload_list)
249
+ @manager.register_forward(uuid, payload_list)
197
250
  true
198
251
  end
199
252
 
253
+ def default
254
+ send, recv, console = @router.get_forward('default')
255
+ console
256
+ end
257
+
200
258
  def available_addresses
201
259
  addr_list = Socket.ip_address_list
202
260
  addresses = []
@@ -217,8 +275,64 @@ module Msf
217
275
  def release_session(host)
218
276
  @manager.park(host)
219
277
  end
278
+
279
+ def request(uuid)
280
+ # return requests here
281
+ result = nil
282
+ send, recv = @router.reverse_route(uuid)
283
+ if send.length > 0
284
+ result = send.pop
285
+ end
286
+ result
287
+ end
288
+
289
+ def respond(uuid, data)
290
+ send, recv = @router.get_forward(uuid)
291
+ recv << data unless recv.nil?
292
+ true
293
+ end
294
+
295
+ def register_response_channel(io)
296
+ # not implemented "client only method"
297
+ response = "register_response_channel not implemented on server"
298
+ Logger.log response
299
+ response
300
+ end
220
301
  end # class Server
221
302
 
303
+ # wrapping class required to avoid MsgPack specific needs to parallel request processing.
304
+ class AsyncMsgPackServer < Server
305
+
306
+ def initialize
307
+ super
308
+ end
309
+
310
+ # MsgPack specific wrapper for listener due to lack of parallel processing
311
+ def request(uuid)
312
+ result = super(uuid)
313
+ sendMsg = nil
314
+ if result
315
+ begin
316
+ sendMsg = result.to_msgpack
317
+ rescue Exception => e
318
+ Logger.log e.backtrace
319
+ # when an error occurs here we should likely respond with an error of some sort to remove block on response
320
+ end
321
+ end
322
+ sendMsg
323
+ end
324
+
325
+ # MsgPack specific wrapper for listener due to lack of parallel processing
326
+ def respond(uuid, data)
327
+ begin
328
+ result = super(uuid, Metasploit::Aggregator::Http::Request.from_msgpack(data))
329
+ result
330
+ rescue Exception => e
331
+ Logger.log e.backtrace
332
+ end
333
+ end
334
+ end # AsyncMsgPackServer
335
+
222
336
  class MsgPackServer
223
337
 
224
338
  def initialize(host, port)
@@ -227,12 +341,12 @@ module Msf
227
341
 
228
342
  # server = TCPServer.new(@host, @port)
229
343
  # sslContext = OpenSSL::SSL::SSLContext.new
230
- # sslContext.key, sslContext.cert = Msf::Aggregator::ConnectionManager.ssl_generate_certificate
344
+ # sslContext.key, sslContext.cert = Metasploit::Aggregator::ConnectionManager.ssl_generate_certificate
231
345
  # sslServer = OpenSSL::SSL::SSLServer.new(server, sslContext)
232
346
  #
233
347
  @svr = MessagePack::RPC::Server.new # need to initialize this as ssl server
234
348
  # @svr.listen(sslServer, Server.new)
235
- @svr.listen(@host, @port, Server.new)
349
+ @svr.listen(@host, @port, AsyncMsgPackServer.new)
236
350
 
237
351
  Thread.new { @svr.run }
238
352
  end
@@ -1,4 +1,4 @@
1
- module Msf
1
+ module Metasploit
2
2
  module Aggregator
3
3
  class Cable
4
4
  HTTPS = 'https'
@@ -1,12 +1,12 @@
1
1
  require 'openssl'
2
2
  require 'socket'
3
3
 
4
- require 'msf/aggregator/logger'
5
- require 'msf/aggregator/http_forwarder'
6
- require 'msf/aggregator/https_forwarder'
7
- require 'msf/aggregator/cable'
4
+ require 'metasploit/aggregator/logger'
5
+ require 'metasploit/aggregator/http_forwarder'
6
+ require 'metasploit/aggregator/https_forwarder'
7
+ require 'metasploit/aggregator/cable'
8
8
 
9
- module Msf
9
+ module Metasploit
10
10
  module Aggregator
11
11
 
12
12
  class ConnectionManager
@@ -14,7 +14,6 @@ module Msf
14
14
  def initialize
15
15
  @cables = []
16
16
  @manager_mutex = Mutex.new
17
- @default_route = []
18
17
  @router = Router.instance
19
18
  end
20
19
 
@@ -61,14 +60,14 @@ module Msf
61
60
 
62
61
  def add_cable_https(host, port, certificate)
63
62
  @manager_mutex.synchronize do
64
- forwarder = Msf::Aggregator::HttpsForwarder.new
63
+ forwarder = Metasploit::Aggregator::HttpsForwarder.new
65
64
  forwarder.log_messages = true
66
65
  server = TCPServer.new(host, port)
67
66
  ssl_context = OpenSSL::SSL::SSLContext.new
68
67
  unless certificate.nil?
69
68
  ssl_context.key, ssl_context.cert = ssl_parse_certificate(certificate)
70
69
  else
71
- ssl_context.key, ssl_context.cert = Msf::Aggregator::ConnectionManager.ssl_generate_certificate
70
+ ssl_context.key, ssl_context.cert = Metasploit::Aggregator::ConnectionManager.ssl_generate_certificate
72
71
  end
73
72
  ssl_server = OpenSSL::SSL::SSLServer.new(server, ssl_context)
74
73
 
@@ -80,7 +79,7 @@ module Msf
80
79
 
81
80
  def add_cable_http(host, port)
82
81
  @manager_mutex.synchronize do
83
- forwarder = Msf::Aggregator::HttpForwarder.new
82
+ forwarder = Metasploit::Aggregator::HttpForwarder.new
84
83
  forwarder.log_messages = true
85
84
  server = TCPServer.new(host, port)
86
85
 
@@ -89,20 +88,12 @@ module Msf
89
88
  end
90
89
  end
91
90
 
92
- def register_forward(rhost, rport, payload_list = nil)
93
- @cables.each do |cable|
94
- addr = cable.server.local_address
95
- if addr.ip_address == rhost && addr.ip_port == rport.to_i
96
- raise ArgumentError.new("#{rhost}:#{rport} is not a valid forward")
97
- end
98
- end
91
+ def register_forward(uuid, payload_list = nil)
99
92
  if payload_list.nil?
100
- # add the this host and port as the new default route
101
- @default_route = [rhost, rport]
102
- @router.add_route(rhost, rport, nil)
93
+ @router.add_route(uuid, nil)
103
94
  else
104
95
  payload_list.each do |payload|
105
- @router.add_route(rhost, rport, payload)
96
+ @router.add_route(uuid, payload)
106
97
  end
107
98
  end
108
99
  end
@@ -174,7 +165,7 @@ module Msf
174
165
  end
175
166
 
176
167
  def park(payload)
177
- @router.add_route(nil, nil, payload)
168
+ @router.add_route(nil, payload)
178
169
  Logger.log "parking #{payload}"
179
170
  end
180
171
 
@@ -1,4 +1,4 @@
1
- module Msf
1
+ module Metasploit
2
2
  module Aggregator
3
3
  class Forwarder
4
4
  CONNECTION_TIMEOUT = 60 # one minute
@@ -9,7 +9,6 @@ module Msf
9
9
  def initialize
10
10
  @log_messages = false
11
11
  @response_queues = {}
12
- @responding_threads = {}
13
12
  @forwarder_mutex = Mutex.new
14
13
  @router = Router.instance
15
14
  end
@@ -25,9 +24,9 @@ module Msf
25
24
  connections = {}
26
25
  @response_queues.each_pair do |connection, queue|
27
26
  forward = 'parked'
28
- host, port = @router.get_forward(connection)
29
- unless host.nil?
30
- forward = "#{host}:#{port}"
27
+ send, recv, console = @router.get_forward(connection)
28
+ unless console.nil?
29
+ forward = "#{console}"
31
30
  end
32
31
  connections[connection] = forward
33
32
  end
@@ -43,8 +42,8 @@ module Msf
43
42
  end
44
43
  end
45
44
  stale_sessions.each do |uri|
46
- @response_queues[uri].stop_processing
47
- @response_queues.delete(uri)
45
+ stale_queue = @response_queues.delete(uri)
46
+ stale_queue.stop_processing unless stale_queue.nil?
48
47
  end
49
48
  end
50
49
  end
@@ -0,0 +1,13 @@
1
+ require 'metasploit/aggregator/http/request'
2
+ require 'metasploit/aggregator/http/requester'
3
+ require 'metasploit/aggregator/http/responder'
4
+ require 'metasploit/aggregator/http/ssl_requester'
5
+ require 'metasploit/aggregator/http/ssl_responder'
6
+
7
+ module Metasploit
8
+ module Aggregator
9
+ module Http
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,53 @@
1
+ module Metasploit
2
+ module Aggregator
3
+ module Http
4
+ class Request
5
+ attr_reader :headers
6
+ attr_reader :body
7
+ attr_reader :socket
8
+
9
+ def initialize(request_headers, request_body, socket)
10
+ @headers = request_headers
11
+ @body = request_body
12
+ @socket = socket
13
+ end
14
+
15
+ def self.parse_uri(http_request)
16
+ req = http_request.headers[0]
17
+ parts = req.split(/ /)
18
+ uri = nil
19
+ if parts.length >= 2
20
+ uri = req.split(/ /)[1]
21
+ uri = uri.chomp('/')
22
+ end
23
+ uri
24
+ end
25
+
26
+ def to_msgpack
27
+ MessagePack.dump ({
28
+ :headers => headers,
29
+ :body => body
30
+ })
31
+ end
32
+
33
+ def self.from_msgpack(string)
34
+ data = MessagePack.load string
35
+ self.new(data['headers'], data['body'].force_encoding(Encoding::ASCII_8BIT), nil)
36
+ end
37
+
38
+ # provide a default response in Request form
39
+ def self.parked()
40
+ parked_message = []
41
+ parked_message << 'HTTP/1.1 200 OK'
42
+ parked_message << 'Content-Type: application/octet-stream'
43
+ parked_message << 'Connection: close'
44
+ parked_message << 'Server: Apache'
45
+ parked_message << 'Content-Length: 0'
46
+ parked_message << ' '
47
+ parked_message << ' '
48
+ self.new(parked_message, '', nil)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,41 @@
1
+ require "metasploit/aggregator/http/request"
2
+ require "metasploit/aggregator/http/responder"
3
+
4
+ module Metasploit
5
+ module Aggregator
6
+ module Http
7
+ # a Requester takes in Request object and to send to a known port and protocol
8
+ # and receives a response that it also returns as a Request object
9
+ class Requester
10
+ def initialize(host, port)
11
+ @host = host
12
+ @port = port
13
+ end
14
+
15
+ def process_request(request)
16
+ socket = get_connection(@host, @port)
17
+ write_request(socket, request)
18
+ response_obj = Metasploit::Aggregator::Http::Responder.get_data(socket, true)
19
+ close_connection(socket)
20
+ response_obj
21
+ end
22
+
23
+ def write_request(connection, request)
24
+ request.headers.each do |header|
25
+ connection.write(header)
26
+ end
27
+ connection.write(request.body) unless request.body.nil?
28
+ end
29
+
30
+ def get_connection(host, port)
31
+ TCPSocket.new host, port
32
+ end
33
+
34
+ def close_connection(connection)
35
+ connection.close
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,8 +1,11 @@
1
- require "msf/aggregator/http/request"
1
+ require "metasploit/aggregator/http/request"
2
2
 
3
- module Msf
3
+ module Metasploit
4
4
  module Aggregator
5
5
  module Http
6
+ # a Responder acts a a gateway to convert data from a port to into a Request object
7
+ # used in the aggregator. It also reverses this process as a gateway for sending Request object
8
+ # back as responses to the original Request.
6
9
  class Responder
7
10
 
8
11
  attr_accessor :queue
@@ -16,6 +19,7 @@ module Msf
16
19
  @thread = Thread.new { process_requests }
17
20
  @time = Time.now
18
21
  @router = Router.instance
22
+ @pending_requests = nil
19
23
  end
20
24
 
21
25
  def process_requests
@@ -26,53 +30,35 @@ module Msf
26
30
  connection = request_task.socket
27
31
  request_task.headers
28
32
 
29
- # peer_addr = connection.io.peeraddr[3]
30
-
31
- host, port = @router.get_forward(@uri)
32
- if host.nil?
33
+ send, recv = @router.get_forward(@uri)
34
+ if send.nil?
33
35
  # when no forward found park the connection for now
34
36
  # in the future this may get smarter and return a 404 or something
35
37
  send_parked_response(connection)
36
38
  next
37
39
  end
38
40
 
39
- client = nil
40
-
41
- begin
42
- client = get_connection(host, port)
43
- rescue StandardError => e
44
- log 'error on console connect ' + e.to_s
45
- send_parked_response(connection)
46
- next
47
- end
48
-
49
- log 'connected to console'
41
+ # response from get_forward will be a queue to push messages onto and a response queue to retrieve result from
42
+ send << request_task
43
+ @pending_request = connection
50
44
 
51
- request_task.headers.each do |line|
52
- client.write line
53
- end
54
- unless request_task.body.nil?
55
- client.write request_task.body
56
- end
57
- client.flush
58
- # log "From victim: \n" + request_lines.join()
45
+ log 'queued to console'
59
46
 
47
+ # now get the response once available and send back using this connection
60
48
  begin
61
- response = ''
62
- request_obj = Responder.get_data(client, true)
49
+ request_obj = recv.pop
50
+ @pending_request = nil
63
51
  request_obj.headers.each do |line|
64
52
  connection.write line
65
- response += line
66
53
  end
67
54
  unless request_obj.body.nil?
68
55
  connection.write request_obj.body
69
56
  end
70
57
  connection.flush
71
- # log "From console: \n" + response
58
+ log 'message delivered from console'
72
59
  rescue
73
60
  log $!
74
61
  end
75
- close_connection(client)
76
62
  close_connection(connection)
77
63
  rescue Exception => e
78
64
  log "an error occurred processing request from #{@uri}"
@@ -83,20 +69,16 @@ module Msf
83
69
 
84
70
  def stop_processing
85
71
  @thread.exit
72
+ if @pending_request
73
+ send_parked_response(@pending_request)
74
+ close_connection(@pending_request)
75
+ end
86
76
  end
87
77
 
88
78
  def send_parked_response(connection)
89
79
  address = connection.peeraddr[3]
90
80
  log "sending parked response to #{address}"
91
- parked_message = []
92
- parked_message << 'HTTP/1.1 200 OK'
93
- parked_message << 'Content-Type: application/octet-stream'
94
- parked_message << 'Connection: close'
95
- parked_message << 'Server: Apache'
96
- parked_message << 'Content-Length: 0'
97
- parked_message << ' '
98
- parked_message << ' '
99
- parked_message.each do |line|
81
+ Metasploit::Aggregator::Http::Request.parked.headers.each do |line|
100
82
  connection.puts line
101
83
  end
102
84
  close_connection(connection)
@@ -0,0 +1,27 @@
1
+ require "metasploit/aggregator/http/requester"
2
+
3
+ module Metasploit
4
+ module Aggregator
5
+ module Http
6
+ class SslRequester < Requester
7
+ def initialize(host, port)
8
+ super(host, port)
9
+ end
10
+
11
+ def get_connection(host, port)
12
+ tcp_client = TCPSocket.new host, port
13
+ ssl_context = OpenSSL::SSL::SSLContext.new
14
+ ssl_context.ssl_version = :TLSv1
15
+ ssl_client = OpenSSL::SSL::SSLSocket.new tcp_client, ssl_context
16
+ ssl_client.connect
17
+ ssl_client
18
+ end
19
+
20
+ def close_connection(connection)
21
+ connection.sync_close = true
22
+ connection.close
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,7 +1,7 @@
1
- require "msf/aggregator/http/request"
2
- require "msf/aggregator/http/responder"
1
+ require "metasploit/aggregator/http/request"
2
+ require "metasploit/aggregator/http/responder"
3
3
 
4
- module Msf
4
+ module Metasploit
5
5
  module Aggregator
6
6
  module Http
7
7
  class SslResponder < Responder
@@ -1,11 +1,11 @@
1
1
  require 'socket'
2
- require 'msf/aggregator/forwarder'
3
- require 'msf/aggregator/http/request'
4
- require 'msf/aggregator/http/responder'
5
- require 'msf/aggregator/logger'
6
- require 'msf/aggregator/router'
2
+ require 'metasploit/aggregator/forwarder'
3
+ require 'metasploit/aggregator/http/request'
4
+ require 'metasploit/aggregator/http/responder'
5
+ require 'metasploit/aggregator/logger'
6
+ require 'metasploit/aggregator/router'
7
7
 
8
- module Msf
8
+ module Metasploit
9
9
  module Aggregator
10
10
  class HttpForwarder < Forwarder
11
11
  CONNECTION_TIMEOUT = 60 # one minute
@@ -19,12 +19,12 @@ module Msf
19
19
 
20
20
  def forward(connection)
21
21
  #forward input requests
22
- request_obj = Msf::Aggregator::Http::Responder.get_data(connection, false)
23
- uri = Msf::Aggregator::Http::Request.parse_uri(request_obj)
22
+ request_obj = Metasploit::Aggregator::Http::Responder.get_data(connection, false)
23
+ uri = Metasploit::Aggregator::Http::Request.parse_uri(request_obj)
24
24
  @forwarder_mutex.synchronize do
25
25
  unless uri.nil?
26
26
  unless @response_queues[uri]
27
- uri_responder = Msf::Aggregator::Http::Responder.new(uri)
27
+ uri_responder = Metasploit::Aggregator::Http::Responder.new(uri)
28
28
  uri_responder.log_messages = @log_messages
29
29
  @response_queues[uri] = uri_responder
30
30
  end
@@ -1,12 +1,12 @@
1
1
  require 'socket'
2
2
  require 'openssl'
3
- require 'msf/aggregator/forwarder'
4
- require 'msf/aggregator/http/request'
5
- require 'msf/aggregator/http/ssl_responder'
6
- require 'msf/aggregator/logger'
7
- require 'msf/aggregator/router'
3
+ require 'metasploit/aggregator/forwarder'
4
+ require 'metasploit/aggregator/http/request'
5
+ require 'metasploit/aggregator/http/ssl_responder'
6
+ require 'metasploit/aggregator/logger'
7
+ require 'metasploit/aggregator/router'
8
8
 
9
- module Msf
9
+ module Metasploit
10
10
  module Aggregator
11
11
 
12
12
  class HttpsForwarder < Forwarder
@@ -17,12 +17,12 @@ module Msf
17
17
 
18
18
  def forward(connection)
19
19
  #forward input requests
20
- request_obj = Msf::Aggregator::Http::SslResponder.get_data(connection, false)
21
- uri = Msf::Aggregator::Http::Request.parse_uri(request_obj)
20
+ request_obj = Metasploit::Aggregator::Http::SslResponder.get_data(connection, false)
21
+ uri = Metasploit::Aggregator::Http::Request.parse_uri(request_obj)
22
22
  @forwarder_mutex.synchronize do
23
23
  unless uri.nil?
24
24
  unless @response_queues[uri]
25
- uri_responder = Msf::Aggregator::Http::SslResponder.new(uri)
25
+ uri_responder = Metasploit::Aggregator::Http::SslResponder.new(uri)
26
26
  uri_responder.log_messages = @log_messages
27
27
  @response_queues[uri] = uri_responder
28
28
  end
File without changes
@@ -0,0 +1,68 @@
1
+ require 'singleton'
2
+
3
+ module Metasploit
4
+ module Aggregator
5
+ class Router
6
+ include Singleton
7
+
8
+ def initialize
9
+ @mutex = Mutex.new
10
+ @forward_routes = {}
11
+ @queue_by_uuid = {}
12
+ end
13
+
14
+ def add_route(uuid, payload)
15
+ # for now always replace in future may check if same route to avoid request loss
16
+ forward = uuid.nil? ? [] : [Queue.new, Queue.new, uuid]
17
+ @mutex.synchronize do
18
+ if payload.nil?
19
+ @forward_routes['default'] = forward
20
+ return
21
+ end
22
+ @forward_routes[payload] = forward
23
+ end
24
+ end
25
+
26
+ def remove_route(payload)
27
+ unless payload.nil?
28
+ @mutex.synchronize do
29
+ @forward_routes.delete(payload)
30
+ end
31
+ end
32
+ end
33
+
34
+ def get_forward(uri)
35
+ unless @forward_routes[uri].nil?
36
+ @forward_routes[uri]
37
+ else
38
+ @forward_routes['default']
39
+ end
40
+ end
41
+
42
+ def reverse_route(uuid)
43
+ # this method is not ready for prime time yet as will not
44
+ # support multiple sessions properly, either need unique Queue
45
+ # for each session which can be identified on reverse or need
46
+ # pipeline request order to ensure all results are posted in order only
47
+ # this could create deadlocks while one session waits for a response
48
+ # if another fails to respond.
49
+
50
+ # try returning a uuid queue filled an aggregate of queues for all requests
51
+ # for a reverse uuid, and refill that on each reverse, this puts logic
52
+ # here that I do not like but accomplishes the requirement for now
53
+ unless @queue_by_uuid[uuid]
54
+ @queue_by_uuid[uuid] = Queue.new
55
+ end
56
+ @forward_routes.each_pair do |key, val|
57
+ request, response, remote_uuid = val
58
+ next unless remote_uuid == uuid
59
+ while !request.empty?
60
+ @queue_by_uuid[uuid] << request.pop
61
+ end
62
+ end
63
+ [] unless @queue_by_uuid[uuid].length > 0
64
+ [@queue_by_uuid[uuid], nil, uuid]
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,5 @@
1
+ module Metasploit
2
+ module Aggregator
3
+ VERSION = '0.1.1'
4
+ end
5
+ end
@@ -1,11 +1,11 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'msf/aggregator/version'
4
+ require 'metasploit/aggregator/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "metasploit-aggregator"
8
- spec.version = Msf::Aggregator::VERSION
8
+ spec.version = Metasploit::Aggregator::VERSION
9
9
  spec.authors = ['Metasploit Hackers']
10
10
  spec.email = ['metasploit-hackers@lists.sourceforge.net']
11
11
  spec.summary = "metasploit-aggregator"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metasploit-aggregator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Metasploit Hackers
@@ -88,7 +88,7 @@ cert_chain:
88
88
  G+Hmcg1v810agasPdoydE0RTVZgEOOMoQ07qu7JFXVWZ9ZQpHT7qJATWL/b2csFG
89
89
  8mVuTXnyJOKRJA==
90
90
  -----END CERTIFICATE-----
91
- date: 2016-12-21 00:00:00.000000000 Z
91
+ date: 2017-01-31 00:00:00.000000000 Z
92
92
  dependencies:
93
93
  - !ruby/object:Gem::Dependency
94
94
  name: bundler
@@ -178,18 +178,21 @@ files:
178
178
  - README.md
179
179
  - Rakefile
180
180
  - bin/msfaggregator
181
- - lib/msf/aggregator.rb
182
- - lib/msf/aggregator/cable.rb
183
- - lib/msf/aggregator/connection_manager.rb
184
- - lib/msf/aggregator/forwarder.rb
185
- - lib/msf/aggregator/http/request.rb
186
- - lib/msf/aggregator/http/responder.rb
187
- - lib/msf/aggregator/http/ssl_responder.rb
188
- - lib/msf/aggregator/http_forwarder.rb
189
- - lib/msf/aggregator/https_forwarder.rb
190
- - lib/msf/aggregator/logger.rb
191
- - lib/msf/aggregator/router.rb
192
- - lib/msf/aggregator/version.rb
181
+ - lib/metasploit/aggregator.rb
182
+ - lib/metasploit/aggregator/cable.rb
183
+ - lib/metasploit/aggregator/connection_manager.rb
184
+ - lib/metasploit/aggregator/forwarder.rb
185
+ - lib/metasploit/aggregator/http.rb
186
+ - lib/metasploit/aggregator/http/request.rb
187
+ - lib/metasploit/aggregator/http/requester.rb
188
+ - lib/metasploit/aggregator/http/responder.rb
189
+ - lib/metasploit/aggregator/http/ssl_requester.rb
190
+ - lib/metasploit/aggregator/http/ssl_responder.rb
191
+ - lib/metasploit/aggregator/http_forwarder.rb
192
+ - lib/metasploit/aggregator/https_forwarder.rb
193
+ - lib/metasploit/aggregator/logger.rb
194
+ - lib/metasploit/aggregator/router.rb
195
+ - lib/metasploit/aggregator/version.rb
193
196
  - metasploit-aggregator.gemspec
194
197
  homepage: https://www.msf.com
195
198
  licenses:
metadata.gz.sig CHANGED
@@ -1,2 +1,3 @@
1
- # j��T�h��k��B2 Xv����{[^ф��+W�RC�#�G��e۝^9�[��
2
- ��/�ns7�ŴCН]3���f*o�BTD��;4>zEAՌ!] ^A>����XOP�F�X��Q
1
+ �����~jB� {��B6��i_�*++�|�h綏�q+bD~h���@g��F0g��딮$��m�r꣓��)FEw8����(tk���Z����t�&q�b������0��<a188���yO��e0"ΒQ��H,"<C5O@�åmwՓ�ݽ���RG��6�]h綀
2
+ D���\����
3
+ ��fUH=>'��(xgj~�zX98ʓMW?�y�(��gͬ��$1Н` m
@@ -1,28 +0,0 @@
1
- module Msf
2
- module Aggregator
3
- module Http
4
- class Request
5
- attr_reader :headers
6
- attr_reader :body
7
- attr_reader :socket
8
-
9
- def initialize(request_headers, request_body, socket)
10
- @headers = request_headers
11
- @body = request_body
12
- @socket = socket
13
- end
14
-
15
- def self.parse_uri(http_request)
16
- req = http_request.headers[0]
17
- parts = req.split(/ /)
18
- uri = nil
19
- if parts.length >= 2
20
- uri = req.split(/ /)[1]
21
- uri = uri.chomp('/')
22
- end
23
- uri
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,41 +0,0 @@
1
- require 'singleton'
2
-
3
- module Msf
4
- module Aggregator
5
- class Router
6
- include Singleton
7
-
8
- def initialize
9
- @mutex = Mutex.new
10
- @forward_routes = {}
11
- end
12
-
13
- def add_route(rhost, rport, payload)
14
- forward = [rhost, rport]
15
- @mutex.synchronize do
16
- if payload.nil?
17
- @forward_routes['default'] = forward
18
- return
19
- end
20
- @forward_routes[payload] = forward
21
- end
22
- end
23
-
24
- def remove_route(payload)
25
- unless payload.nil?
26
- @mutex.synchronize do
27
- @forward_routes.delete(payload)
28
- end
29
- end
30
- end
31
-
32
- def get_forward(uri)
33
- unless @forward_routes[uri].nil?
34
- @forward_routes[uri]
35
- else
36
- @forward_routes['default']
37
- end
38
- end
39
- end
40
- end
41
- end
@@ -1,5 +0,0 @@
1
- module Msf
2
- module Aggregator
3
- VERSION = '0.1.0'
4
- end
5
- end