metasploit-aggregator 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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