Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,6 @@ group :test do
gem 'timecop'
end

gem 'rex-core', git: 'https://github.com/zeroSteiner/rex-core', branch: 'feat/io/relay-manager'
gem 'rex-socket', git: 'https://github.com/zeroSteiner/rex-socket', branch: 'feat/tcp/starttls'

22 changes: 18 additions & 4 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
GIT
remote: https://github.com/zeroSteiner/rex-core
revision: 65d936d0d01f4f7fd41cbc676fc0af12aed536d6
branch: feat/io/relay-manager
specs:
rex-core (0.1.35)

GIT
remote: https://github.com/zeroSteiner/rex-socket
revision: 04b35d4085c7f8a621d41e50a5b1b6509b4f533e
branch: feat/tcp/starttls
specs:
rex-socket (0.1.64)
dnsruby
rex-core

PATH
remote: .
specs:
Expand Down Expand Up @@ -484,7 +500,6 @@ GEM
rex-core
rex-struct2
rex-text
rex-core (0.1.34)
rex-encoder (0.1.8)
metasm
rex-arch
Expand Down Expand Up @@ -518,9 +533,6 @@ GEM
metasm
rex-core
rex-text
rex-socket (0.1.62)
dnsruby
rex-core
rex-sslscan (0.1.13)
rex-core
rex-socket
Expand Down Expand Up @@ -679,6 +691,8 @@ DEPENDENCIES
pry-byebug
rake
redcarpet
rex-core!
rex-socket!
rspec-rails
rspec-rerun
rubocop (= 1.75.7)
Expand Down
2 changes: 1 addition & 1 deletion lib/metasploit/framework/credential_collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ def each_password(user)
yield ["", :password]
end

if pass_file
if pass_file.present?
File.open(pass_file, 'r:binary') do |pass_fd|
pass_fd.each_line do |pass_from_file|
pass_from_file.chomp!
Expand Down
145 changes: 0 additions & 145 deletions lib/metasploit/framework/mssql/tdssslproxy.rb

This file was deleted.

3 changes: 2 additions & 1 deletion lib/msf/core/handler/bind_aws_ssm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,10 @@ def start_handler
# Configure Channel
chan._start_ssm_keepalive if datastore['SSM_KEEP_ALIVE']
chan.params.comm = Rex::Socket::Comm::Local unless chan.params.comm
chan.params.peerhostname = peer_info['ComputerName']
chan.params.peerhost = peer_info['IpAddress']
chan.params.peerport = 0
chan.params.peerhostname = peer_info['ComputerName']
chan.lsock.initinfo(Rex::Socket.to_authority(peer_info['IpAddress'], 0), chan.lsock.localinfo)
chan.update_term_size
rescue => e
print_error("AWS SSM handler failed: #{e.message}")
Expand Down
3 changes: 1 addition & 2 deletions lib/postgres/postgres-pr/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,7 @@ def establish_connection(uri, proxies, ssl = nil, ssl_opts = {})
@conn.write(ssl_request_message.dump)
response = @conn.read(1)
if response == 'S'
@conn.extend(Rex::Socket::SslTcp)
@conn.initsock_with_ssl_version(params, (params.ssl_version || Rex::Socket::Ssl::DEFAULT_SSL_VERSION))
@conn.starttls(params)
elsif response == 'N'
# Server does not support SSL
raise "SSL connection requested but server at #{u.host}:#{u.port} does not support SSL"
Expand Down
6 changes: 0 additions & 6 deletions lib/rex/post/channel/socket_abstraction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,6 @@ def getpeername
end
end

def close
super
channel.cleanup_abstraction
channel.close
end

attr_accessor :channel
end
end
Expand Down
9 changes: 0 additions & 9 deletions lib/rex/post/meterpreter/channels/pools/stream_pool.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,6 @@ def dio_write_handler(packet, data)
end
end

#
# Closes the local half of the pool stream.
#
def dio_close_handler(packet)
rsock.close

return super(packet)
end
Comment on lines -86 to -90
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was removed because the #close method is no longer replaced with something that'd close the channel. The original logic was prone to creating recursion loops during development and would send a close command back to Meterpreter when Meterpreter initiated the close operation.

