Again Riddle

“MySQL client leaks
like a riddle again”

Again Riddle is a security vulnerability found in Oracle's MySQL client database libraries and their forks (like MariaDB or Percona). The vulnerability allows an attacker to use again man riddle in the middle for breaking SSL configured connection between MySQL server and client application.

Some déjà vu?

Looks like yes. The Riddle vulnerability strikes back and is there Again. So this new vulnerability is called Again Riddle.

Q&A

What happened?

In 2015 Adam Goodman discovered BACKRONYM vulnerability (CVE-2015-3152). That security vulnerability allowed an attacker to downgrade and snoop on the SSL encrypted connection between MySQL client and server. Oracle claimed that they fixed it in MySQL 5.5.49. Later in February 2017 Pali Rohár discovered The Riddle vulnerability (CVE-2017-3305). It allowed an attacker to use man in the middle attack and was introduced in MySQL 5.5.49 by improper fix of the BACKRONYM vulnerability. Oracle claimed that they fixes The Riddle vulnerability in MySQL 5.5.55. But in April 2017 Pali Rohár discovered that fix introduced in MySQL 5.5.55 is still improper, problem persists and instead of fix, Oracle introduced this Again Riddle vulnerability. So even after two years Oracle is unable to properly fix security vulnerability in MySQL!

What is the problem now?

If MySQL client library libmysqlclient.so is compiled from source code without SSL support via cmake switch -DWITH_SSL=OFF, then all SSL related functions from libmysqlclient.so return success (non-error) value. And function mysql_real_connect() from libmysqlclient.so connects to MySQL server via plain text protocol, even if client enforced SSL mode with certificate verification. Which means that function for enforcing SSL mode does nothing if libmysqlclient.so is compiled without SSL support.

In MySQL 5.5 documentation for MYSQL_OPT_SSL_MODE option passed to mysql_options() function is written:

... mysql_real_connect() returns an error if the server does not support SSL or the client is not configured to use SSL ...

But in reality no error is returned and connection is successfully established.

There is a new MySQL 5.5.56, so is this problem fixed now?

Oracle in May 2017 released new MySQL security update 5.5.56 which just targets this issue. But Again Riddle is not truly fixed. Oracle instead of proper fix changed cmake build system to disallow compiling MySQL without SSL support and -DWITH_SSL=OFF is not valid anymore. So Oracle just prevented compilation of MySQL when build configuration could lead to vulnerable code path.

So can be MySQL compiled without SSL support?

No. Since 5.5.56 it is not possible anymore. Due to improper fix of Again Riddle vulnerability Oracle disallowed it.

When is MySQL client library vulnerable?

Only when is compiled without SSL support.

Which programs are affected by Again Riddle?

Every program which uses system installed libmysqlclient.so library and depends on SSL encrypted connection.

How to verify if system libmysqlclient.so library is vulnerable?

You can use simple C program (see below) against some MySQL server which does not support SSL. If it show SSL related error message, then you are not vulnerable. Testing has shown that MySQL 5.5.55 and MariaDB 5.5.55 are vulnerable. And other versions could be too. Note that official precompiled binaries of MySQL and MariaDB are not affected as they have SSL support enabled, but lot of people and distributions too compiled binaries from source code. Also note that MariaDB was not vulnerable to the original Riddle, but is to Again Riddle!

Testing vulnerability

I have prepared simple againriddle.c program written in C which can be used for testing Again Riddle vulnerability. Together with Perl script riddle.pl, from the original Riddle website, can be used to do MITM attack.

Example which expects that non-SSL MySQL server is already running on localhost:

Compile Again Riddle:

$ cc againriddle.c `mysql_config --cflags --libs` -o againriddle
Prepare CA certificate file (can be empty) and connect to MySQL server:
$ ./againriddle 127.0.0.1 3306 dbname user password ca.pem
If you provided correct dbname, user and password then with vulnerable libmysqlclient.so it writes output:
Output: have_ssl : DISABLED
If you enter invalid password then with vulnerable libmysqlclient.so it writes output:
mysql_real_connect failed: Access denied for user 'root'@'localhost' (using password: YES)
And if you connect with valid password to the Riddle in the middle server you should see nice message:
mysql_real_connect failed: Access denied: MITM attack

Contact

Discovered by: Pali Rohár
Email address: middle at riddle dot link

Timeline

  • 2017-04-10 - Oracle - Released MySQL 5.5.55
  • 2017-04-14 - me - Found Again Riddle vulnerability and reported it to oCERT team
  • 2017-04-18 - oCERT - Suggested to contact DB parties as this vulnerability is already known
  • 2017-04-19 - me - Reported it to Oracle, Percona and MariaDB security teams and provided test program
  • 2017-04-19 - Oracle, Percona and MariaDB - Confirmed issue
  • 2017-04-24 - me - Reported planned public disclosure on 2017-05-03
  • 2017-05-02 - Oracle - Released MySQL 5.5.56
  • 2017-05-03 - me - Announced the vulnerability to the oss-sec mailing list

References