-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathrdp-vuln-ms12-020.nse
223 lines (201 loc) · 8.68 KB
/
rdp-vuln-ms12-020.nse
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
local bin = require "bin"
local nmap = require "nmap"
local shortport = require "shortport"
local stdnse = require "stdnse"
local vulns = require "vulns"
description = [[
Checks if a machine is vulnerable to MS12-020 RDP vulnerability.
The Microsoft bulletin MS12-020 patches two vulnerabilities: CVE-2012-0152
which addresses a denial of service vulnerability inside Terminal Server, and
CVE-2012-0002 which fixes a vulnerability in Remote Desktop Protocol. Both are
part of Remote Desktop Services.
The script works by checking for the CVE-2012-0152 vulnerability. If this
vulnerability is not patched, it is assumed that CVE-2012-0002 is not patched
either. This script can do its check without crashing the target.
The way this works follows:
* Send one user request. The server replies with a user id (call it A) and a channel for that user.
* Send another user request. The server replies with another user id (call it B) and another channel.
* Send a channel join request with requesting user set to A and requesting channel set to B. If the server replies with a success message, we conclude that the server is vulnerable.
* In case the server is vulnerable, send a channel join request with the requesting user set to B and requesting channel set to B to prevent the chance of a crash.
References:
* http://technet.microsoft.com/en-us/security/bulletin/ms12-020
* http://support.microsoft.com/kb/2621440
* http://zerodayinitiative.com/advisories/ZDI-12-044/
* http://aluigi.org/adv/termdd_1-adv.txt
Original check by by Worawit Wang (sleepya).
]]
---
-- @usage
-- nmap -sV --script=rdp-ms12-020 -p 3389 <target>
--
-- @output
-- PORT STATE SERVICE VERSION
-- 3389/tcp open ms-wbt-server?
-- | rdp-ms12-020:
-- | VULNERABLE:
-- | MS12-020 Remote Desktop Protocol Denial Of Service Vulnerability
-- | State: VULNERABLE
-- | IDs: CVE:CVE-2012-0152
-- | Risk factor: Medium CVSSv2: 4.3 (MEDIUM) (AV:N/AC:M/Au:N/C:N/I:N/A:P)
-- | Description:
-- | Remote Desktop Protocol vulnerability that could allow remote attackers to cause a denial of service.
-- |
-- | Disclosure date: 2012-03-13
-- | References:
-- | http://technet.microsoft.com/en-us/security/bulletin/ms12-020
-- | http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0152
-- |
-- | MS12-020 Remote Desktop Protocol Remote Code Execution Vulnerability
-- | State: VULNERABLE
-- | IDs: CVE:CVE-2012-0002
-- | Risk factor: High CVSSv2: 9.3 (HIGH) (AV:N/AC:M/Au:N/C:C/I:C/A:C)
-- | Description:
-- | Remote Desktop Protocol vulnerability that could allow remote attackers to execute arbitrary code on the targeted system.
-- |
-- | Disclosure date: 2012-03-13
-- | References:
-- | http://technet.microsoft.com/en-us/security/bulletin/ms12-020
-- |_ http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0002
author = "Aleksandar Nikolic, based on python script by sleepya"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"intrusive", "vuln"}
portrule = shortport.port_or_service({3389},{"ms-wbt-server"})
action = function(host, port)
local socket = nmap.new_socket()
local status, err,response
-- see http://msdn.microsoft.com/en-us/library/cc240836%28v=prot.10%29.aspx for more info
local connectionRequestStr = "0300" -- TPKT Header version 03, reserved 0
.. "000b" -- Length
.. "06" -- X.224 Data TPDU length
.. "e0" -- X.224 Type (Connection request)
.. "0000" -- dst reference
.. "0000" -- src reference
.. "00" -- class and options
local connectionRequest = bin.pack("H",connectionRequestStr)
-- see http://msdn.microsoft.com/en-us/library/cc240836%28v=prot.10%29.aspx
local connectInitialStr = "03000065" -- TPKT Header
.. "02f080" -- Data TPDU, EOT
.. "7f655b" -- Connect-Initial
.. "040101" -- callingDomainSelector
.. "040101" -- calledDomainSelector
.. "0101ff" -- upwardFlag
.. "3019" -- targetParams + size
.. "020122" -- maxChannelIds
.. "020120" -- maxUserIds
.. "020100" -- maxTokenIds
.. "020101" -- numPriorities
.. "020100" -- minThroughput
.. "020101" -- maxHeight
.. "0202ffff" -- maxMCSPDUSize
.. "020102" -- protocolVersion
.. "3018" -- minParams + size
.. "020101" -- maxChannelIds
.. "020101" -- maxUserIds
.. "020101" -- maxTokenIds
.. "020101" -- numPriorities
.. "020100" -- minThroughput
.. "020101" -- maxHeight
.. "0201ff" -- maxMCSPDUSize
.. "020102" -- protocolVersion
.. "3019" -- maxParams + size
.. "0201ff" -- maxChannelIds
.. "0201ff" -- maxUserIds
.. "0201ff" -- maxTokenIds
.. "020101" -- numPriorities
.. "020100" -- minThroughput
.. "020101" -- maxHeight
.. "0202ffff" -- maxMCSPDUSize
.. "020102" -- protocolVersion
.. "0400" -- userData
local connectInitial = bin.pack("H",connectInitialStr)
-- see http://msdn.microsoft.com/en-us/library/cc240835%28v=prot.10%29.aspx
local userRequestStr = "0300" -- header
.. "0008" -- length
.. "02f080" -- X.224 Data TPDU (2 bytes: 0xf0 = Data TPDU, 0x80 = EOT, end of transmission)
.. "28" -- PER encoded PDU contents
local userRequest = bin.pack("H",userRequestStr)
local user1,user2
local pos
local rdp_vuln_0152 = {
title = "MS12-020 Remote Desktop Protocol Denial Of Service Vulnerability",
IDS = {CVE = 'CVE-2012-0152'},
risk_factor = "Medium",
scores = {
CVSSv2 = "4.3 (MEDIUM) (AV:N/AC:M/Au:N/C:N/I:N/A:P)",
},
description = [[
Remote Desktop Protocol vulnerability that could allow remote attackers to cause a denial of service.
]],
references = {
'http://technet.microsoft.com/en-us/security/bulletin/ms12-020',
},
dates = {
disclosure = {year = '2012', month = '03', day = '13'},
},
exploit_results = {},
}
local rdp_vuln_0002 = {
title = "MS12-020 Remote Desktop Protocol Remote Code Execution Vulnerability",
IDS = {CVE = 'CVE-2012-0002'},
risk_factor = "High",
scores = {
CVSSv2 = "9.3 (HIGH) (AV:N/AC:M/Au:N/C:C/I:C/A:C)",
},
description = [[
Remote Desktop Protocol vulnerability that could allow remote attackers to execute arbitrary code on the targeted system.
]],
references = {
'http://technet.microsoft.com/en-us/security/bulletin/ms12-020',
},
dates = {
disclosure = {year = '2012', month = '03', day = '13'},
},
exploit_results = {},
}
local report = vulns.Report:new(SCRIPT_NAME, host, port)
rdp_vuln_0152.state = vulns.STATE.NOT_VULN
rdp_vuln_0002.state = vulns.STATE.NOT_VULN
-- Sleep for 0.2 seconds to make sure the script works even with SYN scan.
-- Posible reason for this is that Windows resets the connection if we try to
-- reconect too fast to the same port after doing a SYN scan and not completing the
-- handshake. In my tests, sleep values above 0.1s prevent the connection reset.
stdnse.sleep(0.2)
socket:connect(host.ip, port)
status, err = socket:send(connectionRequest)
status, response = socket:receive_bytes(0)
if response ~= bin.pack("H","0300000b06d00000123400") then
--probably not rdp at all
stdnse.print_debug(1, "%s: not RDP", SCRIPT_NAME)
return nil
end
status, err = socket:send(connectInitial)
status, err = socket:send(userRequest) -- send attach user request
status, response = socket:receive_bytes(0) -- recieve attach user confirm
pos,user1 = bin.unpack(">S",response:sub(10,11)) -- user_channel-1001 - see http://msdn.microsoft.com/en-us/library/cc240918%28v=prot.10%29.aspx
status, err = socket:send(userRequest) -- send another attach user request
status, response = socket:receive_bytes(0) -- recieve another attach user confirm
pos,user2 = bin.unpack(">S",response:sub(10,11)) -- second user's channel - 1001
user2 = user2+1001 -- second user's channel
local data4 = bin.pack(">SS",user1,user2)
local data5 = bin.pack("H","0300000c02f08038") -- channel join request TPDU
local channelJoinRequest = data5 .. data4
status, err = socket:send(channelJoinRequest) -- bogus channel join request user1 requests channel of user2
status, response = socket:receive_bytes(0)
if response:sub(8,9) == bin.pack("H","3e00") then
-- 3e00 indicates a successfull join
-- see http://msdn.microsoft.com/en-us/library/cc240911%28v=prot.10%29.aspx
-- service is vulnerable
-- send a valid request to prevent the BSoD
data4 = bin.pack(">SS",user2-1001,user2)
channelJoinRequest = data5 .. data4 -- valid join request
status, err = socket:send(channelJoinRequest)
status, response = socket:receive_bytes(0)
socket:close()
rdp_vuln_0152.state = vulns.STATE.VULN
rdp_vuln_0002.state = vulns.STATE.VULN
return report:make_output(rdp_vuln_0152,rdp_vuln_0002)
end
--service is not vulnerable
socket:close()
return report:make_output(rdp_vuln_0152,rdp_vuln_0002)
end