The new implementation should simply things by always closing the channel from the channel object level instead of the rsock. Now when a channel is closed by Meterpreter, the #dio_close_handler will simply close and cleanup the channel locally without echoing the command back to Meterpreter.

When the channel is closed by Metasploit Framework, it's either closed by lsock.close which causes an EOF to be read in the Relay Manager which will dispatch to the on_exit callback, which by default calls #close_write. Alternatively, the channel object can be closed directly, but there's no longer a loop as everything is notified.


#
# Cleans up resources used by the channel.
#
Expand Down
9 changes: 0 additions & 9 deletions lib/rex/post/meterpreter/channels/socket_abstraction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,6 @@ def dio_write_handler(packet, data)
end
end

#
# Performs a close operation on the right side of the local stream.
#
def dio_close_handler(packet)
rsock.close

return super(packet)
end

#
# Cleans up the stream abstraction.
#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ def initialize(client, cid, type, flags, packet, sock_params: nil)
rsock.synchronize_access { rsock.initsock(@params) }
end

def monitor_rsock(name = 'MonitorRemote')
# call #close on exit instead of #close_write because this is triggered in response to lsock.close
# lsock.close -> rsock EOF -> #close -> Meterpreter close
monitor_sock(rsock, sink: self, name: name, on_exit: method(:close))
end

#
# Closes the write half of the connection.
#
Expand Down
6 changes: 4 additions & 2 deletions lib/rex/proto/http/web_socket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ def type?
# binary and text)
# @param [Symbol] write_type the data type to write to the WebSocket
def initialize(websocket, read_type: nil, write_type: :binary)
initialize_abstraction

# a read type of nil will handle both binary and text frames that are received
raise ArgumentError, 'read_type must be nil, :binary or :text' unless [nil, :binary, :text].include?(read_type)
raise ArgumentError, 'write_type must be :binary or :text' unless %i[binary text].include?(write_type)
Expand All @@ -66,6 +64,10 @@ def initialize(websocket, read_type: nil, write_type: :binary)
'SSL' => websocket.respond_to?(:sslctx) && !websocket.sslctx.nil?
})

initialize_abstraction

lsock.initinfo(Rex::Socket.to_authority(peerhost, peerport), Rex::Socket.to_authority(localhost, localport))

@thread = Rex::ThreadFactory.spawn("WebSocketChannel(#{localhost}->#{peerhost})", false) do
websocket.wsloop do |data, data_type|
next unless @read_type.nil? || data_type == @read_type
Expand Down
62 changes: 62 additions & 0 deletions lib/rex/proto/ms_tds/channel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# -*- coding: binary -*-

require 'bindata'

module Rex::Proto::MsTds
class Channel
include Rex::IO::StreamAbstraction

attr_reader :params

# the socket that makes the outbound connection to the SQL server
attr_reader :sock

def initialize(opts = {})
@params = Rex::Socket::Parameters.from_hash(opts)

# it doesn't work this way so throw an exception so that's clear
raise RuntimeError.new('SSL incompatible with MsTds::Socket') if @params.ssl
raise ArgumentError.new('MsTds::Socket must be TCP') if @params.proto != 'tcp'

@sock = Rex::Socket.create_param(@params)
initialize_abstraction

lsock.initinfo(@sock.peerinfo, @sock.localinfo)

monitor_sock(@sock, sink: method(:_read_handler), name: 'MonitorLocal', on_exit: method(:_exit_handler))
end

def write(buf, opts = {})
if negotiating_ssl?
Rex::IO::RelayManager.io_write_all(self.sock, [18, 0x01, buf.length + 8, 0x0000, 0x00, 0x00].pack('CCnnCC') + buf) - 8
else
Rex::IO::RelayManager.io_write_all(self.sock, buf)
end
end

def starttls
self.lsock.starttls(params)
end

protected

def negotiating_ssl?
return false unless self.lsock.is_a?(Rex::Socket::SslTcp)
return false if self.lsock.sslsock.state.start_with?('SSLOK')

true
end

def _exit_handler
self.rsock.close
end

def _read_handler(buf)
if negotiating_ssl?
Rex::IO::RelayManager.io_write_all(self.rsock, buf[8..]) + 8
else
Rex::IO::RelayManager.io_write_all(self.rsock, buf)
end
end
end
end
Loading
Loading