Skip to content

Commit 93ca81a

Browse files
author
iBearcat
authored
Tests if a system is Winshock (MS14-066) vulnerable
1 parent 28ea4fb commit 93ca81a

File tree

3 files changed

+350
-0
lines changed

3 files changed

+350
-0
lines changed

MS14-066/LICENSE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2014 ANEXIA Internetdienstleistungs GmbH
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
22+

MS14-066/README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
winshock-test
2+
=============
3+
4+
Bash script that tests if a system is Winshock (MS14-066) vulnerable.
5+
6+
This script was developed by the emergency response team at [ANEXIA](http://www.anexia-wwc.com).
7+
8+
Important
9+
---------
10+
11+
winshock_test.sh does behavioural analysis based upon the available SSL ciphers.
12+
If you either do not have direct access to the target system due to SSL-offloading in any form or manually modified the available SSL ciphers the script will
13+
be giving **false positives**.
14+
15+
16+
Disclaimer
17+
----------
18+
19+
This script does in no way try to exploit the vulnerability described in MS14-066.
20+
It merely checks for hints on whether the target system has been patched or not.
21+
For details, have a look at the script itself or read the short 'How it works'
22+
part of this document below.
23+
24+
Usage
25+
-----
26+
27+
```shell
28+
./winshock_test.sh 10.0.0.1 3389
29+
./winshock_test.sh 10.0.0.2 443
30+
```
31+
32+
Be sure to use a port on which a service is listening for SSL connections,
33+
which you can actually connect to. If the script takes long to complete,
34+
chances are good that either no service is listening on that port or
35+
a firewall is blocking access to that port.
36+
37+
The examples above use the default RDP and HTTPS ports for those checks.
38+
39+
Also, please ensure you are connecting directly to the target system. A
40+
load balancer or any other form of SSL-offloading may impact the results
41+
and may generate false-positives or false-negatives.
42+
43+
44+
How it works
45+
------------
46+
47+
MS14-066 introduced four new SSL ciphers, so a check can be made if
48+
the target system supports those previously unsupported ciphers.
49+
winshock_test.sh uses this fact by simply checking if those ciphers are
50+
supported by the target system or not. If they are supported, the patches
51+
have been applied.
52+
53+
54+
55+
56+
57+
58+
59+

MS14-066/winshock_test.sh

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
#!/bin/bash
2+
#
3+
# winshock_test.sh
4+
#
5+
# This script tries to determine whether the target system has the
6+
# winshock (MS14-066) patches applied or not.
7+
# This is done by checking if the SSL ciphers introduced by MS14-066 are
8+
# available on the system.
9+
#
10+
#
11+
# Authors:
12+
# Stephan Peijnik <[email protected]>
13+
#
14+
# The MIT License (MIT)
15+
#
16+
# Copyright (c) 2014 ANEXIA Internetdienstleistungs GmbH
17+
#
18+
# Permission is hereby granted, free of charge, to any person obtaining a copy
19+
# of this software and associated documentation files (the "Software"), to deal
20+
# in the Software without restriction, including without limitation the rights
21+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
22+
# copies of the Software, and to permit persons to whom the Software is
23+
# furnished to do so, subject to the following conditions:
24+
#
25+
# The above copyright notice and this permission notice shall be included in all
26+
# copies or substantial portions of the Software.
27+
#
28+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
31+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
33+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34+
# SOFTWARE.
35+
36+
VERSION=0.2.1
37+
HOST=$1
38+
PORT=${2:-443}
39+
40+
if [ -z "$HOST" -o -z "$PORT" ]
41+
then
42+
echo "Usage: $0 host [port]"
43+
echo "port defaults to 443."
44+
exit 1
45+
fi
46+
47+
echo "Checking if script is up-to-date..."
48+
REMOTE_VERSION=$(curl -k https://raw.githubusercontent.com/anexia-it/winshock-test/master/winshock_test.sh 2>/dev/null | grep '^VERSION=' | sed -e 's/^VERSION=//g')
49+
50+
if [[ "$REMOTE_VERSION" != "$VERSION" ]]
51+
then
52+
echo -e "\033[91mYou are running an outdated version of this script."
53+
echo "The most recent version is $REMOTE_VERSION."
54+
echo -e "It is highly recommended to update your script first.\033[0m"
55+
read -p "Do you want to continue? (y/N) " -n 1 -r
56+
if [[ ! "$REPLY" =~ ^[Yy]$ ]]
57+
then
58+
exit 2
59+
fi
60+
else
61+
echo "Script is up-to-date."
62+
fi
63+
64+
echo -e "\n\033[91m"
65+
cat <<IMP
66+
*** IMPORTANT ***
67+
This script is intended to give you a hint on whether the MS14-66 patches
68+
have been installed or not.
69+
70+
Please do NOT rely on the results this script is giving, as the correctness
71+
of the results can be impacted by manual modifications of cipher suites
72+
with tools like IIS Crypto or load balancers or SSL-offloaders between
73+
you and the target host.
74+
75+
Also, this script is unreliable if the target system is running
76+
Windows Server 2012 R2, as the ciphers this script is testing for were present
77+
on Windows Server 2012 R2 without the MS14-066 updates as well.
78+
If the checks are executed against IIS the result for Windows Server 2012 R2
79+
will be presented as "UNKNOWN".
80+
IMP
81+
82+
echo -e "\033[93m"
83+
84+
cat <<WARN
85+
*** WARNING ***
86+
A negative result presented by this script does NOT mean that you do not
87+
have to install the MS14-66 patches on the target system.
88+
Make sure to update all your Windows installations, regardless of the
89+
results this script gives you.
90+
91+
WARN
92+
93+
echo -e "\033[0m"
94+
read -p "I have read and understood the messages above. (y/N) " -n 1 -r
95+
if [[ ! "$REPLY" =~ ^[yY]$ ]]
96+
then
97+
echo -e "\n\033[91mAborting. Please re-run and confirm that you have read and understood the messages above.\033[0m"
98+
exit 4
99+
fi
100+
echo ""
101+
102+
# According to https://technet.microsoft.com/library/security/ms14-066 the
103+
# following ciphers were added with the patch:
104+
# * TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
105+
# * TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
106+
# * TLS_RSA_WITH_AES_256_GCM_SHA384
107+
# * TLS_RSA_WITH_AES_128_GCM_SHA256
108+
#
109+
# The OpenSSL cipher names for these ciphers are:
110+
MS14_066_CIPHERS="DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES128-GCM-SHA256 AES256-GCM-SHA384 AES128-GCM-SHA256"
111+
# Ciphers supported by Windows Server 2012R2
112+
WINDOWS_SERVER_2012R2_CIPHERS="ECDHE-RSA-AES256-SHA384 ECDHE-RSA-AES256-SHA"
113+
114+
# Test if OpenSSL does support the ciphers we're checking for...
115+
echo -n "Testing if OpenSSL supports the ciphers we are checking for: "
116+
openssl_ciphers=$(openssl ciphers)
117+
118+
for c in $MS14_066_CIPHERS
119+
do
120+
if ! echo $openssl_ciphers | grep -q $c 2>&1 >/dev/null
121+
then
122+
echo -e "\033[91mNO (OpenSSL does not support $c cipher.)\033[0m"
123+
echo -e "\033[91mAborting."
124+
exit 5
125+
fi
126+
done
127+
128+
echo -e "\033[92mYES\033[0m"
129+
130+
SERVER=$HOST:$PORT
131+
132+
echo -e "\n\033[94mTesting ${SERVER} for availability of SSL ciphers added in MS14-066...\033[0m"
133+
134+
patched="no"
135+
for cipher in ${MS14_066_CIPHERS}
136+
do
137+
echo -en "Testing cipher ${cipher}: "
138+
result=$(echo -n | openssl s_client -cipher "$cipher" -connect $SERVER 2>&1)
139+
if [[ "$result" =~ "connect:errno=" ]]
140+
then
141+
err=$(echo $result | grep ^connect: \
142+
| sed -e 's/connect:errno=.*//g' -e 's/connect: //g')
143+
echo -e "\033[93mConnection error: $err"
144+
echo -e "Aborting checks.\033[0m"
145+
exit 1
146+
elif [[ "$result" =~ "SSL23_GET_SERVER_HELLO:unknown protocol" ]]
147+
then
148+
echo -e "\033[93mNo SSL/TLS support on target port."
149+
echo -e "Aborting checks.\033[0m"
150+
exit 1
151+
elif [[ "$result" =~ "SSL_CTX_set_cipher_list:no cipher match" ]]
152+
then
153+
echo -e "\033[93mYour version of OpenSSL is not supported."
154+
echo -e "Aborting checks.\033[39m"
155+
exit 1
156+
elif [[ "$result" =~ "Cipher is ${cipher}" || "$result" =~ "Cipher : ${cipher}" ]]
157+
then
158+
echo -e "\033[92mSUPPORTED\033[0m"
159+
if [[ "$patched" == "no" ]]
160+
then
161+
patched="yes"
162+
fi
163+
else
164+
echo -e "\033[91mUNSUPPORTED\033[0m"
165+
fi
166+
done
167+
168+
windows_server_2012_or_later="no"
169+
windows_server_2012_r2="no"
170+
iis_detected="no"
171+
# added by @stoep: check whether a 443 port runs IIS
172+
if [[ "$PORT" == "443" ]]
173+
then
174+
iis=$(curl -k -I https://$SERVER 2> /dev/null | grep "Server" )
175+
echo -n "Testing if IIS is running on port 443: "
176+
if [[ $iis == *Microsoft-IIS* ]]
177+
then
178+
iis_version=$(echo $iis | sed -e 's|Server: Microsoft-IIS/||g')
179+
iis_detected="yes"
180+
echo -e "\033[92mYES - Version ${iis_version}\033[0m"
181+
if [[ $iis_version == *8.5* ]]
182+
then
183+
echo -e "\033[91mWindows Server 2012 R2 detected. Results of this script will be inconclusive.\033[0m"
184+
windows_server_2012_or_later="yes"
185+
windows_server_2012_r2="yes"
186+
elif [[ $iis_version == *8.0* ]]
187+
then
188+
windows_server_2012_or_later="yes"
189+
windows_server_2012_r2="no"
190+
fi
191+
else
192+
echo -e "\033[91mNO\033[0m"
193+
fi
194+
fi
195+
196+
# Check if Windows Server 2012 or later is running on the remote system...
197+
if [[ "$windows_server_2012_or_later" == "no" && "$iis_detected" == "no" ]]
198+
then
199+
echo -e "\033[94mChecking if target system is running Windows Server 2012 or later...\033[0m"
200+
for cipher in ${WINDOWS_SERVER_2012R2_CIPHERS}
201+
do
202+
echo -en "Testing cipher ${cipher}: "
203+
result=$(echo -n | openssl s_client -cipher "$cipher" -connect $SERVER 2>&1)
204+
if [[ "$result" =~ "connect:errno=" ]]
205+
then
206+
err=$(echo $result | grep ^connect: \
207+
| sed -e 's/connect:errno=.*//g' -e 's/connect: //g')
208+
echo -e "\033[93mConnection error: $err"
209+
echo -e "Aborting checks.\033[0m"
210+
exit 1
211+
elif [[ "$result" =~ "SSL23_GET_SERVER_HELLO:unknown protocol" ]]
212+
then
213+
echo -e "\033[93mNo SSL/TLS support on target port."
214+
echo -e "Aborting checks.\033[0m"
215+
exit 1
216+
elif [[ "$result" =~ "Cipher is ${cipher}" || "$result" =~ "Cipher : ${cipher}" ]]
217+
then
218+
echo -e "\033[92mSUPPORTED\033[0m"
219+
if [[ "$windows_server_2012_or_later" == "no" ]]
220+
then
221+
windows_server_2012_or_later="yes"
222+
break
223+
fi
224+
else
225+
echo -e "\033[91mUNSUPPORTED\033[0m"
226+
fi
227+
done
228+
fi
229+
230+
if [[ "$patched" == "yes" && "$windows_server_2012_or_later" == "no" ]]
231+
then
232+
patched="\033[92mYES\033[0m"
233+
elif [[ "$patched" == "yes" ]]
234+
then
235+
patched="\033[93mUNKNOWN"
236+
if [[ "$windows_server_2012_r2" == "yes" ]]
237+
then
238+
patched="$patched: Windows Server 2012 R2 detected."
239+
else
240+
patched="$patched: Windows Server 2012 or later detected."
241+
fi
242+
else
243+
patched="\033[91mNO\033[0m"
244+
fi
245+
246+
echo -e "\033[94m$SERVER is patched: $patched\033[0m"
247+
echo -e "\n\033[93m"
248+
cat <<EOF
249+
*** IMPORTANT ***
250+
251+
Please keep in mind that the patch-status reported above is only a hint and
252+
may generate both false-positive and false-negative results in some cases.
253+
254+
If Windows Server 2012 R2 is reported above results WIIL BE incorrect.
255+
If Windows Server 2012 or later is reported above results MAY BE incorrect,
256+
please test again against IIS running on port 443.
257+
258+
The information above may be incorrect if:
259+
260+
* the available SSL ciphers have been modified manually
261+
* you are not directly connecting to the target system
262+
* the target system is running Windows Server 2012 R2
263+
264+
Please do apply the MS14-066 patches to all your systems regardless
265+
of the results presented above!
266+
267+
EOF
268+
echo -en "\033[0m"
269+
exit 0

0 commit comments

Comments
 (0)