網站安全🔒 目錄遍歷 Path Traversal 攻擊手法
筆者任職 Yahoo ,《經典駭客攻擊教程:給每個人的網站安全入門》線上課程講師 | 粉絲團:《程式猿吃香蕉🍌》
目錄遍歷 (Path Traversal) 是一種經典的網站攻擊手法,概念很簡單,卻也最容易被大家忽略,即使是有多年開發經驗的工程師,也有可能一不小心而犯錯。
許多人對於目錄遍歷的誤解之處在於:以為駭客只會在前端網頁的網址做目錄遍歷,或是以為前端頁面框架的路由(Router) 功能可以保護你,但其實駭客會在你意想不到的地方進行目錄遍歷,例如:API 路由等等。
本篇文章將會介紹目錄遍歷的攻擊原理、提供實際攻擊範例以及說明該防禦的注意事項。
本篇內容:
✔ 目錄遍歷的攻擊原理
✔ 實際攻擊範例: 前端網址遍歷 & API 路由遍歷
✔ 防禦的注意事項
▍目錄遍歷的攻擊原理
目錄遍歷 (Path traversal) 根據維基百科定義:
『目錄遍歷(Path traversal)是一種利用網站的安全驗證缺陷或用戶請求驗證缺陷(如傳遞特定字符串至文件應用程式接口)來列出伺服器目錄的漏洞利用方式。 此攻擊手段的目的是利用存在缺陷的應用程式來獲得目標文件系統上的非授權訪問權限。』
在說明攻擊原理之前,要先談談「目錄」(Path ,或是稱之為路徑)。每個使用電腦的人,應該很熟悉電腦裡( Mac 或是 Linux )目錄的表示方式,例如:
/Home/Document/hacker/
上述的目錄表示法,意思是指在目錄 Home
底下有 Document
目錄,在Document
目錄底下有 hacker
目錄。
會造成目錄遍歷的關鍵在於:我們可以使用 ../
來表示「到上一層目錄」,例如:
/Home/Document/hacker/../
上述的表示法,因為加上了 ../
,電腦在解析的時候,會判斷這個目錄為 /Home/Document/hacker
的上一層目錄,意即 /Home/Document
。
同理,我們可以做一些變化,例如:
/Home/Document/../Document/hacker
電腦解析時,由左而右(如下圖所示),我們可以看到:
- 第一步,先將
/Home/Document/../
解析為從/Home/Document/
目錄開始「到上一層目錄」,即為/Home/
- 第二步再往後讀取
/Document/hacker
,組成Home/Document/hacker
為最終的結果。
由上圖的解析我們可以知道 /Home/Document/../Document/hacker
同義於 /Home/Document/hacker
。
從解析過程也可以發現,我們可以透過../
在目錄間穿梭,例如下方的例子,透過 ../
移動到其他目錄。
/Home/Document/../Media 同義於 /Home/Media
/Home/../Logs 同義於 /Logs
/Home/Document/../Picture 同義於 /Home/Picture
同樣的概念,應用到網站的目錄( Path )上,效果也是一樣的,有興趣的話,大家也可以實際在瀏覽器網址上試一試。
http://hahow.in/courses/../ 同義於 http://hahow.in/
而目錄遍歷的攻擊,便是駭客就是利用這種目錄解析的原理,透過../
在目錄間穿梭,移動到他不該移動到的目錄底下,存取機密資訊。
簡單來說,目錄( Path )表示程式碼要前往/執行的位置,駭客透過修改目錄位置,來讓程式碼前往/執行在錯誤的地方。以譬喻的方式來說,假設有一個老闆,請秘書幫他到辦公室「抽屜」裡面取「文件」出來交給「客戶」,文件的「抽屜」位置即為目錄 ( Path ) ,客戶故意修改了給秘書的指令,「改」了秘書取文件的抽屜位置,讓秘書到「另一個抽屜」取得「另一份機密文件」交給客戶,此時客戶扮演的角色就跟駭客一樣,修改目錄( Path )取得機密文件。
基於以上的攻擊原理,以下我將分享幾種實際攻擊的範例。
▍目錄遍歷實際攻擊範例
以下將介紹兩種不同的目錄遍歷攻擊,第一種是「前端頁面網址的目錄遍歷」另一種是「API 路由的目錄遍歷」。
1. 前端頁面網址的目錄遍歷
架設網站的時候,會將網頁放在伺服器的某個目錄之下,舉例來說,你架設了一個網站,網址為 https://game.com
而網頁檔案的目錄如下所示:
/home/document/123.html
/home/app.conf
網址 https://game.com/document/123.html
對應到 /home/document/123.html
這個檔案,而 app.conf
是網站的設定檔,裡面有重要的機密設定資料,例如資料庫連線用的帳號密碼等等。
駭客會利用 ../
指令企圖去存取 app.conf
,用以下網址去存取你的網站:
http://game.com/document/../app.conf
上述該網址對應到伺服器實際的目錄,即為:
/home/document/../app.conf
此路徑又同義於:
/home/app.conf
由此方式,駭客可以從瀏覽器網址存取到 app.conf
。這裡有一點要特別說明,在真正攻擊的時候通常不能直接使用 ../
在網址上,因為這個加了../
是要被傳送到「伺服器」端做解析的,如果直接在網址目錄的表示字串使用 ../
會被「客戶端」的瀏覽器解析,變成無法傳遞到「伺服器」端,而造成攻擊失敗,如下圖所示,客戶端解析後會以為網址是要連到 https://game.com/app.conf
,根本沒有對應到 GET /documenmt
這個路由 (Router) ,導致伺服器端並沒有接收到我們傳遞的目錄,而造成攻擊失敗。
若是要避免客戶端解析我們傳送的目錄,便需要對 ../
進行 Url Encode 變成 ..%2F
,如下圖所示:
透過編碼後的參數 ..%2Fapp.conf
就可以成功對應到GET /documenmt
這個路由,由伺服器端解析目錄,成功達成攻擊。
這種攻擊方式通常出現在伺服器端的檔案權限沒有設定正確,或是進行服務 (Serving) 的目錄,不是白名單的方式,而是由伺服器端的程式碼使用「使用者傳入的字串」組成 目錄字串所造成的,例如:使用 +
來做字串相加。
以下提供 express.js 為例,展示使用「使用者傳入的字串」組成目錄字串而造成問題的程式碼,其中 filename
為使用者傳入的餐數,/home/documment/${filename}
為組合後的字串。
一般來說,這類透過前端頁面路由來做目錄遍歷的攻擊,目前比較少見,因為除非是你自己去細化網站的路由 (Router) 設定,若是直接使用一些目前較新的前端框架(例如:Next.js),這些前端的框架通常會幫你處理掉目錄遍歷的問題,不會任由使用者傳入的惡意參數(例如:../
) 來存取到不該存取的檔案。
下面要介紹的攻擊範例,就是較多人會忽略的案例 「API 路由的目錄遍歷」。
2. API 路由的目錄遍歷
在我的職涯中,即使些有經驗的工程師仍會忽略「API 路由的目錄遍歷」問題,因為通常 API 的路由 (Router) 是由自己設定/撰寫的,若是不小心沒處理好,便會造成漏洞,一定要特別小心,以下將舉例說明。
假定一個情境,你架設一個部落格網站,有後端內部的 API ,分別為:
GET http://backend.corp.com/posts/${postId}
:傳入部落格文章編號 post id (以下稱 postId ),回應相對應的部落格文章 (以下稱 post )GET http://backend.corp.com/systeminfo
:為了查看系統方便,有一個網址,顯示系統機密狀態資訊
由於後端 API 要跟前端串接,要取得部落格 post ,你使用 Node.js 做了一個中介層串接後端內部 API ,如下:
當使用者傳入部落格文章編號 postId 時,回傳相對應的部落格文章 post ,程式碼看起來很完美,我們並沒有特別做什麼危險的事情,但你看出問題了嗎?這是一段可能造成問題的程式碼。
因為對於駭客來說,他並不會乖乖的傳入 postId
,而是會利用目錄遍歷的原理,傳入:
GET /api/posts/..%2Fsysteminfo
來存取系統機密資訊。這裡要特別說明的是 ..%2F
同義於 ../
,使用 ..%2F
可以成功通過 app.get(`/api/posts/:postId`)
的路由,進而傳送到 ${req.params.postId}
去組合字串,使得程式呼叫的後端內部 API 變成:
http://backend.corp.com/posts/../systeminfo同義於http://backend.corp.com/systeminfo
因此造成攻擊發生。
這裡的範例是使用 GET 作為例子,同樣的原理利用在 POST/PUT/DELETE 上面也是行得通的,也會造成更大的危害。
回到上述的例子,你可能會想,駭客怎麼會知道 systeminfo 這個路徑?如果駭客不知道的話不就沒事了?是的,如果駭客不知道 systeminfo 這個目錄,是無法造成攻擊的,但在實務上來說,如果你有這類的漏洞,駭客會使用暴力法,寫程式去不斷地試各種不同的路徑,猜你的路徑背後有什麼資料,因此較為安全的做法,還是不要有這種漏洞給駭客有機可乘得好。
▍如何防禦目錄遍歷
總和上述的攻擊案例,我們可以將防禦方式歸納為以下幾點:
- 正確的設定目錄底下的權限:如此一來,當駭客透過「前端頁面網址的目錄遍歷」存取檔案時,存取到沒有權限的目錄時,便無法正確顯示。除此之外,上述「API 路由的目錄遍歷」的案例,也是因為 systeminfo 系統機密資訊沒有進行權限限制,造成駭客做目錄遍歷時可以直接存取,這也是不應該的。若是有權限限制,即使不小心被遍歷到,也可以被權限擋掉。以剛才 Node.js 的例子來說,可以將
root:'/home/'
改成root:'/home/document/'
來鎖定目錄讀取的權限:
- 組合路由 (Router) 字串的時候驗證輸入:以上述「API 路由的目錄遍歷」的案例來說,若是已知 postId 都是數字,便應該驗證資料是數字才可以進行字串組合,或是說,若已知的使用者輸入的字串是某種固定的格式,也可以用正則運算式先行驗證,再進行字串組合會比較安全。
最重要的心態是,不要以為目錄遍歷攻擊只會發生在前端頁面網址上,對於每個 API 的路由 (Router) 都要非常小心才是,再次強調,目錄遍歷 (Path Traversal) 攻擊原理非常簡單,卻也是最容易被工程師忽略的,一個細節沒注意,就容易造成漏洞。
以上便是我對目錄遍歷 (Path Traversal) 的分享,希望對大家有幫助。對駭客與資訊安全有興趣的朋友,也可以參考我其他文章或是線上課程《經典駭客攻擊教程:給每個人的網站安全入門》:
若是喜歡我分享的內容,歡迎幫我按個拍手,可拍 50下,給我一點鼓勵,或是加入我的粉絲團《程式猿吃香蕉🍌》,一起分享軟體知識與心得!