Padding Oracle On Downgraded Legacy Encryption
First off, the naming “convention” as of late for security issues has been terrible. The newest vulnerability (CVE-2014-3566) is nicknamed POODLE, which at least is an acronym and as per the header above has some meaning.
The summary of this issue is that it is much the same as the earlier B.E.A.S.T (Browser Exploit Against SSL TLS), however there’s no known mitigation method in this case – other than entirely disabling SSLv3 support, in short, an attacker has a vector by which they can retrieve the plaintext form your encrypted streams.
So let’s talk mitigation, the Mozilla Security Wiki Serverside TLS has for some time made strict recommendations of ciphers and protocols; and is certainly worth your attention.
Apache
Disable SSLv2 and SSLv3 in your ssh apache configuration by setting:
SSLProtocol all -SSLv2 -SSLv3
Nginx
Allow support only for TLS in Nginx with the following:
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
MySQL
This is where things get far more interesting; unlike Apache and Nginx there’s no way to allow / disallow entire protocols of the SSL / TLS spec within mysql; there is however the ability to specify the cipher spec to be used in SSL communication.
As such to remove SSLv3 support from MySQL you need only ensure that none of the SSLv3 ciphers are in use wihtin your configuration.
As per information in this bug you can find a list of SSLv3 ciphers by simply
openssl ciphers -v 'DEFAULT' | awk '/SSLv3 Kx=(RSA|DH|DH(512))/ { print $1 }'
DHE-RSA-AES256-SHA
DHE-DSS-AES256-SHA
DHE-RSA-CAMELLIA256-SHA
DHE-DSS-CAMELLIA256-SHA
AES256-SHA
CAMELLIA256-SHA
EDH-RSA-DES-CBC3-SHA
EDH-DSS-DES-CBC3-SHA
DES-CBC3-SHA
DHE-RSA-AES128-SHA
DHE-DSS-AES128-SHA
DHE-RSA-SEED-SHA
DHE-DSS-SEED-SHA
DHE-RSA-CAMELLIA128-SHA
DHE-DSS-CAMELLIA128-SHA
AES128-SHA
SEED-SHA
CAMELLIA128-SHA
RC4-SHA
RC4-MD5
EDH-RSA-DES-CBC-SHA
EDH-DSS-DES-CBC-SHA
DES-CBC-SHA
EXP-EDH-RSA-DES-CBC-SHA
EXP-EDH-DSS-DES-CBC-SHA
EXP-DES-CBC-SHA
EXP-RC2-CBC-MD5
EXP-RC4-MD5
Removing the above form your ssl-cipher configuration should disable SSLv3 support; of course ensuring your MySQL service is NOT generally accessible is by far one of the most important steps you can take in securing your MySQL deployment against CVE-2014-3566.
You can read more about POODLE here.
The following script will help to identify support for any none SSLv3 ciphers; unfortunately in my limited testing I have yet to have found a supported none SSLv3 cipher.
Formatting is an issue for the script as such please see the Github gist
UPDATE 2014-10-16: openssl updates are now becoming available with patches against this issue
AMI Linux: openssl-1.0.1j-1.80.amzn1 “add patch for CVE-2014-3566 (Padding Oracle On Downgraded Legacy Encryption attack)”
RedHat: no update is yet available
UPDATE 2014-11-17:
Oracle have released an update here: http://www.oracle.com/technetwork/topics/security/poodlecve-2014-3566-2339408.html which notes MySQL products are not affected by the POODLE bug; this is due to the cipher suite which MySQL supports not including the affected SSLv3 ciphers.
openssl -v ciphers
output contracdicts documentation here: https://www.openssl.org/docs/apps/ciphers.html e.g.
openssl ciphers -v AES128-SHA
AES128-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1
The linked documentation page above however lists AES128-SHA as a TLS1.0 cipher
dbusby@kali:~$ openssl ciphers -v AES128-SHA
AES128-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1
busby@kali:~$ mysql -se “SHOW STATUS LIKE ‘Ssl_cipher_list’” | sed
‘s/:/n/g’
Ssl_cipher_list DHE-RSA-AES256-SHA
AES256-SHA
DHE-RSA-AES128-SHA
AES128-SHA
AES256-RMD
AES128-RMD
DES-CBC3-RMD
DHE-RSA-AES256-RMD
DHE-RSA-AES128-RMD
DHE-RSA-DES-CBC3-RMD
RC4-SHA
RC4-MD5
DES-CBC3-SHA
DES-CBC-SHA
EDH-RSA-DES-CBC3-SHA
EDH-RSA-DES-CBC-SHA
dbusby@kali:~$ mysql –ssl-cipher=AES128-SHA
Welcome to the MySQL monitor. Commands end with ; or g.
Your MySQL connection id is 53
Server version: 5.5.40-0+wheezy1 (Debian)
Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type ‘help;’ or ‘h’ for help. Type ‘c’ to clear the current input
statement.
mysql> s
————–
mysql Ver 14.14 Distrib 5.5.40, for debian-linux-gnu (x86_64) using
readline 6.2
Connection id: 53
Current database:
Current user: root@localhost
SSL: Cipher in use is AES128-SHA
Current pager: stdout
Using outfile: ”
Using delimiter: ;
Server version: 5.5.40-0+wheezy1 (Debian)
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8
UNIX socket: /var/run/mysqld/mysqld.sock
Uptime: 11 min 43 sec
Threads: 1 Questions: 727 Slow queries: 0 Opens: 785 Flush tables: 1
Open tables: 132 Queries per second avg: 1.034
————–
mysql> Bye
“no known mitigation method” – so what about TLS_FALLBACK_SCSV support?
Why not just turn off CBC ciphers instead the whole SSLv3?
Eh… What do you mean “the authentication handshake must be completed BEFORE SSL / TLS connection is negotiated”?
You made a typo:
Disable SSLv3 and SSLv3 in your ssh apache configuration by setting:
it should be:
Disable SSLv2 and SSLv3 in your ssh apache configuration by setting:
Thanks for the write up. This will help greatly.
Is there a way to turn off CBC ciphers instead the whole SSLv3????
With ugly quotes:
mysql -se “SHOW STATUS LIKE ‘Ssl_cipher_list'” | sed ‘s/:/n/g’ | sed ‘s/Ssl_cipher_listss//g’ | while read sspec; do SPEC=openssl ciphers -v “$sspec” 2>/dev/null | grep -v SSLv3 | awk ‘{print $1}’; [[ “$sspec” == “$SPEC” ]] && mysql –ssl-cipher=$sspec -e QUIT 2>/dev/null && echo “$sspec OK”; done
Second try:
mysql -se “SHOW STATUS LIKE ‘Ssl_cipher_list'” | sed ‘s/:/n/g’ | sed ‘s/Ssl_cipher_listss//g’ | while read sspec; do SPEC=openssl ciphers -v “$sspec” 2>/dev/null | grep -v SSLv3 | awk ‘{print $1}’; [[ “$sspec” == “$SPEC” ]] && mysql –ssl-cipher=$sspec -e QUIT 2>/dev/null && echo “$sspec OK”; done
@Arek TLS_FALLBACK_SCSV requires support be compiled in; rather than waiting for it to be made available via update; disabling SSLv3 is a viable workaround.
@Sergei possibly alsoa viable method; in which case:
—
mysql -se “SHOW STATUS LIKE ‘Ssl_cipher_list'” | sed ‘s/:/\n/g’ | sed ‘s/Ssl_cipher_lists\s//g’ | while read sspec; do SPEC=openssl ciphers -v “$sspec” 2>/dev/null | grep -v CBC | awk ‘{print $1}’; [[ “$sspec” == “$SPEC” ]] && mysql –ssl-cipher=$sspec -e QUIT 2>/dev/null && echo “$sspec OK”; done
—
@anthony oopps typo corrected thanks; w.r.t. CBC potentially please note reply Sergei above
@Bob something’s going awry with the blog post formatting; I’ve linked to a gist to provide a cleaner format
@Sergei Golubchik iirc standard mysql_na takesplace before TLS / SSL is negotiated; see http://www.slideshare.net/DavidBusby1/security-and-why-you-need-to-review-yours slide 17 except where MySQL5.6 is deployed with sha256_password in which case the authentication can take place over a SSL / TLS connection from what the documentation says
@David: openssl upgrade and I get TLS_FALLBACK_SCSV automaticly (my mysql/percona is built with shared openssl). I am missing something?
@Arek, if you upgrade openssl you’ll just need to restart the mysql service so that the new libraries are loaded by mysqld
@David: exactly. So no need to rebuild anything. Just simple upgrade.
Yes, the slide is correct, but it doesn’t explain what happens when SSL is enabled. And what happens is:
* the server sends the first handshake packet
* the client notices “SSL” capability and switches to SSL *before* sending the user name and the password hash
Sending the username and the password unencrypted, before SSL, would be a pretty weird design decision. MySQL never did it, not in 4.0 even.
See mysql internals manual of the source code (send_client_reply_packet function in sql-common/client.c)
@Arek; indeed I’ve updated the blog post added an update section to the end; there’s no RHEL upgrade available at this time it would appear which I find somewhat supprising; AMI rpm–changelog notes the patch being in place though
I found this ambiguous: “It is worth noting that unless you deploy sha256_password plugin for MySQL 5.6; then the authentication handshake must be completed BEFORE SSL/ TLS connection is negotiated; therefor this attack vector only becomes an issue for valid logins which have access to the data in the stream anyway.” So does that mean my system is potentially vulnerable if I *have* the plugin, or if I *don’t*
Why is DHE-RSA-AES256-SHA listed as sslv3?
Per https://www.openssl.org/docs/apps/ciphers.html , this is TLS v1.0,
That is just an example. Others in the list shown in your blog are also TLS.
@Björn, it doesn’t matter what plugin you use, if any. In MySQL authentication handshake is ALWAYS completed AFTER SSL/ TLS connection is negotiated, no plugin changes that.
@Sergei I’ve removed the section on sha256_password for the time being; I’m going to re-read the source code here on mysql_na and provide an update here.
@john per linked bug; openssl itself outputs this as SSLv3 probably due to “(SSLv2 or SSLv3; the latter includes TLS)” per your linked document
—
DHE-RSA-AES256-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(256) Mac=SHA256
DHE-RSA-AES256-SHA SSLv3 Kx=DH Au=RSA Enc=AES(256) Mac=SHA1
—
@arek, TLS_FALLBACK_SCSV is not fix for POODLE attack. It is a fix for protocl downgrade attack. Without it, MITM attacker can force the connection to SSLv3 even if both client and server supports TLS.
With TLS_FALLBACK_SCSV if both client & server support TLS, they will refuse to use SSLv3. So with it, the POODLE attack should be only possible where either client or server doesn’t support TLS (IE6 on XP for example).
So, in trying to accomplish this, whenever I try to connect using a non-SSLv3 cipher (using –ssl-cipher option), I get the error:
ERROR 2026 (HY000): SSL connection error: error:00000001:lib(0):func(0):reason(1)
I can successfully connect without the option, or when using the option with any SSLv3 cipher, and status shows the connection using SSL. The error message seems to most commonly be caused by the client and server certs having the same common name as the ca cert, but they definitely have different common names (otherwise all SSL connections fail).
I could not make this work. facing the same issue as in Kyle’s message above. It seems like MySQL/Percona/MariaDB codebases are using SSLv3 only.
As I am using MariaDB, filed a bug and it seems to be getting some love… https://mariadb.atlassian.net/browse/MDEV-6975
@martin there’s no need to Orcale have cited that MySQL is not affected by POODLE; this appears to be due to the SSL method extablishing only TLSv1 connectivity, also of note that openssl command line tool flags a lot of the TLS1.0 ciphers as belonging to SSLv3 whilst their online documentation notes they are infact TLSv1 e.g. AES128-SHA
e.g. AES128-SHA
https://www.openssl.org/docs/apps/ciphers.html notes this as TLS 1.0
dbusby@kali:~$ openssl ciphers -v AES128-SHA
AES128-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1
busby@kali:~$ mysql -se “SHOW STATUS LIKE ‘Ssl_cipher_list'” | sed
‘s/:/\n/g’
Ssl_cipher_list DHE-RSA-AES256-SHA
AES256-SHA
DHE-RSA-AES128-SHA
AES128-SHA
AES256-RMD
AES128-RMD
DES-CBC3-RMD
DHE-RSA-AES256-RMD
DHE-RSA-AES128-RMD
DHE-RSA-DES-CBC3-RMD
RC4-SHA
RC4-MD5
DES-CBC3-SHA
DES-CBC-SHA
EDH-RSA-DES-CBC3-SHA
EDH-RSA-DES-CBC-SHA
dbusby@kali:~$ mysql –ssl-cipher=AES128-SHA
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 53
Server version: 5.5.40-0+wheezy1 (Debian)
Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input
statement.
mysql> \s
————–
mysql Ver 14.14 Distrib 5.5.40, for debian-linux-gnu (x86_64) using
readline 6.2
Connection id: 53
Current database:
Current user: root@localhost
SSL: Cipher in use is AES128-SHA
Current pager: stdout
Using outfile: ”
Using delimiter: ;
Server version: 5.5.40-0+wheezy1 (Debian)
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8
UNIX socket: /var/run/mysqld/mysqld.sock
Uptime: 11 min 43 sec
Threads: 1 Questions: 727 Slow queries: 0 Opens: 785 Flush tables: 1
Open tables: 132 Queries per second avg: 1.034
————–
mysql> Bye
https://www.openssl.org/docs/apps/ciphers.html
@Sergei Golubchik
Indeed having had time to dive into the internals of the handshake some more and do some protocol analysis the following is true for the connection phase.
1. exchange the capabilities of client and server
2. setup SSL communication channel if requested
3. authenticate the client against the server
More information can be found here: http://dev.mysql.com/doc/internals/en/connection-phase.html