[閒聊] 2017.W27 - Path Traversal

作者: CMJ0121 (請多指教!!)   2017-07-04 21:58:14
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/
作者: skycat2216 (skycat2216)   2017-08-17 20:59:00
12.8GB/S AS FUK

Links booklink

Contact Us: admin [ a t ] ucptt.com