metasploit-framework/modules/auxiliary/scanner/rdp/rdp_scanner.rb

105 lines
3.0 KiB
Ruby

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::Tcp
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::Report
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Identify endpoints speaking the Remote Desktop Protocol (RDP)',
'Description' => %q(
This module attempts to connect to the specified Remote Desktop Protocol port
and determines if it speaks RDP.
),
'Author' => 'Jon Hart <jon_hart[at]rapid7.com>',
'References' =>
[
['URL', 'https://msdn.microsoft.com/en-us/library/cc240445.aspx']
],
'License' => MSF_LICENSE
)
)
register_options(
[
Opt::RPORT(3389),
OptBool.new('TLS', [true, 'Wheter or not request TLS security', true]),
OptBool.new('CredSSP', [true, 'Whether or not to request CredSSP', true]),
OptBool.new('EarlyUser', [true, 'Whether to support Earlier User Authorization Result PDU', false])
]
)
end
# any TPKT v3 + x.2224 COTP Connect Confirm
RDP_RE = /^\x03\x00.{3}\xd0.{5}.*$/
def rdp?
sock.put(@probe)
response = sock.get_once(-1)
if response
if RDP_RE.match(response)
# XXX: it might be helpful to decode the response and show what was selected.
print_good("Identified RDP")
return true
else
vprint_status("No match for '#{Rex::Text.to_hex_ascii(response)}'")
end
else
vprint_status("No response")
end
end
def setup
# build a simple TPKT v3 + x.224 COTP Connect Request. optionally append
# RDP negotiation request with TLS, CredSSP and Early User as requesteste
requested_protocols = 0
if datastore['TLS']
requested_protocols = requested_protocols ^ 0b1
end
if datastore['CredSSP']
requested_protocols = requested_protocols ^ 0b10
end
if datastore['EarlyUser']
requested_protocols = requested_protocols ^ 0b1000
end
if requested_protocols == 0
tpkt_len = 11
cotp_len = 6
pack = [ 3, 0, tpkt_len, cotp_len, 0xe0, 0, 0, 0 ]
pack_string = "CCnCCnnC"
else
tpkt_len = 19
cotp_len = 14
pack = [ 3, 0, tpkt_len, cotp_len, 0xe0, 0, 0, 0, 1, 0, 8, 0, requested_protocols ]
pack_string = "CCnCCnnCCCCCV"
end
@probe = pack.pack(pack_string)
end
def run_host(_ip)
begin
connect
return unless rdp?
rescue Rex::AddressInUse, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, \
::Errno::ETIMEDOUT, ::Timeout::Error, ::EOFError => e
vprint_error("error while connecting and negotiating RDP: #{e}")
return
ensure
disconnect
end
report_service(
host: rhost,
port: rport,
proto: 'tcp',
name: 'RDP'
)
end
end