管理員常在資料庫檔名加 `#` (如 `#data.mdb`),以為 IE 會忽略 `#` 後內容而無法下載。實則 **URL 編碼 `%23` 即可繞過**,此技術同樣適用於繞過各類基於副檔名/特殊字元的下載攔截。
| 原始請求 | 瀏覽器行為 | 繞過請求 | Server 端解析 |
|---|---|---|---|
GET /#data.mdb | 視為錨點,不發送請求 | GET /%23data.mdb | 解碼為 `#data.mdb`,正常返回檔案 |
核心原因:`#` 在 URL 中為片段識別符,瀏覽器**不發送**給 Server。但 `%23` 是 `#` 的 URL 編碼,**會發送給 Server**,Server 端解碼後還原為 `#data.mdb` 並正常處理。
# 假設網站根目錄有 #data.mdb
# 直接瀏覽器輸入 https://site/#data.mdb → 不會下載 (瀏覽器截留)
# 瀏覽器輸入 https://site/%23data.mdb → 正常下載 #data.mdb
# 進階:雙重編碼繞過 WAF
%2523data.mdb -- %25 = %,解碼後變 %23data.mdb,再解碼為 #data.mdb
| 偽裝手法 | 繞過編碼 | 原理 |
|---|---|---|
副檔名修改 data.asp → data.jpg | 直接請求真實名 data.asp | Server 端按實際檔名查找 |
加入 . 結尾 data.mdb. | data.mdb%2e 或 data.mdb. | Windows 檔案系統忽略結尾點 |
加入 $ data.mdb$ | data.mdb%24 | NTFS 替代資料流特殊字元 |
| 隱藏屬性 + 系統屬性 | 無效,下載不受屬性影響 | HTTP 協議不檢查檔案屬性 |
# ❌ 錯誤架構
/var/www/html/
├─ index.php
├─ data/
│ └─ database.mdb <-- 可直接 HTTP 存取
# ✅ 正確架構
/var/www/html/ <-- Web Root (DocumentRoot)
└─ index.php
/var/lib/mysql/ <-- 資料庫目錄 (非 Web 可存取)
└─ database.mdb <-- 或使用 SQL Server/MySQL Server 引擎
# Apache .htaccess
Order allow,deny
Deny from all
# IIS web.config
`#` 號防下載 = **虛假安全感**。`%23` URL 編碼瞬間繞過。
🔐 **唯一有效防禦**:資料庫檔案**完全移出 Web DocumentRoot**,使用真正的資料庫服務引擎。
🛡 **纏深度防禦**:Web 伺服器層封鎖敏感副檔名、目錄權限最小化、應用層代理讀取。