How to Disable Weak SSL Protocols and Ciphers in IIS
I recently undertook the process of moving websites to different servers here at work. This required that university networking group scan the new webserver with a tool called Nessus. Unfortunately this turned up several errors, all of them had to do with Secure Sockets Layer or SSL which in Microsoft Windows Server 2003 / Internet Information Server 6 out of the box support both unsecure protocols and cipher suites. These problems would have to be solved before they would allow the new server though the firewalls. The report they university sent me was generated by Nessus generated errors like this:
SSL Version 2 (v2) Protocol Detection
Synopsis :
The remote service encrypts traffic using a protocol with known
weaknesses.
Description :
The remote service accepts connections encrypted using SSL 2.0, which
reportedly suffers from several cryptographic flaws and has been
deprecated for several years. An attacker may be able to exploit
these issues to conduct man-in-the-middle attacks or decrypt
communications between the affected service and clients.
See also :
http://www.schneier.com/paper-ssl.pdf
http://support.microsoft.com/kb/187498
http://www.linux4beginners.info/node/disable-sslv2
Solution :
Consult the application's documentation to disable SSL 2.0 and use SSL
3.0 or TLS 1.0 instead.
Risk factor :
Medium / CVSS Base Score : 5.0
(CVSS2#AV:N/AC:L/Au:N/C:P/I:N/A:N)
Nessus ID : 20007
----------------------------------------------------------
SSL Medium Strength Cipher Suites Supported
Synopsis :
The remote service supports the use of medium strength SSL ciphers.
Description :
The remote host supports the use of SSL ciphers that offer medium
strength encryption, which we currently regard as those with key
lengths at least 56 bits and less than 112 bits.
Note: This is considerably easier to exploit if the attacker is on the
same physical network.
Solution :
Reconfigure the affected application if possible to avoid use of
medium strength ciphers.
Risk factor :
Medium / CVSS Base Score : 4.3
(CVSS2#AV:N/AC:M/Au:N/C:P/I:N/A:N)
Plugin output :
Here are the medium strength SSL ciphers supported by the remote server :
Medium Strength Ciphers (>= 56-bit and < 112-bit key)
SSLv2
DES-CBC-MD5 Kx=RSA Au=RSA Enc=DES(56) Mac=MD5
SSLv3
DES-CBC-SHA Kx=RSA Au=RSA Enc=DES(56) Mac=SHA1
TLSv1
EXP1024-DES-CBC-SHA Kx=RSA(1024) Au=RSA Enc=DES(56) Mac=SHA1 export
EXP1024-RC4-SHA Kx=RSA(1024) Au=RSA Enc=RC4(56) Mac=SHA1 export
DES-CBC-SHA Kx=RSA Au=RSA Enc=DES(56) Mac=SHA1
The fields above are :
{OpenSSL ciphername}
Kx={key exchange}
Au={authentication}
Enc={symmetric encryption method}
Mac={message authentication code}
{export flag}
Nessus ID : 42873
--------------------------------------------------------------------
SSL Weak Cipher Suites Supported
Synopsis :
The remote service supports the use of weak SSL ciphers.
Description :
The remote host supports the use of SSL ciphers that offer either weak
encryption or no encryption at all.
Note: This is considerably easier to exploit if the attacker is on the
same physical network.
See also :
http://www.openssl.org/docs/apps/ciphers.html
Solution :
Reconfigure the affected application if possible to avoid use of weak
ciphers.
Risk factor :
Medium / CVSS Base Score : 4.3
(CVSS2#AV:N/AC:M/Au:N/C:P/I:N/A:N)
Plugin output :
Here is the list of weak SSL ciphers supported by the remote server :
Low Strength Ciphers (< 56-bit key)
SSLv2
EXP-RC2-CBC-MD5 Kx=RSA(512) Au=RSA Enc=RC2(40) Mac=MD5 export
EXP-RC4-MD5 Kx=RSA(512) Au=RSA Enc=RC4(40) Mac=MD5 export
SSLv3
EXP-RC2-CBC-MD5 Kx=RSA(512) Au=RSA Enc=RC2(40) Mac=MD5 export
EXP-RC4-MD5 Kx=RSA(512) Au=RSA Enc=RC4(40) Mac=MD5 export
TLSv1
EXP-RC2-CBC-MD5 Kx=RSA(512) Au=RSA Enc=RC2(40) Mac=MD5 export
EXP-RC4-MD5 Kx=RSA(512) Au=RSA Enc=RC4(40) Mac=MD5 export
The fields above are :
{OpenSSL ciphername}
Kx={key exchange}
Au={authentication}
Enc={symmetric encryption method}
Mac={message authentication code}
{export flag}
Other references : CWE:327, CWE:326, CWE:753, CWE:803, CWE:720
Nessus ID : 26928
-----------------------------------------------------------------
These three error messages pretty much mean that you need to turn off SSL 2.0 due to exploits that were found after the standard was created. You need to turn off any encryption suites lower than 128bits. The third error message says we need to turn off anything for less than 56bits, but this will be accomplished by turning of anything less than 128bits. Basically your are modifying the settings that restrict the use of specific protocols and ciphers that are used by the schannel.dll. More detailed information can be found at Micorsoft’s KB187498 or KB245030
How do we do this?
Disabling SSL 2.0 on IIS 6
- Open up “regedit” from the command line
- Browse to the following key:
HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server - Create a new REG_DWORD called “Enabled” and set the value to 0
- You will need to restart the computer for this change to take effect. (you can wait on this if you also need to disable the ciphers)
Disable unsecure encryption ciphers less than 128bit
- Open up “regedit” from the command line
- Browse to the following key:
HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\DES 56/56 - Create a new REG_DWORD called “Enabled” and set the value to 0
- Browse to the following key:
HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC2 40/128 - Create a new REG_DWORD called “Enabled” and set the value to 0
- Browse to the following key:
HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 40/128 - Create a new REG_DWORD called “Enabled” and set the value to 0
- Browse to the following key:
HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 56/128 - Create a new REG_DWORD called “Enabled” and set the value to 0
- You will need to restart the computer for this change to take effect.
How to verify the changes?
Now that you have made these changes how can you be sure that they have taken place without having to go to your boss or higher authority just to find that you did them wrong. Well I found a nice tool called SSL-SCAN which you can download at http://code.google.com/p/sslscan-win/ for the Windows port or you can download an compile for your favorite operating system at the original project SSL-SCAN site http://sourceforge.net/projects/sslscan/. This tool provides some great detail about what is allows and not allows plus some analysis of the SSL certificate itself.
Below the screen shot shows that we have disabled any ciphers that attempt to use the SSL 2.0 protocol and we’ve disabled all ciphers that less than 128bit.
Hardening Your Web Server’s SSL Ciphers
Disclaimer: I’m updating this post continually in order to represent what I consider the best practice in the moment – there are way too many dangerously outdated articles about TLS-deployment out there already.
Therefore it may be a good idea to check back from time to time because the crypto landscape is changing pretty quickly at the moment. You can follow me on Twitter to get notified about noteworthy changes.
If you find any factual problems, please reach out to me immediately and I will fix it ASAP.
Rationale
If you configure a web server’s SSL configuration, you have primarily to take care of three things:
- disable SSL 2.0, and – if you can afford it – SSL 3.0 (Internet Explorer 6 is the last remaining reason to keep it around; you can’t have elliptic curve crypto with SSL 3.0 and downgrade attacks exist),
- disable TLS 1.0 compression (CRIME),
- disable weak ciphers (DES, RC4), prefer modern ciphers (AES), modes (GCM), and protocols (TLS 1.2).
You should also put effort into mitigating BREACH. That’s out of scope here though as it’s largely application-dependent.
Software and Versions
On the server side, you should update your OpenSSL to 1.0.0+ so you can support TLS 1.2, GCM, and ECDH as soon as possible. Fortunately that’s already the case in the current Ubuntu LTS.
On the client side, the browser vendors are starting to catch up. As of now, Chrome 30, Internet Explorer 11 on Windows 8, Safari 7 on OS X 10.9, and Firefox 26 support TLS 1.2 (but no GCM, Chrome 32 is going to be the first one to support that). Firefox also has TLS 1.2 disabled by default which changed recently in Aurora.
RC4
There used to be a bullet point suggesting to use RC4 to avoid BEASTand Lucky Thirteen. And ironically, that used to be the original reason for this article: when Lucky Thirteen came out, the word in the streets was: “use RC4 to mitigate” and everyone was like “how!?”.
Unfortunately shortly thereafter, RC4 was broken in a way that makes deploying TLS with it nowadays a risk. While BEAST et al require an active attack on the browser of the victim, passive attacks on RC4 ciphertext are getting stronger every day. In other words: it’s possible that it will become feasible to decrypt intercepted RC4 traffic eventually. Microsoft even issued a security advisory that recommends to disable RC4.
The String
Until recently, Qualys preferred RC4 over CBC-mode ciphers and I gave you two cipher strings to choose from: one that gave you an “A” but used RC4 and one that gave you a “B” but was actually secure. Since they finally changed their mind – and as of Safari 7 there’s no mainstream browser left that is susceptible to BEAST – I can jump directly to the secure one:
ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
You can test it against your OpenSSL installation using
openssl ciphers -v 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS'
to see what’s supported.
You’ll get:
- Best possible encryption in all browsers.
- Perfect forward secrecy; if your web server, your OpenSSL, and theirbrowser support it.
- It doesn’t offer RC4 even as a fallback. Although its inclusion at the endof the cipher string shouldn’t matter, active downgrade attacks on SSL/TLS exist and having RC4 as part of the the cipher string you potentially expose all of your users to it. Even IE 6 does 3DES just fine.
The string also prefers AES-256 over AES-128 (except for GCM which is preferred over everything else). It does so mostly for liability reasons because customers may insist on it for bogus reasons.
However quoth a cryptographer:
AES-128 isn’t really worse than AES-anythingelse, at least not in ways you care about
So if AES-128 is fine for you, feel free to add an ‘:!AES256
’ to the end of the cipher string to keep your cipher suite shorter which will also expedite your TLS handshakes.
Apache
1 2 3 |
SSLProtocol ALL -SSLv2 SSLHonorCipherOrder On SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS |
This works on both Apache 2.2 and 2.4. If your OpenSSL doesn’t support the preferred modern ciphers (like the still common 0.9.8), it will fall back gracefully but your configuration is ready for the future.
Please note: you need Apache 2.4 for ECDH and ECDSA. You can circumvent that limitation by putting an SSL proxy like stud or even nginx in front of it and let Apache serve only plain HTTP.
TLS compression is a bit more complicated: as of Apache 2.2.23, it’s not possible to switch it off inside of Apache. For Apache 2.2.24+ and 2.4.3+, you can switch it off using:
1 |
SSLCompression Off |
Currently the default is On
, but that changed from 2.4.4 on.
The good news for Ubuntu admins is that Ubuntu has back portedthat option into their 2.2 packages – and set it to off
by default – so you should be fine. The solution on Red Hat based OS (RHEL, Fedora, CentOS, Scientific Linux…) is setting an environment variable inside of your Apache startup script:
1 |
export OPENSSL_NO_DEFAULT_ZLIB=1 |
nginx
1 2 3 |
ssl_prefer_server_ciphers On; ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS; |
SSL 2.0 is off and the best protocols on by default. However it may be that you have some artifact from pre-TLS 1.2 times lurking somewhere in your config so it’s better to be explicit.
TLS compression depends on the version of nginx and the version of OpenSSL. If OpenSSL 1.0.0 or later is installed, anything after nginx 1.0.9 and 1.1.6 is fine. If an older OpenSSL is installed, you’ll need at least nginx 1.2.2 or 1.3.2.
For more details, have a look at this serverfault answer.
TL;DR on TLS compression & nginx: if you’re using Ubuntu Precise (i.e. the current LTS release) you’re fine (OpenSSL 1.0.1/nginx 1.1.19).
Bonus Points
Qualys updated their requirements on 2014-01-21 and the cipher suites here are still “A”–material. If you want an “A+” though, you’ll need to add HSTS headers too, which is out of scope for this article but the linked Wikipedia article will get you started.
Finally
Make sure to test your server afterwards!
If you want to learn more about deploying SSL/TLS, Qualys’s SSL/TLS Deployment Best Practices are a decent primer.
For investigating the SSL/TLS behavior of your browser, How’s My SSL?will give you all the details you need.
The (Near) Future
2013 has galvanized the whole industry. This is a good thing. In 2012 barely anyone lost a thought about configuring their TLS ciphers, how many bits their certificates had, or even forward secrecy. That made it way too easy for the bad folks. Nowadays, people are questioning their own practices, open source projects work on enhancing their TLS support, and the public started to listen to cryptographers again instead of discounting them as crazy tinfoil crowd.
Good things are shaping on the horizon and Google’s Adam Langleygiven the power of having control over both servers and the most popular browser is pressing ahead. Their servers widely support TLS 1.2 with AES-GCM. Chrome has the best TLS support already. Additionally, its Canary releases now have grown support for ChaCha20 which is an extremely fast yet secure stream cipher by Dan Bernstein and Poly1305a great MAC of the same pedigree.
Now if people just stopped using old browsers and we could roll outSNI and mandatory TLS 1.2.
Recent Comments