Skip to content

Commit 618d1b9

Browse files
committed
Land rapid7#8734, Add RDP scanner module
2 parents 39b2e82 + 45f81f3 commit 618d1b9

File tree

2 files changed

+170
-0
lines changed

2 files changed

+170
-0
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
## Vulnerable Application
2+
3+
Any system exposing the remote desktop protocol, RDP, typically on 3389/TCP.
4+
5+
## Verification Steps
6+
7+
1. Do: ```use auxiliary/scanner/rdp/rdp_scanner```
8+
2. Do: ```set [RHOSTS]```, replacing ```[RHOSTS]``` with a list of hosts to test for the presence of RDP
9+
3. Do: ```run```
10+
4. If the host is exposing an identifiable RDP instance, it will print the endpoint.
11+
12+
## Options
13+
14+
There are three options currently supported that control what security protocols to
15+
send in the RDP negotiation request, which can be helpful in identifying RDP
16+
endpoints that might be locked down or configured differently:
17+
18+
**TLS** Set to true to request TLS security support
19+
**CredSSP** Set to true to request CredSSP support
20+
**EarlyUser** Set to true to request Early User Authorization Result PDU support
21+
22+
## Scenarios
23+
24+
```
25+
msf auxiliary(rdp_scanner) > run
26+
27+
[+] 10.4.18.26:3389 - Identified RDP
28+
[+] 10.4.18.22:3389 - Identified RDP
29+
[+] 10.4.18.89:3389 - Identified RDP
30+
[+] 10.4.18.9:3389 - Identified RDP
31+
[+] 10.4.18.67:3389 - Identified RDP
32+
[+] 10.4.18.80:3389 - Identified RDP
33+
[+] 10.4.18.34:3389 - Identified RDP
34+
[+] 10.4.18.70:3389 - Identified RDP
35+
[+] 10.4.18.30:3389 - Identified RDP
36+
[+] 10.4.18.76:3389 - Identified RDP
37+
[+] 10.4.18.13:3389 - Identified RDP
38+
[+] 10.4.18.91:3389 - Identified RDP
39+
[+] 10.4.18.5:3389 - Identified RDP
40+
[+] 10.4.18.47:3389 - Identified RDP
41+
[+] 10.4.18.41:3389 - Identified RDP
42+
[+] 10.4.18.105:3389 - Identified RDP
43+
[*] Scanned 44 of 256 hosts (17% complete)
44+
[*] Scanned 55 of 256 hosts (21% complete)
45+
[+] 10.4.18.118:3389 - Identified RDP
46+
[+] 10.4.18.108:3389 - Identified RDP
47+
[+] 10.4.18.139:3389 - Identified RDP
48+
[*] Scanned 94 of 256 hosts (36% complete)
49+
[*] Scanned 110 of 256 hosts (42% complete)
50+
[+] 10.4.18.157:3389 - Identified RDP
51+
[+] 10.4.18.166:3389 - Identified RDP
52+
[+] 10.4.18.164:3389 - Identified RDP
53+
[+] 10.4.18.170:3389 - Identified RDP
54+
[+] 10.4.18.185:3389 - Identified RDP
55+
[+] 10.4.18.209:3389 - Identified RDP
56+
[+] 10.4.18.188:3389 - Identified RDP
57+
[*] Scanned 156 of 256 hosts (60% complete)
58+
[+] 10.4.18.237:3389 - Identified RDP
59+
[+] 10.4.18.225:3389 - Identified RDP
60+
[*] Scanned 186 of 256 hosts (72% complete)
61+
[*] Scanned 194 of 256 hosts (75% complete)
62+
[*] Scanned 208 of 256 hosts (81% complete)
63+
[*] Scanned 253 of 256 hosts (98% complete)
64+
[*] Scanned 256 of 256 hosts (100% complete)
65+
[*] Auxiliary module execution completed
66+
```
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
##
2+
# This module requires Metasploit: http://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
class MetasploitModule < Msf::Auxiliary
7+
include Msf::Exploit::Remote::Tcp
8+
include Msf::Auxiliary::Scanner
9+
include Msf::Auxiliary::Report
10+
11+
def initialize(info = {})
12+
super(
13+
update_info(
14+
info,
15+
'Name' => 'Identify endpoints speaking the Remote Desktop Protocol (RDP)',
16+
'Description' => %q(
17+
This module attempts to connect to the specified Remote Desktop Protocol port
18+
and determines if it speaks RDP.
19+
),
20+
'Author' => 'Jon Hart <jon_hart[at]rapid7.com>',
21+
'References' =>
22+
[
23+
['URL', 'https://msdn.microsoft.com/en-us/library/cc240445.aspx']
24+
],
25+
'License' => MSF_LICENSE
26+
)
27+
)
28+
29+
register_options(
30+
[
31+
Opt::RPORT(3389),
32+
OptBool.new('TLS', [true, 'Wheter or not request TLS security', true]),
33+
OptBool.new('CredSSP', [true, 'Whether or not to request CredSSP', true]),
34+
OptBool.new('EarlyUser', [true, 'Whether to support Earlier User Authorization Result PDU', false])
35+
]
36+
)
37+
end
38+
39+
# any TPKT v3 + x.2224 COTP Connect Confirm
40+
RDP_RE = /^\x03\x00.{3}\xd0.{5}.*$/
41+
def rdp?
42+
sock.put(@probe)
43+
response = sock.get_once(-1)
44+
if response
45+
if RDP_RE.match?(response)
46+
# XXX: it might be helpful to decode the response and show what was selected.
47+
print_good("Identified RDP")
48+
return true
49+
else
50+
vprint_status("No match for '#{Rex::Text.to_hex_ascii(response)}'")
51+
end
52+
else
53+
vprint_status("No response")
54+
end
55+
end
56+
57+
def setup
58+
# build a simple TPKT v3 + x.224 COTP Connect Request. optionally append
59+
# RDP negotiation request with TLS, CredSSP and Early User as requesteste
60+
requested_protocols = 0
61+
if datastore['TLS']
62+
requested_protocols = requested_protocols ^ 0b1
63+
end
64+
if datastore['CredSSP']
65+
requested_protocols = requested_protocols ^ 0b10
66+
end
67+
if datastore['EarlyUser']
68+
requested_protocols = requested_protocols ^ 0b1000
69+
end
70+
71+
if requested_protocols == 0
72+
tpkt_len = 11
73+
cotp_len = 6
74+
pack = [ 3, 0, tpkt_len, cotp_len, 0xe0, 0, 0, 0 ]
75+
pack_string = "CCnCCnnC"
76+
else
77+
tpkt_len = 19
78+
cotp_len = 14
79+
pack = [ 3, 0, tpkt_len, cotp_len, 0xe0, 0, 0, 0, 1, 0, 8, 0, requested_protocols ]
80+
pack_string = "CCnCCnnCCCCCV"
81+
end
82+
@probe = pack.pack(pack_string)
83+
end
84+
85+
def run_host(_ip)
86+
begin
87+
connect
88+
return unless rdp?
89+
rescue Rex::AddressInUse, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, \
90+
::Errno::ETIMEDOUT, ::Timeout::Error, ::EOFError => e
91+
vprint_error("error while connecting and negotiating RDP: #{e}")
92+
return
93+
ensure
94+
disconnect
95+
end
96+
97+
report_service(
98+
host: rhost,
99+
port: rport,
100+
proto: 'tcp',
101+
name: 'RDP'
102+
)
103+
end
104+
end

0 commit comments

Comments
 (0)