精華區beta NetSecurity 關於我們 聯絡資訊
2017.W27 - Path Traversal > 重新設計輪子當然可以 只要妳開的車裝上你的輪子 ## 前言 ## 最近在處理公司上的事情 一直覺得重新造輪子是個不錯的概念 但是也不要在公司產品上用你設計輪子啊 QQ ## 內容 ## Path Traversal 或者稱為 Directory Travelsal 是一系列安全性的漏洞概念 主要是處理檔案路徑時不正確 造成存取的檔案超出設計者的預期 從 CWE 列表中可以從 CWE-21 - Pathname Traversal and Equivalence Errors[0] 開始 引起各種 Path Travelsal 的問題 主要的問題都會回歸到所謂的 CWE-20 Improper Input Validateion[1] 也就是不正確的使用者輸入驗證 簡單的例子:有一個 web service 會提供 上傳檔案 與 自動轉檔 功能 轉檔功能操作時 需要指定檔案的路徑 一個基本的驗證則是快速判斷檔案路徑中是否包含 . 跟 .. (Linux-Based) 但是這樣的假設也不盡正確 原因是這樣就代表不允許使用 ..abc 這樣的名稱 因此一個聰明的概念就是利用 / 來切割檔案名稱 並且逐一檢查是否包含 . 或者 .. 然而一個優秀的 c/c++ programmer 應該會知道 glibc 會提供 realpath 這個函數 根據 man realpath 可以得到他的主要描述 returns the canonicalized absolute pathname 在下面的描述中的第一段話更明確的表示他的主要功能 The realpath() function resolves all symbolic links, extra ``/'' characters, and references to /./ and /../ in file_name. 這代表用 realpath 處理過後的檔案已經不會包含任何 . .. 跟 symbolic link 這些有機會跳轉的符號 從 glibc 的 realpath 的 source code[2] 來看 可以看到 __realpath 主要有以下幾個判斷 1. 輸入的檔名是否為空 2. 當下路徑不存在則報錯 3. 相對路徑則自動帶入當下路徑 getcwd 4. 依序處理每一個 / 切割的元素 4.1 無視連續的 / 4.2 無視 . 的元素 4.3 .. 則跳到上一個資料夾 已經是 / 則無視 4.4 透過 stat 判斷檔案是否檔案、資料夾是否存在 4.5 如果是 symbolic link 則透過 readlink 獲得真實路徑 透過 realpath 的好處在於你可以獲得一個乾淨的絕對路徑 之後就能透過這個路徑 判斷目的地是否在允許的路徑之下 至於為什麼不需要重新造輪子 原因在於這個問題不是第一天發現 因此在這個平台下這個方式會經過各種優化 像是在這篇文章中[3] 提到的 GNU 的 yes 指令快到突破天際 (12.8 GB/s) 這就是針對平台已經特殊優化的結果了 再重新設計一個 yes 除非有特殊的需求 不然還是乖乖用經過千錘百鍊的版本吧! [0]: https://cwe.mitre.org/data/definitions/21.html [1]: https://cwe.mitre.org/data/definitions/20.html [2]: https://github.com/lattera/glibc/blob/master/stdlib/canonicalize.c [3]: https://www.reddit.com/r/unix/comments/6gxduc/how_is_gnu_yes_so_fast/ -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.193.122.171 ※ 文章網址: https://www.ptt.cc/bbs/NetSecurity/M.1499176697.A.AA1.html