MS14-066 Schannel Scanner
The idea to identify the vulnerabiltiy is:
- if at least one ciphers from the ones below is supported, then the vulneability should not be present (i.e. patch applied)
- if none of the ciphers below is supported then the server might be affected by ms14-066
Ciphers:
DHE-RSA-AES256-SHA256
DHE-RSA-AES256-GCM-SHA384
AES128-GCM-SHA256
AES256-GCM-SHA384
Manual approach: use SSLscan or nmap
Launch the tools below with the following command:
(i.e. specify bash)
Useful Links:
- if at least one ciphers from the ones below is supported, then the vulneability should not be present (i.e. patch applied)
- if none of the ciphers below is supported then the server might be affected by ms14-066
Ciphers:
DHE-RSA-AES256-SHA256
DHE-RSA-AES256-GCM-SHA384
AES128-GCM-SHA256
AES256-GCM-SHA384
Manual approach: use SSLscan or nmap
nmap -v -p443 -n --script ssl-enum-ciphers
Launch the tools below with the following command:
>bash script.sh
(i.e. specify bash)
- https://raw.githubusercontent.com/cudeso/security-tools/master/scanners/MSFT1466test.sh
#!/bin/sh
###############
#
# (c) SANS Internet Storm Center 2014 ; https://isc.sans.edu
#
# This code is free to use / modify as long as it is attributed
# contact handlers@sans.edu for feedback.
# (thanks to @0xmitsurugi and Dan Fayette for providing some updates)
#
###############
# if your copy of openssl is not in your path, please add full path here
# Note for example that for OS X, the default install uses openssl 0.9.8,
# which will not work. If you install openssl 1.0.1 from Macports, you
# have to change this line to openssl="/opt/local/bin/openssl"
openssl="openssl"
ciphers="DHE-RSA-AES256-SHA256 DHE-RSA-AES256-GCM-SHA384 AES128-GCM-SHA256 AES256-GCM-SHA384"
########
#
# no changes needed beyond this point
#
########
program=$0
host=$1
port=$2
#
# copied from http://www.linuxjournal.com/content/validating-ip-address-bash-script
#
function valid_ip()
{
local ip=$1
local stat=1
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
OIFS=$IFS
IFS='.'
ip=($ip)
IFS=$OIFS
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
stat=$?
fi
return $stat
}
if ! $openssl ciphers | grep -q DHE-RSA-AES256-SHA256 ; then
echo "your version of openssl does not support the required ciphers."
echo "upgrade to the latest version (1.0.1h or later)"
exit
fi
if [ -z "$port" ] ; then
port=443
fi
if [ -z "$host" ] ; then
echo "usage: $program hostname [port]"
exit
fi
if ! host "$host" > /dev/null ; then
if ! valid_ip $host; then
echo "ERROR: host $host does not resolve to an IP address";
exit
fi
fi
#
# check if we can connect via SSL at all
#
if ! openssl s_client -connect $host:$port < /dev/null 2>/dev/null >/dev/null; then
echo "Can not connect to server. Verify IP address and Port"
exit
fi
if openssl s_client -connect $host:$port < /dev/null 2>&1 | grep -q 'unknown protocol'; then
echo "This is not an SSL server."
exit
fi
#
# check if TLS 1.2 is supported at all
#
if $openssl s_client -connect $host:$port -tls1_2 < /dev/null 2>&1 | grep -q 'wrong version number'; then
echo "ERROR: The server does not support TLS 1.2 at all. This script will not produce meaningful results and will not run.";
exit
fi
ciphers="DHE-RSA-AES256-SHA256 DHE-RSA-AES256-GCM-SHA384 AES128-GCM-SHA256 AES256-GCM-SHA384"
s=0
for b in $ciphers; do
if $openssl s_client -cipher $b -connect $host:$port < /dev/null 2>&1 | grep -q 'handshake failure'; then
output="- $b not supported\n$output"
else
output="+ $b is supported\n$output"
s=$((s+1))
fi
done
if [ "$s" -gt "0" ] ; then
echo "*** TEST PASS ***"
echo "You are supporting $s out of 4 new ciphers. You likely patched for MS14-066.\n"
else
echo "*** TEST FAIL ***"
echo "You are not supporting any of the new ciphers. You likely didn't patch for MS14-066\n";
fi
echo $output
echo
echo "Note: This test ONLY checks the new ciphers. Loadbalancers, web application firewalls, or specific SSL configurations may give false results. Feedback: handlers@sans.edu"
- https://raw.githubusercontent.com/anexia-it/winshock-test/master/winshock_test.sh
#!/bin/bash
#
# winshock_test.sh
#
# This script tries to determine whether the target system has the
# winshock (MS14-066) patches applied or not.
# This is done by checking if the SSL ciphers introduced by MS14-066 are
# available on the system.
#
#
# Authors:
# Stephan Peijnik
#
# The MIT License (MIT)
#
# Copyright (c) 2014 ANEXIA Internetdienstleistungs GmbH
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
VERSION=0.2.1
HOST=$1
PORT=${2:-443}
if [ -z "$HOST" -o -z "$PORT" ]
then
echo "Usage: $0 host [port]"
echo "port defaults to 443."
exit 1
fi
echo "Checking if script is up-to-date..."
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')
if [[ "$REMOTE_VERSION" != "$VERSION" ]]
then
echo -e "\033[91mYou are running an outdated version of this script."
echo "The most recent version is $REMOTE_VERSION."
echo -e "It is highly recommended to update your script first.\033[0m"
read -p "Do you want to continue? (y/N) " -n 1 -r
if [[ ! "$REPLY" =~ ^[Yy]$ ]]
then
exit 2
fi
else
echo "Script is up-to-date."
fi
echo -e "\n\033[91m"
cat <&1 >/dev/null
then
echo -e "\033[91mNO (OpenSSL does not support $c cipher.)\033[0m"
echo -e "\033[91mAborting."
exit 5
fi
done
echo -e "\033[92mYES\033[0m"
SERVER=$HOST:$PORT
echo -e "\n\033[94mTesting ${SERVER} for availability of SSL ciphers added in MS14-066...\033[0m"
patched="no"
for cipher in ${MS14_066_CIPHERS}
do
echo -en "Testing cipher ${cipher}: "
result=$(echo -n | openssl s_client -cipher "$cipher" -connect $SERVER 2>&1)
if [[ "$result" =~ "connect:errno=" ]]
then
err=$(echo $result | grep ^connect: \
| sed -e 's/connect:errno=.*//g' -e 's/connect: //g')
echo -e "\033[93mConnection error: $err"
echo -e "Aborting checks.\033[0m"
exit 1
elif [[ "$result" =~ "SSL23_GET_SERVER_HELLO:unknown protocol" ]]
then
echo -e "\033[93mNo SSL/TLS support on target port."
echo -e "Aborting checks.\033[0m"
exit 1
elif [[ "$result" =~ "SSL_CTX_set_cipher_list:no cipher match" ]]
then
echo -e "\033[93mYour version of OpenSSL is not supported."
echo -e "Aborting checks.\033[39m"
exit 1
elif [[ "$result" =~ "Cipher is ${cipher}" || "$result" =~ "Cipher : ${cipher}" ]]
then
echo -e "\033[92mSUPPORTED\033[0m"
if [[ "$patched" == "no" ]]
then
patched="yes"
fi
else
echo -e "\033[91mUNSUPPORTED\033[0m"
fi
done
windows_server_2012_or_later="no"
windows_server_2012_r2="no"
iis_detected="no"
# added by @stoep: check whether a 443 port runs IIS
if [[ "$PORT" == "443" ]]
then
iis=$(curl -k -I https://$SERVER 2> /dev/null | grep "Server" )
echo -n "Testing if IIS is running on port 443: "
if [[ $iis == *Microsoft-IIS* ]]
then
iis_version=$(echo $iis | sed -e 's|Server: Microsoft-IIS/||g')
iis_detected="yes"
echo -e "\033[92mYES - Version ${iis_version}\033[0m"
if [[ $iis_version == *8.5* ]]
then
echo -e "\033[91mWindows Server 2012 R2 detected. Results of this script will be inconclusive.\033[0m"
windows_server_2012_or_later="yes"
windows_server_2012_r2="yes"
elif [[ $iis_version == *8.0* ]]
then
windows_server_2012_or_later="yes"
windows_server_2012_r2="no"
fi
else
echo -e "\033[91mNO\033[0m"
fi
fi
# Check if Windows Server 2012 or later is running on the remote system...
if [[ "$windows_server_2012_or_later" == "no" && "$iis_detected" == "no" ]]
then
echo -e "\033[94mChecking if target system is running Windows Server 2012 or later...\033[0m"
for cipher in ${WINDOWS_SERVER_2012R2_CIPHERS}
do
echo -en "Testing cipher ${cipher}: "
result=$(echo -n | openssl s_client -cipher "$cipher" -connect $SERVER 2>&1)
if [[ "$result" =~ "connect:errno=" ]]
then
err=$(echo $result | grep ^connect: \
| sed -e 's/connect:errno=.*//g' -e 's/connect: //g')
echo -e "\033[93mConnection error: $err"
echo -e "Aborting checks.\033[0m"
exit 1
elif [[ "$result" =~ "SSL23_GET_SERVER_HELLO:unknown protocol" ]]
then
echo -e "\033[93mNo SSL/TLS support on target port."
echo -e "Aborting checks.\033[0m"
exit 1
elif [[ "$result" =~ "Cipher is ${cipher}" || "$result" =~ "Cipher : ${cipher}" ]]
then
echo -e "\033[92mSUPPORTED\033[0m"
if [[ "$windows_server_2012_or_later" == "no" ]]
then
windows_server_2012_or_later="yes"
break
fi
else
echo -e "\033[91mUNSUPPORTED\033[0m"
fi
done
fi
if [[ "$patched" == "yes" && "$windows_server_2012_or_later" == "no" ]]
then
patched="\033[92mYES\033[0m"
elif [[ "$patched" == "yes" ]]
then
patched="\033[93mUNKNOWN"
if [[ "$windows_server_2012_r2" == "yes" ]]
then
patched="$patched: Windows Server 2012 R2 detected."
else
patched="$patched: Windows Server 2012 or later detected."
fi
else
patched="\033[91mNO\033[0m"
fi
echo -e "\033[94m$SERVER is patched: $patched\033[0m"
echo -e "\n\033[93m"
cat <
- https://gist.github.com/hugsy/7a58714120cdbc110699
#!/bin/bash
#
# @_hugsy_
#
# Simple (harmless) to test if target is vulnerable to SChannel() memory corruption - MS14-066
#
# It uses the fact that MS added 4 new cipher suites to the patch
# TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
# TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
# TLS_RSA_WITH_AES_256_GCM_SHA384
# TLS_RSA_WITH_AES_128_GCM_SHA256
# A system is *potentially* vulnerable if it doesn't support any of them.
#
# Refs:
# https://technet.microsoft.com/library/security/ms14-066
# https://support.microsoft.com/kb/2992611
#
# set -x
if [ $# -ne 1 ]; then
echo "Usage: $0 vhost:port"
echo "Example: $0 bing.com:443"
exit 1
fi
host=$1
n=0
function is_iis() {
ret="`curl --silent --head https://${host} | egrep -i '^Server: Microsoft-IIS'`"
if [ x"${ret}" == x"" ]; then
echo "[-] Server is *not* IIS"
exit 1
else
echo "[+] Server is IIS version: `echo ${ret} | cut -d ' ' -f 2`"
fi
}
function connect() {
cipher=$1
req="`echo Q | openssl s_client -verify_return_error -cipher ${cipher} -connect ${host} 2>&1`"
# check if it's ssl first
test -n "$(echo $req | grep 'SSL23_GET_SERVER_HELLO:unknown protocol')" && exit 1
# check for new cipher
test -n "$(echo $req | grep 'Cipher is (NONE)')" && n=$((n + 1))
}
is_iis
for c in DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES128-GCM-SHA256 AES256-GCM-SHA384 AES128-GCM-SHA256;
do
connect $c
done
case $n in
4) echo "[+] ${host} is vulnerable";;
*) echo "[-] ${host} is not vulnerable";;
esac
exit 0
Useful Links:
- https://support.microsoft.com/en-us/kb/2992611
- http://www.r00tsec.com/2014/11/list-of-resource-for-ms14-066.html
- http://www.securitysift.com/exploiting-ms14-066-cve-2014-6321-aka-winshock/
- https://raw.githubusercontent.com/cudeso/security-tools/master/scanners/MSFT1466test.sh
- https://raw.githubusercontent.com/anexia-it/winshock-test/master/winshock_test.sh
- https://gist.github.com/hugsy/7a58714120cdbc110699
- http://blog.beyondtrust.com/triggering-ms14-066
- http://www.malwaretech.com/2014/11/how-ms14-066-winshock-is-worse-than.html
- http://www.securitysift.com/exploiting-ms14-066-cve-2014-6321-aka-winshock/
- https://www.reddit.com/r/AskNetsec/comments/2q5zhj/where_can_i_get_poc_code_for_ms14066_aka_schannel/
- https://technet.microsoft.com/en-us/library/security/ms14-066.aspx
- http://www.guidepointsecurity.com/1040/vulnerability-management/a-shock-19-years-in-the-making-microsofts-critical-winshock-vulnerability-ms14-066/
- http://darrenmyher.com/2014/11/13/security-update-ms14-066-causes-major-performance-in-microsoft-access-sql-server-applications/