Skip to content

Change from PEM to DER for crypt TLV negotiation #13400

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 21 commits into from
Closed
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
8 changes: 4 additions & 4 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ PATH
metasploit-concern (~> 2.0.0)
metasploit-credential (~> 3.0.0)
metasploit-model (~> 2.0.4)
metasploit-payloads (= 1.4.2)
metasploit-payloads (= 2.0.0)
metasploit_data_models (~> 3.0.10)
metasploit_payloads-mettle (= 0.5.21)
metasploit_payloads-mettle (= 1.0.0)
mqtt
msgpack
nessus_rest
Expand Down Expand Up @@ -220,7 +220,7 @@ GEM
activemodel (~> 4.2.6)
activesupport (~> 4.2.6)
railties (~> 4.2.6)
metasploit-payloads (1.4.2)
metasploit-payloads (2.0.0)
metasploit_data_models (3.0.10)
activerecord (~> 4.2.6)
activesupport (~> 4.2.6)
Expand All @@ -231,7 +231,7 @@ GEM
postgres_ext
railties (~> 4.2.6)
recog (~> 2.0)
metasploit_payloads-mettle (0.5.21)
metasploit_payloads-mettle (1.0.0)
method_source (1.0.0)
mini_portile2 (2.4.0)
minitest (5.14.1)
Expand Down
4 changes: 2 additions & 2 deletions lib/msf/core/handler/reverse_http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require 'rex/sync/ref'
require 'rex/payloads/meterpreter/uri_checksum'
require 'rex/post/meterpreter'
require 'rex/post/meterpreter/core_ids'
require 'rex/socket/x509_certificate'
require 'msf/core/payload/windows/verify_ssl'
require 'rex/user_agent'
Expand Down Expand Up @@ -367,8 +368,7 @@ def on_request(cli, req)
# was generated on the fly. This means we form a new session for each.

# Hurl a TLV back at the caller, and ignore the response
pkt = Rex::Post::Meterpreter::Packet.new(Rex::Post::Meterpreter::PACKET_TYPE_RESPONSE,
'core_patch_url')
pkt = Rex::Post::Meterpreter::Packet.new(Rex::Post::Meterpreter::PACKET_TYPE_RESPONSE, Rex::Post::Meterpreter::COMMAND_ID_CORE_PATCH_URL)
pkt.add_tlv(Rex::Post::Meterpreter::TLV_TYPE_TRANS_URL, conn_id + "/")
resp.body = pkt.to_r

Expand Down
18 changes: 10 additions & 8 deletions lib/rex/payloads/meterpreter/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require 'msf/core/payload/windows'
require 'msf/core/reflective_dll_loader'
require 'rex/socket/x509_certificate'
require 'rex/post/meterpreter/extension_mapper'
require 'securerandom'

class Rex::Payloads::Meterpreter::Config
Expand Down Expand Up @@ -132,24 +133,25 @@ def transport_block(opts)

