我今天早上打开电脑,在seclists中看到一个很惊人的thread:http://seclists/oss-sec/2012/q2/493MySQL爆出了一个很年夜的平安缝隙,几近影响5.1至5.5的所有版本。出问题的模块是登录时密码校验的部分(password.c),在知道用户名的情况下(如root),直接频频重试(平均年夜约256次)便可登入。不过,MySQL身份认证的时候是采取3元组,username,ip,password。如果client的IP在mysql.user表中找不到对应的,也无法登岸。
这个BUG实际上早在4月份就被发现了,本年5月7号,MySQL发布5.5.24的时候,修正了这个BUG。
缝隙阐发:
出问题的代码如下
/*Check that scrambled message corresponds to the password; the functionis used by server to check that recieved reply is authentic.This function does not check lengths of given strings: message must benull-terminated, reply and hash_stage2 must be at least SHA1_HASH_SIZElong (if not, something fishy is going on).SYNOPSIScheck_scramble()scramble clients' reply, presumably produced by scramble()message original random string, previously sent to client(presumably second argument of scramble()), must beexactly SCRAMBLE_LENGTH long and NULL-terminated.hash_stage2 hex2octet-decoded database entryAll params are IN.RETURN VALUE0 password is correct!0 password is invalid*/my_boolcheck_scramble(const uchar *scramble_arg, const char *message,const uint8 *hash_stage2){SHA1_CONTEXT sha1_context;uint8 buf[SHA1_HASH_SIZE];uint8 hash_stage2_reassured[SHA1_HASH_SIZE];mysql_sha1_reset(&sha1_context);/* create key to encrypt scramble */mysql_sha1_input(&sha1_context, (const uint8 *) message, SCRAMBLE_LENGTH);mysql_sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE);mysql_sha1_result(&sha1_context, buf);/* encrypt scramble */my_crypt((char *) buf, buf, scramble_arg, SCRAMBLE_LENGTH);/* now buf supposedly contains hash_stage1: so we can get hash_stage2 */mysql_sha1_reset(&sha1_context);mysql_sha1_input(&sha1_context, buf, SHA1_HASH_SIZE);mysql_sha1_result(&sha1_context, hash_stage2_reassured);return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE);}
memcmp的返回值实际上是int,而my_bool实际上是char。那么在把int转换成char的时候,就有可能产生截断。比如,memcmp返回0×200,截断后酿成了0,挪用check_scramble函数的就误以为“password is correct“。
可是一般来讲,memcmp的返回值都在[127,-128]之内。glibc的经SSE优化后的代码,不是如此。所以这个BUG只在特定的编译情况下才会触发:即编译MySQL的时候加了-fno-builtin,并且所使用的glibc是经SSE优化后的(一般系统自带的都是如此)。这里所说的glibc是指Linux的glibc,FreeBSD的libc不受影响。
总的来讲这个BUG仍是比较严重的,上次MySQL呈现这样的BUG仍是在3.23/4.0时代。
原文链接: .udpwork/redirect/7463