我今天早上打开电脑,在seclists中看到一个很惊人的thread:https://seclists.org/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。
漏洞分析:
出问题的代码如下
- my_boolcheck_scramble(constuchar*scramble_arg,constchar*message,
- constuint8*hash_stage2)
- {
- SHA1_CONTEXTsha1_context;
- uint8buf[SHA1_HASH_SIZE];
- uint8hash_stage2_reassured[SHA1_HASH_SIZE];
- mysql_sha1_reset(&sha1_context);
- /*createkeytoencryptscramble*/mysql_sha1_input(&sha1_context,(constuint8*)message,SCRAMBLE_LENGTH);
- mysql_sha1_input(&sha1_context,hash_stage2,SHA1_HASH_SIZE);
- mysql_sha1_result(&sha1_context,buf);
- /*encryptscramble*/my_crypt((char*)buf,buf,scramble_arg,SCRAMBLE_LENGTH);
- /*nowbufsupposedlycontainshash_stage1:sowecangethash_stage2*/mysql_sha1_reset(&sha1_context);
- mysql_sha1_input(&sha1_context,buf,SHA1_HASH_SIZE);
- mysql_sha1_result(&sha1_context,hash_stage2_reassured);
- returnmemcmp(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时代。
作者:changming的blog
文章来源:https://www.udpwork.com/redirect/7463
(举报)