所有内容,来自burpsuite官方靶场(portswigger)
目录遍历
什么是目录遍历?
目录遍历(也称为文件路径遍历)是一种 Web 安全漏洞,允许攻击者读取运行应用程序的服务器上的任意文件。这可能包括应用程序代码和数据、后端系统的凭据以及敏感的操作系统文件。在某些情况下,攻击者可能能够写入服务器上的任意文件,从而允许他们修改应用程序数据或行为,并最终完全控制服务器。
通过目录遍历读取任意文件
考虑一个显示待售商品图像的购物应用程序。图像通过一些 HTML 加载,如下所示:
<img src="loadImage?filename=218.png">
该loadImage
网址将filename
参数,返回指定的文件的内容。图像文件本身存储在该位置的磁盘上/var/www/images/
。要返回图像,应用程序将请求的文件名附加到此基本目录并使用文件系统 API 读取文件的内容。在上述情况下,应用程序从以下文件路径读取:
/var/www/images/218.png
该应用程序没有针对目录遍历攻击实施任何防御,因此攻击者可以请求以下 URL 从服务器的文件系统中检索任意文件:
https://insecure-website.com/loadImage?filename=../../../etc/passwd
这会导致应用程序从以下文件路径读取:
/var/www/images/../../../etc/passwd
该序列../
在文件路径内有效,意味着在目录结构中上一级。三个连续的../
序列从/var/www/images/
文件系统根目录开始,因此实际读取的文件是:
/etc/passwd
在基于 Unix 的操作系统上,这是一个标准文件,其中包含在服务器上注册的用户的详细信息。
在 Windows 上,../
和..\
都是有效的目录遍历序列,检索标准操作系统文件的等效攻击是:
https://insecure-website.com/loadImage?filename=..\..\..\windows\win.ini
LAB:文件路径遍历简单案例
利用文件路径遍历漏洞的常见障碍
将用户输入放入文件路径的应用程序实现了对路径遍历攻击的某种防御,而这些通常可以被规避。如果应用程序从用户提供的文件名中剥离或阻止目录遍历序列,则可以使用各种技术绕过防御。
可以使用文件系统根目录中的绝对路径(例如filename=/etc/passwd
)来直接引用文件,而无需使用任何遍历序列。
LAB:文件路径遍历,绝对路径绕过
使用嵌套遍历序列,例如....//
或....\/
,当内部序列被剥离时,它将恢复为简单的遍历序列
LAB:文件路径遍历,双写绕过
使用各种非标准编码(例如..%c0%af
或..%252f
)来绕过输入过滤器
LAB:文件路径遍历,双URL编码绕过
如果应用程序要求用户提供的文件名必须以预期的基本文件夹开头,例如/var/www/images
,则可能包含所需的基本文件夹,后跟合适的遍历序列。例如:
filename=/var/www/images/../../../etc/passwd
LAB:文件路径遍历,路径开始验证
如果应用程序要求用户提供的文件名必须以预期的文件扩展名结尾,例如.png
,则可以使用空字节有效地终止所需扩展名之前的文件路径。例如:
filename=../../../etc/passwd%00.png
LAB:文件路径遍历,通过空字节绕过文件拓展名验证
如何防止目录遍历攻击
防止文件路径遍历漏洞的最有效方法是完全避免将用户提供的输入传递给文件系统 API。可以重写执行此操作的许多应用程序函数,以更安全的方式提供相同的行为。
如果认为将用户提供的输入传递给文件系统 API 是不可避免的,那么应该同时使用两层防御来防止攻击:
- 应用程序应在处理之前验证用户输入。理想情况下,验证应与允许值的白名单进行比较。如果这对于所需的功能是不可能的,则验证应验证输入是否仅包含允许的内容,例如纯字母数字字符。
- 验证提供的输入后,应用程序应将输入附加到基本目录并使用平台文件系统 API 规范化路径。它应该验证规范化路径是否以预期的基本目录开头。
下面是一些简单的 Java 代码示例,用于根据用户输入验证文件的规范路径:
File file = new File(BASE_DIRECTORY, userInput);if (file.getCanonicalPath().startsWith(BASE_DIRECTORY)) { // process file}
评论区