身分驗證繞過測試實戰指南。適用於評估登入流程、密碼重置邏輯、帳號復原機制、MFA 繞過、Token 可預測性、防暴力破解能力以及 Session 邊界缺陷。
SKILL:身分驗證繞過 — 專家級攻擊實戰指南
AI 載入指令:專家級身分驗證繞過技術。涵蓋基於 SQL 注入的登入繞過、密碼重置缺陷、Token 可預測性、帳號列舉、繞過暴力破解防護,以及多重因素驗證繞過。與 JWT/OAuth(於 ../jwt-oauth-token-attacks/SKILL.md 中說明)不同,本篇專注於登入機制本身。
0. 授權憑證測試規劃
在精簡路由條目後,預設憑證、使用者名稱變體、聚焦埠號(Port)與字典檔大小調整皆在此集中處理。
服務優先的微型憑證集
| 服務類型 | 優先使用者名稱 | 優先密碼 |
|---|---|---|
| phpMyAdmin | root, admin |
(空白), root, phpmyadmin, admin |
| FTP | ftp, admin, test |
(空白), ftp, admin, 123456 |
| SSH | root, admin, 服務帳號名稱 |
root, admin, 季節性變體 |
| MySQL | root, mysql |
(空白), root, mysql |
| Tomcat / Java 管理介面 | tomcat, admin, manager |
tomcat, admin, s3cret |
| WebLogic | weblogic, admin |
weblogic, welcome1, admin |
使用者名稱分類
| 分類 | 範例 |
|---|---|
| 通用管理員 | admin, administrator, root, test, guest |
| 技術支援 / 運維 | dev, ops, sysadmin, service, backup |
| 名字組合 | firstname, lastname, f.lastname, first.last |
| 電子郵件衍生 | 企業 Email 格式的帳號部分(@ 前方) |
| 產品預設 | tomcat, weblogic, jenkins, gitlab |
字典檔大小選擇與聚焦埠號
| 測試情境 | 建議規模 | 原因 |
|---|---|---|
| 預設管理面板 | 5 到 50 組密碼 | 在此情境下預設密碼效果勝過龐大字典檔 |
| 已知產品的內部服務 | 廠商專屬微型清單 | 比通用清單能提供更好的測試訊號 |
| 防護較弱的消費級登入 | 前 20 或前 100 高頻密碼 | 快速驗證 |
| 設有頻率限制的登入 | 極小清單 + Header / IP 輪替策略 | 節省可嘗試次數 |
| 離線雜湊破解 | 大型字典檔 | 線上破解規則不適用於此 |
優先針對常見埠號與服務暴露面:80/443/8080/8443 管理面板、22 SSH、21 FTP,以及 3306/5432/6379/27017 資料或管理服務。
1. SQL 注入登入繞過
雖然經典,但在舊型系統、自訂 ORM 以及原生查詢程式碼中依然可見:
-- 基本繞過(假設 admin 使用者位於第一筆記錄):
Username: admin'--
Password: anything
→ 查詢語法: SELECT * FROM users WHERE user='admin'--' AND pass='anything'
-- 通用繞過(以資料庫中的第一個使用者身分登入):
Username: ' OR '1'='1'--
Password: anything
→ 查詢語法: SELECT * FROM users WHERE user='' OR '1'='1'--' AND pass='anything'
-- 盲注測試:這樣可行嗎?
Username: ' OR 1=1--
Username: admin' OR 'a'='a
Username: 1' OR '1'='1'/*
Username: 1 or 1=1
分別測試每個欄位 — 可能只有單一欄位存在漏洞。
2. 密碼重置漏洞
可猜測 / 可預測的重置 Token
檢查重置 Token 是否基於以下項目生成:
- 時間戳記:token=1691234567890 (Unix 時間)
- 連續數字:token=1001, 1002, 1003
- MD5(email):echo -n "user@example.com" | md5sum
- MD5(username+timestamp):可逆推算出規律
- 簡短 Token (4-6 位數字):可被暴力破解
測試方法:連續申請 3 次密碼重置郵件,比對 Token 的生成規律。
重置 Token 未過期
1. 申請密碼重置 → 透過 Email 取得 Token
2. 等待 48 小時以上(Token 理應過期)
3. 使用舊 Token → 檢查是否依然有效?
重置 Token 重複使用
1. 申請重置 → 取得 Token T1
2. 使用 T1 完成密碼重置
3. 再次使用 T1 → 檢查是否能再次重置?
重置郵件中的 Host Header 注入
當應用程式使用 Host Header 來建構重置 URL 時:
POST /forgot-password HTTP/1.1
Host: attacker.com ← 注入攻擊者的域名
Content-Type: application/x-www-form-urlencoded
email=victim@target.com
→ 發送給受害者的重置郵件中,連結指向 attacker.com/reset?token=VICTIM_TOKEN
→ 受害者點擊連結 → 攻擊者擷取 Token
測試方法:發送密碼重置請求並修改 Host: 欄位,檢查郵件中的重置連結指向何處。
Referer 中的密碼重置 Token 洩露
1. 申請重置 → 造訪帶有 Token 的重置 URL
2. 重置頁面載入第三方資源(如分析工具、字型)
→ Referer Header 洩露:https://target.com/reset?token=TOKEN
→ 第三方伺服器的 Log 中接收到 Token
未驗證當前密碼即可變更密碼
PUT /api/user/password
{"new_password": "hacked"}
→ 不需要提供 current_password 欄位?
→ 可搭配 CSRF 實現帳號接管
3. 帳號列舉(Account Enumeration)
確認有效的使用者名稱或 Email 有助於發動標靶式攻擊:
錯誤訊息差異
無效的使用者名稱 → "User not found"
有效的使用者名稱,密碼錯誤 → "Incorrect password"
→ 可據此列舉出有效的帳號
回應時間差異
無效的使用者名稱 → 回應快速(未進行 DB 查詢)
有效的使用者名稱 → 回應稍慢(DB 查詢 + 雜湊比對)
→ 時間差側道洩露(Timing oracle)
密碼重置流程
POST /forgot-password {"email": "nonexistent@example.com"}
→ "若此 Email 存在,我們已發送重置連結"(適當的處理)
相較於:
→ "此 Email 未註冊"(可能導致帳號列舉)
註冊端點
POST /register {"email": "victim@example.com"}
→ "Email 已被註冊" → 確認帳號存在
相較於:
→ 無論是否存在皆提示 "已發送驗證郵件" → 無法進行列舉
4. 繞過暴力破解防護
嘗試 N 次後鎖定並隨後重置
嘗試 10 次後鎖定 → 試錯 9 次密碼
等待重置冷卻期(通常為 30 分鐘或 1 小時)
→ 再嘗試 9 次 → 循環往復 → 避免觸發永久鎖定
繞過基於 IP 的鎖定機制
X-Forwarded-For: 1.1.1.1 ← 每次請求更換 IP
X-Real-IP: 2.2.2.2
在 Header 中輪替不同 IP
帳號輪替 vs 密碼輪替
一般暴破:針對單一帳號嘗試多組密碼 → 觸發鎖定
反向暴破(Password Spraying):拿「同一組密碼」嘗試多個帳號
→ 使用 "password123" 測試所有使用者 → 找出使用弱密碼的帳號
→ 不會導致任何單一帳號被鎖定
憑證填充(Credential Stuffing)
利用外洩資料集(如 HaveIBeenPwned)中的憑證對目標進行測試:
# 工具:Hydra、Burp Intruder、自訂腳本
hydra -C credentials.txt https-post-form://target.com/login:"username=^USER^&password=^PASS^":"error message"
5. 多重因素驗證(MFA)繞過
完成 2FA 前即發放 Session Cookie
流程:登入(密碼正確)→ 重定向至 2FA 頁面 → 輸入驗證碼
攻擊方式:密碼驗證通過後即設定了 Session Cookie,但尚未校驗 2FA。
→ 直接攜帶 Session Cookie 造訪 /dashboard
→ 完全繞過 2FA 頁面
2FA 驗證碼暴力破解
4-6 位數的 TOTP 驗證碼最多僅有 1,000,000 種組合
若 2FA 步驟未設置嘗試次數限制或鎖定機制:
→ 暴力破解所有驗證碼組合(工具:Burp Intruder、按順序嘗試)
→ TOTP 時間視窗:一般為 30 秒,部分系統接受前一個或下一個時間視窗
2FA 僅用於關鍵操作而非登入
登入時不需要 2FA,但是:
DELETE /account 或 POST /transfer 等操作需要 2FA
攻擊測試:2FA 是在這些操作時被嚴格檢查,還是僅在登入時檢查?
→ 若僅在登入時要求 2FA:一旦登入成功後,後續操作是否真正校驗了 2FA
2FA 備用碼濫用
生成備用碼(通常為 8-10 組一次性代碼)
測試重點:
→ 備用碼是否有驗證頻率限制?
→ 備用碼是否能重複使用?
→ 長度較短(6-8 字元)?若無頻率限制則可嘗試暴力破解
2FA 驗證碼重複使用
TOTP 驗證碼原則上僅限使用一次
→ 重複輸入同一組 TOTP 驗證碼 → 檢查第二次是否依然有效?
→ 若伺服器未紀錄已使用過的代碼,將導致重放攻擊(Replay attack)
6. OAUTH / SSO 帳號接管模式
盲目信任 Email Claim
1. 在攻擊者控制的 OAuth Provider 建立帳號
2. 將 Email Claim 設定為 victim@target.com
3. 透過該 Provider 進行綁定 / 登入
→ 若目標伺服器未經驗證即信任 Email Claim → 導致帳號合併 / 帳號接管
綁定 SSO 後未妥善處理密碼
1. 使用者綁定 Google SSO
2. 使用者忘記密碼(純 SSO 帳號原本未設定密碼)
3. 觸發「忘記密碼」流程 → 是否允許為純 SSO 帳號設定密碼?
→ 若可成功設定密碼 → 即可繞過 SSO 直接登入
7. 使用者名稱 / 密碼欄位操控
超長密碼 DoS → 繞過機制
某些應用程式會在傳送至資料庫前對密碼進行雜湊處理。
bcrypt 存在 72 位元組的限制 — 超過 72 位元組的輸入會被忽略。
攻擊測試:
→ 使用密碼 "A"*100 進行註冊
→ 使用密碼 "A"*72 登入 → 雜湊值相同 → 登入成功
→ 使用 "A"*71 + "完全不同的內容" 登入 → 若字元遭到截斷且前 72 位元組相同 → 雜湊值相同
使用者名稱中的 Null Byte(空字元)
username=admin%00 vs username=admin
→ 在某些字串比對中可能因 Null Byte 導致截斷
→ 在 C 語言風格的字串比對中,"admin\0attacker" 會被視為 "admin"
Unicode 正規化(Normalization)
使用者名稱:"ⓢcott" → 正規化後變為 "scott" → 冒充 "scott"
使用者名稱:"admin"(使用字母 a,d,m,i,n 的各式 Unicode 同形字形 / Homoglyphs)
8. SESSION 管理缺陷
登出時未將 Session 廢除
1. 登入 → 擷取 Session Cookie
2. 點擊登出
3. 重放先前擷取的 Session Cookie → 檢查是否依然有效?
→ 伺服器端未真正將 Session 廢除(Invalidate)
權限變更時未重新生成 Session
1. 以低權限身分登入 → 取得 Session Cookie
2. 管理員提升你的帳號權限
3. 舊的 Session Cookie 是否自動具備了管理員權限?
→ Session 未重新生成 → 舊 Token 直接繼承了新權限
可預測的 Session Token
Token: base64(userid+timestamp) → 可逆推解碼
Token: 連續整數 → Session ID = 你的 Session ID +/- 小數值
Token: 熵值過低的簡短隨機數 (32-bit 熵值) → 可被暴力破解
9. 身分驗證測試自我檢查清單
□ 嘗試在登入欄位進行 SQL 注入(' OR 1=1--)
□ 測試密碼重置:預測 Token、Host Header 注入、Referer 洩露
□ 透過錯誤訊息 / 時間差測試帳號列舉
□ 檢查 2FA:跳過步驟(直接造訪 URL)、暴力破解驗證碼、重複使用驗證碼
□ 測試防暴力破解機制:X-Forwarded-For 繞過、反向暴破 (Password Spraying)
□ 檢查登出時是否廢除 Session
□ 檢查權限變更後是否重新生成 Session
□ 測試變更密碼功能是否強制要求提供當前密碼
□ 測試超長密碼(bcrypt 72 位元組截斷)
□ OAuth/SSO:測試 Email Claim 信任機制、SSO 後密碼設定
□ 檢查 remember_me Token:有效期限多長、是否可撤銷、是否可預測?
10. 密碼重置攻擊矩陣(22 種模式)
| # | 模式 | 說明 |
|---|---|---|
| 1 | 可預測的重置 Token | Token 基於時間戳記、使用者 ID 或連續數字生成 |
| 2 | Token 未與使用者強綁定 | 使用為使用者 A 生成的 Token 來重置使用者 B 的密碼 |
| 3 | Token 存在於 Response Body | 重置 Token 直接在 HTTP 回應中傳回(而非僅發送至 Email) |
| 4 | Token 存在於 URL 參數中 | 重置連結中的 Token 在載入外部資源時透過 Referer Header 洩露 |
| 5 | Token 無過期機制 | Token 永久有效 |
| 6 | Token 重複使用 | 同一 Token 可多次成功使用 |
| 7 | 簡短 / 可被暴破的 Token | 未設置頻率限制的 4-6 位數字驗證碼 |
| 8 | 透過 Host Header 進行密碼重置 | Host: attacker.com → 發送含有攻擊者域名的重置連結 |
| 9 | 重新註冊覆蓋既有帳號 | 使用相同的 Email 重新註冊 → 直接覆蓋原密碼 |
| 10 | 步驟跳過(僅前端防護) | 透過 URL 直接跳轉至「設定新密碼」步驟 |
| 11 | 回應操控(Response Manipulation) | 在 Proxy 中將 {"status":"fail"} 修改為 {"status":"success"} |
| 12 | 驗證碼直接傳回 Response | 簡訊 / 郵件驗證碼在 API 回應中直接傳回 |
| 13 | 平行 Session 重置 | 發起使用者 A 的重置,並在使用者 B 的 Session 下完成 |
| 14 | Email / 電話參數污染 | email=victim@x.com&email=attacker@x.com |
| 15 | Unicode 正規化 | admin@target.com vs ADMIN@target.com 或 Unicode 混淆字元 |
| 16 | 重置流程中的 SQL 注入 | 重置查詢語法中的 Email 欄位存在注入漏洞 |
| 17 | 重置端點的 IDOR | 在重置確認請求中修改使用者 ID |
| 18 | 跨協定 / 跨平台重置 | 行動端 API 未如 Web 端般嚴格校驗相同的 Token |
| 19 | 預設安全問題缺陷 | 答案可猜測且無驗證頻率限制 |
| 20 | Token 生成的競態條件(Race Condition) | 同時發送多個請求生成了相同的 Token |
| 21 | Logout doesn't |
<!-- truncated for translation batch; full body continues in source -->






