作者CMJ0121 (不要偷 Q)
看板NetSecurity
标题[闲聊] 2017.W27 - Path Traversal
时间Tue Jul 4 21:58:14 2017
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://webptt.com/cn.aspx?n=bbs/NetSecurity/M.1499176697.A.AA1.html
1F:推 skycat2216: 12.8GB/S AS FUK 08/17 20:59