Land #14789, Fix session verification by checking TLV negotiation

This commit is contained in:
Grant Willcox 2021-02-22 14:06:34 -06:00
commit 6f8821dd1d
No known key found for this signature in database
GPG Key ID: D35E05C0F2B81E83
3 changed files with 15 additions and 34 deletions

View File

@ -128,16 +128,20 @@ class Meterpreter < Rex::Post::Meterpreter::Client
session.init_ui(self.user_input, self.user_output)
session.tlv_enc_key = session.core.negotiate_tlv_encryption
verification_timeout = datastore['AutoVerifySessionTimeout']&.to_i || session.comm_timeout
begin
session.tlv_enc_key = session.core.negotiate_tlv_encryption(timeout: verification_timeout)
rescue Rex::TimeoutError
end
unless datastore['AutoVerifySession'] == false
unless session.is_valid_session?(datastore['AutoVerifySessionTimeout'].to_i)
print_error("Meterpreter session #{session.sid} is not valid and will be closed")
# Terminate the session without cleanup if it did not validate
session.skip_cleanup = true
session.kill
return nil
end
if session.tlv_enc_key.nil?
# Fail-closed if TLV encryption can't be negotiated (close the session as invalid)
dlog("Session #{session.sid} failed to negotiate TLV encryption")
print_error("Meterpreter session #{session.sid} is not valid and will be closed")
# Terminate the session without cleanup if it did not validate
session.skip_cleanup = true
session.kill
return nil
end
# always make sure that the new session has a new guid if it's not already known
@ -409,25 +413,6 @@ class Meterpreter < Rex::Post::Meterpreter::Client
console.disable_output = original
end
#
# Validate session information by checking for a machine_id response
#
def is_valid_session?(timeout=10)
return true if self.machine_id
begin
self.machine_id = self.core.machine_id(timeout)
return true
rescue ::Rex::Post::Meterpreter::RequestError
# This meterpreter doesn't support core_machine_id
return true
rescue ::Exception => e
dlog("Session #{self.sid} did not respond to validation request #{e.class}: #{e}")
end
false
end
def update_session_info
# sys.config.getuid, and fs.dir.getwd cache their results, so update them
fs.dir.getwd

View File

@ -23,10 +23,6 @@ module Msf
'AutoLoadStdapi',
[true, "Automatically load the Stdapi extension", true]
),
OptBool.new(
'AutoVerifySession',
[true, "Automatically verify and drop invalid sessions", true]
),
OptInt.new(
'AutoVerifySessionTimeout',
[false, "Timeout period to wait for session validation to occur, in seconds", 30]

View File

@ -742,7 +742,7 @@ class ClientCore < Extension
#
# Negotiates the use of encryption at the TLV level
#
def negotiate_tlv_encryption
def negotiate_tlv_encryption(timeout: client.comm_timeout)
sym_key = nil
rsa_key = OpenSSL::PKey::RSA.new(2048)
rsa_pub_key = rsa_key.public_key
@ -751,7 +751,7 @@ class ClientCore < Extension
request.add_tlv(TLV_TYPE_RSA_PUB_KEY, rsa_pub_key.to_der)
begin
response = client.send_request(request)
response = client.send_request(request, timeout)
key_enc = response.get_tlv_value(TLV_TYPE_ENC_SYM_KEY)
key_type = response.get_tlv_value(TLV_TYPE_SYM_KEY_TYPE)