mysql身份认证漏洞

post by rocdk890 / 2012-6-12 13:39 Tuesday linux技术
 今天在群里听说mysql爆出了一个很大的安全漏洞,几乎影响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_bool check_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]之内,把两个字符串逐个字符的比较,如果找到不一样的,就把这两个字符相减后返回.但是这样逐个逐个的比较,速度太慢.而且C语言标准中并没有要求返回值一定在char的可表示范围内.Linux的glibc一般使用的是SSE优化后的代码,它会一次读取多个字节,然后相减,结果可能是一个很大的数.但是一般来讲,在拿GCC编译C/C++程序的时候,对于memcmp/memcpy这样的常用函数,GCC会优先使用编译器内置的实现(而非glibc中的).所以这个BUG只在特定的编译环境下才会触发:即编译MySQL的时候在CFLAGS中加了-fno-builtin,并且所使用的glibc是经SSE优化后的(最近今年的发行版自带的都是如此).
夜空- 本站版权
1、本站所有主题由该文章作者发表,该文章作者与夜空享有文章相关版权
2、其他单位或个人使用、转载或引用本文时必须同时征得该文章作者和夜空的同意
3、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
4、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
5、原文链接:blog.slogra.com/post-210.html

标签: mysql 升级 漏洞 身份 认证

评论: