目錄遍歷
目錄遍歷(英文:Directory traversal),又名路徑遍歷(英文:Path traversal)是一種利用網站的安全驗證缺陷或用戶請求驗證缺陷(如傳遞特定字符串至文件應用程式接口)來列出伺服器目錄的漏洞利用方式。
此攻擊手段的目的是利用存在缺陷的應用程式來獲得目標文件系統上的非授權訪問權限。與利用程序漏洞的手段相比,這一手段缺乏安全性(因為程序運行邏輯正確)。
目錄遍歷在英文世界裡又名../
攻擊(Dot dot slash attack)、目錄攀登(Directory climbing)及回溯(Backtracking)。其部分攻擊手段也可劃分為規範化攻擊(Canonicalization attack)。
示例
下方是一個存在安全隱患的PHP程序示例:
<?php
$template = 'red.php';
if (isset($_COOKIE['TEMPLATE']))
$template = $_COOKIE['TEMPLATE'];
include ("/home/users/phpguru/templates/" . $template);
?>
攻擊者可對此程序發送下列HTTP請求:
GET /vulnerable.php HTTP/1.0
Cookie: TEMPLATE=../../../../../../../../../etc/passwd
從而使伺服器產生如下的響應:
HTTP/1.0 200 OK
Content-Type: text/html
Server: Apache
root:fi3sED95ibqR6:0:1:System Operator:/:/bin/ksh
daemon:*:1:1::/tmp:
phpguru:f8fk3j1OIf31.:182:100:Developer:/home/users/phpguru/:/bin/csh
/home/users/phpguru/templates/
後重複的../
導致include()
函數遍歷Root目錄,並向攻擊者返回Unix密碼文件/etc/passwd
。
Unix中的/etc/passwd
常用於展示應用程式存在目錄遍歷問題,黑客及駭客可使用此文件來破解密碼。
新版Unix作業系統中,原位於passwd文件中的經散列處理後的密碼被移動到了/etc/shadow
,其無法被沒有特權的用戶讀取。但攻擊者仍可使用此文件來列出系統上的用戶帳戶。
變體
下方是已知的目錄遍歷攻擊方式變體:
Unix上的目錄遍歷
常見的Unix類目錄遍歷攻擊使用../
字符。攻擊者可使用glob通配符對Sudo程序進行攻擊(如chown /opt/myapp/myconfig/*
可通過sudo chown baduser /opt/myapp/myconfig/../../../etc/passwd
命令攻擊)。
Windows上的目錄遍歷
對微軟Windows及DOS進行目錄遍歷通常使用..\
或../
。[1]
在這類系統上,每個分區均有不同的根目錄(如C盤則為C:\
),不同的盤符之間沒有共同的根目錄。這意味著對於大多數的目錄遍歷缺陷而言,其僅僅對單一的分區有效。
這種攻擊手段也是此類系統上大多數安全缺陷的異派同源。[2][3]
URI編碼目錄遍歷
此缺陷與規範化問題有關。
部分網頁應用程式會檢查查詢字符串中的危險字符,如:
..
..\
../
這種方法能避免部分目錄遍歷問題。但是,查詢字符串在使用前通常經過URI解碼。因此,這些應用程式易受到百分號編碼類的目錄遍歷攻擊,如:
%2e%2e%2f
將解碼為.
./
%2e%2e/
將解碼為.
./
..%2f
將解碼為.
./
%2e%2e%5c
將解碼為.
.\
Unicode / UTF-8編碼目錄遍歷
同樣與規範化問題有關。
布魯斯·施奈爾與傑弗里·斯特里夫林(Jeffrey Streifling)稱UTF-8是安全缺陷與攻擊向量的根源。[4]
當微軟為其網頁伺服器添加Unicode支持時,同時添加了一種編碼../
的全新方式,卻繞過了防止目錄遍歷的補丁。
多個百分號編碼,如:
%c1%1c
%c0%af
可被解碼為/
或\
符。
微軟的網頁伺服器將百分號編碼解碼為對應的8位字符。這是Windows和DOS的正確行為,因為兩者都使用基於ASCII的8位字符集的規範形式。
但是,原版UTF-8並不是規範形式,多個字符串經編碼後可被譯為相同的字符串。微軟在未經UTF-8規範化時即進行防遍歷檢查,從而導致在字符串比較時忽略了(HEX)C0AF
及(HEX) 2F
均為同一字符。攻擊者可使用%c0%9v
字符進行攻擊。[5]
Zip/壓縮文件遍歷攻擊
攻擊者可使用歸檔文件(如zip格式)來進行目錄遍歷攻擊:壓縮文件中的文件可為攻擊者精心製造,利用回溯法來覆蓋文件系統上的文件。用於解壓縮歸檔文件的代碼應對歸檔中的文件進行檢查,避免目錄遍歷。
防止目錄遍歷的方法
下方是防止目錄遍歷的幾種方法:
- 在繼續運行下方代碼時處理與文件無關的URI請求(如鉤入用戶代碼);
- 當用戶請求訪問文件/目錄時,構造文件/目錄(若存在)所在的的完整路徑,並標準化所有字符(如
%20
轉為空格); - 假設文檔根目錄已合格、被正常化、目錄已知且字符串的長度為N。假設此目錄外的任何文件都無法被讀取/寫入;
- 確保請求文件完整目錄後的頭N個字符與文檔根目錄完全相同;
- 若相同,則返回指定文件;
- 若不同,則返回錯誤,因為請求顯然超出伺服器提供文件範圍;
- 將硬編碼的預定義文件拓展名添加到目錄後將無法限制對此文件拓展名的攻擊。
<?php
include($_GET['file'] . '.html');
用戶可使用空字符(表示字符串結束)來繞過$_GET
後的全部內容(僅限PHP語言)。
另請參閱
參考文獻
- ^ Naming Files, Paths, and Namespaces. Microsoft. [2019-07-11]. (原始內容存檔於2018-06-01).
File I/O functions in the Windows API convert '/' to '\' as part of converting the name to an NT-style name
- ^ Burnett, Mark. Security Holes That Run Deep. SecurityFocus. December 20, 2004 [2019-07-11]. (原始內容存檔於2021-02-02).
- ^ Microsoft: Security Vulnerabilities (Directory Traversal). CVE Details. [2019-07-11]. (原始內容存檔於2019-07-11).
- ^ Crypto-Gram Newsletter July 2000. [2019-07-11]. (原始內容存檔於2014-08-14).
- ^ IIS cmd.exe attack strings. [2019-07-11]. (原始內容存檔於2010-08-03).