目录穿越漏洞
概念和实验参考自portswigger – https://portswigger.net/web-security/file-path-traversal
思维导图如下
概念与漏洞场景
目录穿越也称作目录遍历漏洞,这种漏洞允许攻击者读取服务器上的任意文件,例如源代码,数据凭证,os的敏感文件。甚至有可能可以在服务器上写入文件,从而修改程序数据和行为并最终控制服务器(getshell)
目录穿越漏洞场景
当程序通过url读取文件 – <img src="/loadImage?filename=218.png">
,
图片文件一般存在/var/www/images
,攻击者可以修改url的filename,使用文件系统api读取文件内容。
?filename="../../../etc/passwd"
– linux/unix?filename="..\..\..\win.ini"
– windows
事实上,网站通过文件路径加载文件的地方都有可能存在目录穿越漏洞
绕过方式
- 使用文件绝对路径读取 –
?filename=/etc/passwd
- 嵌套遍历符号 –
?filename=....//....//etc//passwd
or ?filename=..../\..../\/\etc/\passwd
这用来绕过非递归过滤的检测方式,如php中的str_replace()
函数就是非递归的 - 使用非标准编码例如url编码 –
?filename=..%c0%af
or?filename=..%252f
第一个使用了unicode,会将其解码为符号/
,使用..%c0%2f
,..%ef%bc%8f
也是可以的。第二个使用了二次urlencode注入,浏览器会先进行一次urldecode,将%25解码为符号%
,然后就组合成为了%2f
,%2f
就是符号/
的url编码,后端再次进行url解码,从而触发漏洞。同样,双重url编码将.
编码后就为%252e
- %00截断绕过 – 有些会要求在url中读取指定的后缀名文件,所以可以使用%00对文件后缀名进行截断 , 如
?filename=../../etc/password%00.png
。当然,对指定后缀文件名的绕过方式不止这一种,不同的处理,绕过方式不同,这里可以参照文件上传漏洞中的一些绕过方式
防御方式
-
避免用户的输入传递到文件系统api
-
双层防御
-
- 处理用户输入时对其进行验证,与白名单比较,验证输入是否只包含允许输入的内容
- 将输入附加到基本目录,使用平台系统api来规范化文件路径。验证文件路径是否以基本目录开头
以java代码为例验证路径是否规范
File file = new File(BASE_DIRECTORY,userInput);
if(file.getCanoncalPath().startsWith(BASE_DIRECTORY)){
// process file
}
burpsuite中的目录穿越fuzz功能
burp pro版本在inruder中提供了目录穿越的fuzz功能
在simple list中的从列表添加,选中路径遍历的fuzz字典即可
靶场实验
目录穿越的简单场景
Lab: File path traversal, simple case
抓包,网页的图片都是通过url加载的
将filename修改为 ../../../etc/passwd
提交数据即可看到响应的passwd文件内容
绝对路径绕过
Lab: File path traversal, traversal sequences blocked with absolute path bypass
还是抓取数据包,请求图片的方式不变
filename修改为绝对路径后提交数据
非递归过滤绕过
Lab: File path traversal, traversal sequences stripped non-recursively
还是抓包,将路径符双写即可
使用二次urldecode绕过
Lab: File path traversal, traversal sequences stripped with superfluous URL-decode
抓包,测试了双写,单次url编码都不行
将/
进行两次url编码,第二次编码%
路径起点验证
Lab: File path traversal, validation of start of path
抓包,这个实验中图片以绝对路径请求
那就以其绝对路径开头获取passwd即可
截断符%00绕过
Lab: File path traversal, validation of file extension with null byte bypass
抓包,使用简单payload测试,无果
编码测试同样失败
那么就可能是验证了文件后缀
使用%00进行截断