一、目录遍历漏洞
目录遍历漏洞允许攻击者通过向应用程序提交恶意构造的文件路径,绕过安全限制,访问Web根目录以外的文件或目录
1-漏洞原理
应用程序在处理文件请求时(如图片下载、读取文件模板),通常需要根据用户通过的参数(文件名、路径)来定位文件。如果开发者没有对用户输入进行充分过滤和校验,攻击者就可以在参数中插入路径跳转符(如../或..\),从而跳出预期目录,访问服务器文件系统中的任意文件
例如,一个文件下载功能通过URL调用
http://example.com/download?file=report.pdf
服务端代码可能如下:
php
$file = $_GET['file'];
readfile('/var/www/files/' . $file);
正常情况下,会读取/var/www/files/report.pdf。但如果攻击者将file参数改为../../../../etc/passwd,则实际路径变为/var/www/files/../../../../etc/passwd,经过路径解析后等价于/etc/passwd,从而读取到系统密码文件。
2-常见攻击场景
(1)读取敏感文件
我们可以构造恶意的文件路径去读取操作系统下的敏感文件,如:
- Linux下的
/etc/passwd、/etc/shadow - Windows下的
C:\boot.ini、C:\Windows\win.ini - Web应用的配置文件、数据库连接信息等。
(2)遍历目录列表
如果服务器配置不当,攻击者可能通过路径遍历列出目录内容,进一步寻找有用信息。
3-漏洞危害
目录遍历漏洞无法直接执行远程代码执行等恶意操作,但是存在以下危害:
- 信息泄露:攻击者能够读取系统文件、源代码、配置文件,导致敏感数据(如密钥、账号密码)泄露。
- 扩大攻击面:泄露的信息可能暴露系统内部结构、软件版本,帮助攻击者发现更多漏洞。
- 潜在提权:如果读取到包含凭证的文件(如备份文件),可能直接获得系统访问权限。
二、绕过方法
在实战中,难免遇到对../的过滤,分析一下绕过方法
1-编码绕过
(1)URL编码
在HTTP传输中,特殊符号通常能够被URL编码,.是%2e,/是%2f,\是%5c,根据这些编码原则,我们尝试绕过
../../../../etc/passwd
%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd
更高级的,可以使用双重编码 %252e%252e(%25 是 % 的编码),如果后端错误地进行了多次解码,也可能绕过
(2)Unicode/UTF-8编码绕过
在一些特定的解析环境下,攻击者甚至可以使用全角字符 .. 或 / 进行绕过,或者利用UTF-8编码的多种表示形式。
2-双写绕过
如果是 filename = filename.replace("../", "") 这类经典过滤方法,只是简单地将 ../ 替换为空字符串,且只执行一次,那么攻击者可以输入 ....//。
处理过程如下:
- 用户输入:
....//etc/passwd - 后端替换
../为空:第一次发现中间的../,将其删除,字符串变为../etc/passwd。 - 漏洞点 :如果替换后没有进行第二轮检查,那么现在字符串里正好剩下一个
../,攻击成功。
同理,还有..././(替换../后剩下./,但./通常无害,需要结合其他技巧)、....\/(利用反斜杠)等变体。
3-空字节截断
在处理文件扩展名校验、拼接字符串时,如果逻辑不当,我们可以使用%00截断,这在php 5.4.3版本之前是有效的。
?filename=../../../etc/passwd%00.jpg
假设后端代码逻辑是:检查文件名是否以 .jpg 结尾,如果是,则将../../../etc/passwd%00.jpg拼接路径读取。但在后续实际拼接路径字符串或调用系统函数时,遇到 %00(解码后为NULL字符)就认为字符串结束了,实际读取的路径变成了 ../../../etc/passwd。
三、目录遍历漏洞和文件包含的对比
因为目录遍历和文件包含在攻击利用上有的手法比较相似,所以会容易混淆,现在将其剖析一下
1-利用函数
(1)目录遍历
目录遍历的漏洞代码如下:
php
<?php
$file=$_GET['file'];
readfile($file);
?>
传递参数phpinfo.php

]
我们可以读取到php文件源码,但是无法执行文件
(2)文件包含
文件包含的漏洞代码
php
<?php
$file=$_GET['file'];
inculde($file);
?>
同样传递参数phpinfo.php

phpinfo.php被解析执行,如果想要读取源码就需要利用php://伪协议
http://php/include.php?file=php://filter/read=convert.base64-encode/resource=phpinfo.php
解码得到源码

2-区别
(1)攻击目的
文件包含:通常是为了执行文件中的代码(通常为脚本语言),实现远程命令执行、后门植入等。目录遍历:则是读取文件内容,获取敏感信息(如密码、配置)。
(2)危害程度
文件包含:通常更高,可能直接导致服务器沦陷。目录遍历:危害程度较低,但敏感信息泄露可辅助进一步攻击。
(3)对文件要求
文件包含:包含的文件必须是可解析的(如PHP文件),如果包含的是纯文本,则可能只是显示内容(效果类似目录遍历)。目录遍历:任何文件均可读取,不要求可执行。
(4)利用特征
文件包含:常出现在动态页面参数中(如?page=about)。目录遍历:常出现在文件下载、图片显示等参数中(如?file=image.jpg)。
3-联系
(1)路径遍历技术相同
两者都可能使用../等路径跳转符来访问非预期目录。例如,LFI攻击中经常使用../../../../etc/passwd来尝试包含系统文件。
(2)常同时存在
很多Web应用中,文件包含和目录遍历往往源于共同的缺陷------对用户输入的文件路径过滤不严。
4-典型示例
- 文件包含 :URL:
http://example.com/index.php?page=../../../../var/log/apache/access.log,如果access.log中包含攻击者注入的PHP代码,服务器会执行该代码,导致RCE。 - 目录遍历 :URL:
http://example.com/download.php?file=../../../../etc/passwd,服务器直接读取并返回/etc/passwd文件的内容。
三、总结
文件包含和目录遍历都是危险的输入验证漏洞,但前者侧重于代码执行,后者侧重于文件读取。在安全防护上,都需要严格过滤用户输入的文件路径,禁用不必要的文件操作函数,并遵循最小权限原则。