def extension_block(ext_name, file_extension)
ext_name = ext_name.strip.downcase
ext, o = load_rdi_dll(MetasploitPayloads.meterpreter_path("ext_server_#{ext_name}",
ext, _ = load_rdi_dll(MetasploitPayloads.meterpreter_path("ext_server_#{ext_name}",
file_extension))

extension_data = [ ext.length, ext ].pack('VA*')
[ ext.length, ext ].pack('VA*')
end

def extension_init_block(name, value)
ext_id = Rex::Post::Meterpreter::ExtensionMapper.get_extension_id(name)

# for now, we're going to blindly assume that the value is a path to a file
# which contains the data that gets passed to the extension
content = ::File.read(value)
content = ::File.read(value) + "\x00\x00"
data = [
name,
"\x00",
ext_id,
content.length,
content
]

data.pack('A*A*VA*')
data.pack('VVA*')
end

def config_block
Expand Down Expand Up @@ -182,8 +184,8 @@ def config_block
config << extension_init_block(name, value)
end

# terminate the ext init config with a final null byte
config << "\x00"
# terminate the ext init config with -1
config << "\xFF\xFF\xFF\xFF"

# and we're done
config
Expand Down
18 changes: 9 additions & 9 deletions lib/rex/post/meterpreter/channel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def request_handler(client, packet)
#
def Channel.create(client, type = nil, klass = nil,
flags = CHANNEL_FLAG_SYNCHRONOUS, addends = nil, **klass_kwargs)
request = Packet.create_request('core_channel_open')
request = Packet.create_request(COMMAND_ID_CORE_CHANNEL_OPEN)

# Set the type of channel that we're allocating
if !type.nil?
Expand Down Expand Up @@ -179,7 +179,7 @@ def _read(length = nil, addends = nil)
raise IOError, "Channel has been closed.", caller
end

request = Packet.create_request('core_channel_read')
request = Packet.create_request(COMMAND_ID_CORE_CHANNEL_READ)

if length.nil?
# Default block size to a higher amount for passive dispatcher
Expand Down Expand Up @@ -227,7 +227,7 @@ def _write(buf, length = nil, addends = nil)
raise IOError, "Channel has been closed.", caller
end

request = Packet.create_request('core_channel_write')
request = Packet.create_request(COMMAND_ID_CORE_CHANNEL_WRITE)

# Truncation and celebration
if ((length != nil) &&
Expand Down Expand Up @@ -290,7 +290,7 @@ def self._close(client, cid, addends=nil)
raise IOError, "Channel has been closed.", caller
end

request = Packet.create_request('core_channel_close')
request = Packet.create_request(COMMAND_ID_CORE_CHANNEL_CLOSE)

# Populate the request
request.add_tlv(TLV_TYPE_CHANNEL_ID, cid)
Expand Down Expand Up @@ -322,7 +322,7 @@ def interactive(tf = true, addends = nil)
raise IOError, "Channel has been closed.", caller
end

request = Packet.create_request('core_channel_interact')
request = Packet.create_request(COMMAND_ID_CORE_CHANNEL_INTERACT)

# Populate the request
request.add_tlv(TLV_TYPE_CHANNEL_ID, self.cid)
Expand Down Expand Up @@ -397,12 +397,12 @@ def dio_close_handler(packet)
# per-instance basis as other instances may add custom dio
# handlers.
#
def dio_map(method)
if (method == 'core_channel_read')
def dio_map(command_id)
if command_id == COMMAND_ID_CORE_CHANNEL_READ
return CHANNEL_DIO_READ
elsif (method == 'core_channel_write')
elsif command_id == COMMAND_ID_CORE_CHANNEL_WRITE
return CHANNEL_DIO_WRITE
elsif (method == 'core_channel_close')
elsif command_id == COMMAND_ID_CORE_CHANNEL_CLOSE
return CHANNEL_DIO_CLOSE
end

Expand Down
13 changes: 6 additions & 7 deletions lib/rex/post/meterpreter/channels/pool.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def initialize(client, cid, type, flags, packet, **_)
# Checks to see if the EOF flag has been set on the pool.
#
def eof
request = Packet.create_request('core_channel_eof')
request = Packet.create_request(COMMAND_ID_CORE_CHANNEL_EOF)

request.add_tlv(TLV_TYPE_CHANNEL_ID, self.cid)

Expand Down Expand Up @@ -106,33 +106,32 @@ def seek(offset, whence = SEEK_SET)
raise RuntimeError, "Invalid seek whence #{whence}.", caller
end

request = Packet.create_request('core_channel_seek')
request = Packet.create_request(COMMAND_ID_CORE_CHANNEL_SEEK)

request.add_tlv(TLV_TYPE_CHANNEL_ID, self.cid)
request.add_tlv(TLV_TYPE_SEEK_OFFSET, offset)
request.add_tlv(TLV_TYPE_SEEK_WHENCE, sane)

begin
response = self.client.send_request(request)
self.client.send_request(request)
tell
rescue
return -1
end

return tell
end

#
# Synonym for tell.
#
def pos
return tell
tell
end

#
# This method returns the current file pointer position to the caller.
#
def tell
request = Packet.create_request('core_channel_tell')
request = Packet.create_request(COMMAND_ID_CORE_CHANNEL_TELL)
pos = -1

request.add_tlv(TLV_TYPE_CHANNEL_ID, self.cid)
Expand Down
2 changes: 1 addition & 1 deletion lib/rex/post/meterpreter/channels/socket_abstraction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def syswrite(buf)
def initialize(client, cid, type, flags, packet, **_)
# sf: initialize_abstraction() before super() as we can get a scenario where dio_write_handler() is called
# with data to write to the rsock but rsock has not yet been initialized. This happens if the channel
# is registered (client.add_channel(self) in Channel.initialize) to a session and a 'core_channel_write'
# is registered (client.add_channel(self) in Channel.initialize) to a session and a COMMAND_ID_CORE_CHANNEL_WRITE
# request comes in before we have called self.initialize_abstraction()
initialize_abstraction
super(client, cid, type, flags, packet)
Expand Down
16 changes: 4 additions & 12 deletions lib/rex/post/meterpreter/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require 'openssl'

require 'rex/script'
require 'rex/post/meterpreter/extension_mapper'
require 'rex/post/meterpreter/client_core'
require 'rex/post/meterpreter/channel'
require 'rex/post/meterpreter/channel_container'
Expand Down Expand Up @@ -316,21 +317,12 @@ def method_missing(symbol, *args)
# registered extension that can be reached through client.ext.[extension].
#
def add_extension(name, commands=[])
self.commands |= commands
self.commands |= []
self.commands.concat(commands)

# Check to see if this extension has already been loaded.
if ((klass = self.class.check_ext_hash(name.downcase)) == nil)
old = Rex::Post::Meterpreter::Extensions.constants
require("rex/post/meterpreter/extensions/#{name.downcase}/#{name.downcase}")
new = Rex::Post::Meterpreter::Extensions.constants

# No new constants added?
if ((diff = new - old).empty?)
diff = [ name.capitalize ]
end

klass = Rex::Post::Meterpreter::Extensions.const_get(diff[0]).const_get(diff[0])

klass = Rex::Post::Meterpreter::ExtensionMapper.get_extension_klass(name)
# Save the module name to class association now that the code is
# loaded.
self.class.set_ext_hash(name.downcase, klass)
Expand Down
Loading