目录穿越漏洞(Directory Traversal)是Web安全领域中最常见但往往被低估的威胁之一。攻击者通过操纵文件路径中的../序列,能够突破应用程序的路径限制,读取服务器上任意文件,甚至写入恶意代码。核心问题在于:大多数开发者以为简单过滤../就能阻止攻击,但实际绕过手法层出不穷,从编码变形到长度截断,从符号链接到路径规范化差异,均能轻松绕过表面防御。本文从实战角度拆解七种绕过技巧,并给出可落地的三层防御策略。
当应用程序根据用户输入拼接文件路径时,如果没有对../或..\进行充分过滤,攻击者就可以构造类似../../etc/passwd的路径访问系统文件。据OWASP《Web应用安全漏洞分类》数据显示:目录穿越漏洞在Top 10漏洞中排名第7,影响约15%的Web应用。但防御难点在于:不同操作系统、不同语言框架、不同编码方式下的路径解析规则存在差异,导致黑名单过滤极易被绕过。
编码绕过最常见的变形是将../中的点号或斜杠进行URL编码。例如%2e%2e%2f代表../,%2e%2e%5c代表..\。很多开发者只对原始字符做过滤,却忽略了编码后的输入。实际测试中,使用双编码(如%252e%252e%252f)可以绕过一层解码后的过滤。
# 原始路径过滤
if "../" in user_input:
return False
# 编码绕过:%2e%2e%2f
user_input = "%2e%2e%2f%2e%2e%2fetc/passwd"
# 解码后为 ../../etc/passwd
在Windows系统中,路径长度限制并非绝对。NTFS文件系统支持短路径名(8.3格式),例如C:\Program Files会被表示为C:\PROGRA~1。攻击者可以利用这一特性将长时间路径压缩为短路径,从而绕过部分基于长度的检测。例如,使用C:\progra~1\..\..\windows\system32\config\sam可以绕过包含"Program Files"的过滤规则。
| 绕过方式 | 原始路径 | 变形后路径 |
|---|---|---|
| 短路径 | C:\Program Files\..\..\Windows\System32 | C:\PROGRA~1\..\..\Windows\System32 |
| 文件流 | C:\boot.ini::$DATA | C:\boot.ini |
不同编程语言和框架对路径的规范化处理不同。例如PHP的realpath()和Java的normalize()函数处理结果可能存在差异。攻击者可以通过构造包含多个连续点或斜杠的路径,利用规范化差异绕过限制。例如//etc///passwd在某些系统中等同于/etc/passwd,而过滤规则可能只检查单斜杠。
如果Web服务器允许上传文件,攻击者可以上传一个符号链接文件,指向目标敏感文件(如/etc/shadow)。当应用程序读取该上传文件时,实际上访问的是链接指向的真实文件。这种攻击在允许上传文件且未禁用符号链接的系统中非常有效。
在PHP 5.3.4之前的版本中,路径字符串遇到空字节(%00)会被截断,导致../过滤失效。例如构造../../etc/passwd%00.txt,系统会忽略%00后的内容,最终访问../../etc/passwd。虽然该漏洞在新版本中已被修复,但仍有大量遗留系统未更新。
如果应用程序允许用户指定完整路径,攻击者可以直接使用绝对路径如C:\Windows\System32\config\SAM或/var/log/auth.log,而无需使用../。很多开发者只过滤了相对路径中的../,却忽略了绝对路径的风险。
有些过滤规则会递归删除../,但攻击者可以通过构造嵌套路径如....//或....//./来绕过。例如..\/../在第一次删除后可能变成../,从而绕过单次过滤。
第一层:白名单验证。只允许用户请求预定义的文件列表,拒绝所有其他路径。第二层:路径规范化与限制。使用语言内置的路径规范化函数(如Python的os.path.abspath()、Java的Paths.get().normalize()),然后检查规范化后的路径是否在允许的目录内。第三层:最小权限原则。将Web服务器进程运行在受限用户账户下,并限制其对文件系统的访问权限,即使漏洞被利用,也只能读取非敏感文件。
据MITRE CVE数据库统计,超过80%的目录穿越漏洞可以通过路径规范化加固提前预防。正确的做法是:永远不要信任用户输入,对路径进行规范化后检查是否在预期的根目录范围内,并配合操作系统级别的访问控制。例如,在Nginx中可以通过alias指令和root指令的严格配置来限制目录访问。
location /downloads/ {
alias /var/www/downloads/; # 必须确保alias路径末尾有斜杠,且用户无法跳出该目录
# 通过限制$uri避免目录穿越
if ($uri ~ "/\.\.") {
return 403;
}
}
最后,建议定期使用自动化检测工具(如Burp Suite的Intruder模块、OWASP ZAP)对应用进行目录穿越扫描,并结合SAST(静态应用安全测试)工具在代码提交时自动漏洞检测。只有通过持续的安全测试和加固,才能有效抵御不断演变的绕过技术。
评论
加载中...