|
|
|
|
| |
| The MySQL "database server is the world's most popular open source database". A bug allows a remote user to authenticate and get access to the database completely bypassing the normal authentication mechanism and without providing the DB user's password. |
| |
Credit:
The information has been provided by NGSSoftware Insight Security Research.
|
| |
Vulnerable Systems:
* MySQL version 4.1 and prior
Immune Systems:
* MySQL versions 4.1.3 and 5.0
By submitting a carefully crafted authentication packet, it is possible for an attacker to bypass the password authentication mechanism. From check_connection (sql_parse.cpp), line ~837:
/*
Old clients send null-terminated string as password; new clients send
the size (1 byte) + string (not null-terminated). Hence in case of
empty
password both send '\0'.
*/
uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
*passwd++ : strlen(passwd);
Provided 0x8000 is specified in the client capabilities flags, the use can specify the passwd_len field of their choice. For this attack, 14h (20) bytes will be chosen, the length of a SHA-1 hash string. Several checks are now carried out to ensure that the user is authenticating from a host that is permitted to connect. Provided these checks are passed, the following code is executed:
/* check password: it should be empty or valid */
if (passwd_len == acl_user_tmp->salt_len)
{
if (acl_user_tmp->salt_len == 0 ||
acl_user_tmp->salt_len == SCRAMBLE_LENGTH &&
check_scramble(passwd, thd->scramble, acl_user_tmp->salt) == 0 ||
check_scramble_323(passwd, thd->scramble,
(ulong *) acl_user_tmp->salt) == 0)
{
acl_user= acl_user_tmp;
res= 0;
}
}
The check_scramble function fails, but within the check_scramble_323() function we see:
my_bool
check_scramble_323(const char *scrambled, const char *message,
ulong *hash_pass)
{
struct rand_struct rand_st;
ulong hash_message[2];
char buff[16],*to,extra; /* Big enough for check */
const char *pos;
hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
randominit(&rand_st,hash_pass[0] ^ hash_message[0],
hash_pass[1] ^ hash_message[1]);
to=buff;
for (pos=scrambled ; *pos ; pos++)
*to++=(char) (floor(my_rnd(&rand_st)*31)+64);
extra=(char) (floor(my_rnd(&rand_st)*31));
to=buff;
while (*scrambled)
{
if (*scrambled++ != (char) (*to++ ^ extra))
return 1; /* Wrong password */
}
return 0;
}
At this point, the user has specified a 'scrambled' string that is as long as they wish. In the case of the straightforward authentication bypass, this is a zero-length string. The final loop compares each character in the 'scrambled' string against the string that mysql knows is the correct response, until there are no more characters in 'scrambled'. Since there are no characters *at all* in 'scrambled', the function returns '0' immediately, allowing the user to authenticate with a zero-length string.
In addition to the zero-length string authentication bypass, the stack-based buffer 'buff' can be overflowed by a long 'scramble' string. The buffer is overflowed with characters output from my_rnd(), a pseudo random number generator. The characters are in the range 0x40..0x5f. On some platforms, arbitrary code execution is possible, though the exploit is complex and requires either brute force, or knowledge of at least one password hash.
Vendor Status:
MySQL AB were contacted on June 1st and a patch in the source code was available on June 2nd. Upgrade to the newer versions of MySQL in order to mitigate this vulnerability.
Since the attack requires the attacker to know at least the username of the user to authenticate as, changing the default names of the users might be a simple workaroun. In addition, any access retrictions on connections (such as IP addresses) can be applied since the attacker has to be able to access the account in question from the attacking host.
|
|
|
|
|
|
|