Directory traversal 目录遍历漏洞

26/100

保存草稿

发布文章

ZripenYe

未选择文件

new

什么是目录遍历?

目录遍历(也称为文件路径遍历)是一种 Web 安全漏洞,​​允许攻击者读取运行应用程序的服务器上的任意文件​​。这可能包括应用程序代码和数据、后端系统的凭据以及敏感的操作系统文件。在某些情况下,攻击者可能能够写入服务器上的任意文件,从而允许他们修改应用程序数据或行为,并最终完全控制服务器

Directory traversal 目录遍历漏洞_文件系统

通过目录遍历读取任意文件

假设一个显示待售商品图像的购物应用程序。图像通过一些 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


利用文件路径遍历漏洞的常见障碍

许多将用户输入放入文件路径的应用程序实现了对路径遍历攻击的某种防御,而这些通常可以被规避。

如果应用程序从用户提供的文件名中剥离或阻止目录遍历序列,则可以使用各种技术绕过防御。

  • 可以使用文件系统根目录中的绝对路径(例如filename=/etc/passwd)来直接引用文件,而无需使用任何遍历序列。
  • 可能能够使用嵌套遍历序列,例如....//或..../,当内部序列被剥离时,它将恢复为简单的遍历序列。
  • 可以使用各种非标准编码(例如..%c0%af或..%252f)来绕过输入过滤器。
  • 如果应用程序要求用户提供的文件名必须以预期的基本文件夹开头,例如/var/www/images,则可能包含所需的基本文件夹,后跟合适的遍历序列。例如:
filename=/var/www/images/../../../etc/passwd


  • 如果应用程序要求用户提供的文件名必须以预期的文件扩展名结尾,例如.png,则可以使用空字节有效地终止所需扩展名之前的文件路径。例如:
filename=../../../etc/passwd%00.png


如何防止目录遍历攻击

防止文件路径遍历漏洞的最有效方法是完全避免将用户提供的输入传递给文件系统 API。可以重写执行此操作的许多应用程序函数,以更安全的方式提供相同的行为。

如果认为将用户提供的输入传递给文件系统 API 是不可避免的,那么应该同时使用两层防御来防止攻击:

应用程序应在处理之前验证用户输入。理想情况下,验证应与允许值的白名单进行比较。如果这对于所需的功能是不可能的,则验证应验证输入是否仅包含允许的内容,例如纯字母数字字符。

验证提供的输入后,应用程序应将输入附加到基本目录并使用平台文件系统 API 规范化路径。它应该验证规范化路径是否以预期的基本目录开头。

下面是一些简单的 Java 代码示例,用于根据用户输入验证文件的规范路径:

File file = new File(BASE_DIRECTORY, userInput);
if (file.getCanonicalPath().startsWith(BASE_DIRECTORY)) {
// process file
}


靶场复盘链接:

通过目录遍历读取任意文件

假设一个显示待售商品图像的购物应用程序。图像通过一些 HTML 加载,如下所示:


该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

利用文件路径遍历漏洞的常见障碍

许多将用户输入放入文件路径的应用程序实现了对路径遍历攻击的某种防御,而这些通常可以被规避。

如果应用程序从用户提供的文件名中剥离或阻止目录遍历序列,则可以使用各种技术绕过防御。

可以使用文件系统根目录中的绝对路径(例如filename=/etc/passwd)来直接引用文件,而无需使用任何遍历序列。

可能能够使用嵌套遍历序列,例如…//或…/,当内部序列被剥离时,它将恢复为简单的遍历序列。

可以使用各种非标准编码(例如…%c0%af或…%252f)来绕过输入过滤器。

如果应用程序要求用户提供的文件名必须以预期的基本文件夹开头,例如/var/www/images,则可能包含所需的基本文件夹,后跟合适的遍历序列。例如:

filename=/var/www/images/../../../etc/passwd

如果应用程序要求用户提供的文件名必须以预期的文件扩展名结尾,例如.png,则可以使用空字节有效地终止所需扩展名之前的文件路径。例如:

filename=../../../etc/passwd%00.png

如何防止目录遍历攻击

防止文件路径遍历漏洞的最有效方法是完全避免将用户提供的输入传递给文件系统 API。可以重写执行此操作的许多应用程序函数,以更安全的方式提供相同的行为。

如果认为将用户提供的输入传递给文件系统 API 是不可避免的,那么应该同时使用两层防御来防止攻击:

应用程序应在处理之前验证用户输入。理想情况下,验证应与允许值的白名单进行比较。如果这对于所需的功能是不可能的,则验证应验证输入是否仅包含允许的内容,例如纯字母数字字符。

验证提供的输入后,应用程序应将输入附加到基本目录并使用平台文件系统 API 规范化路径。它应该验证规范化路径是否以预期的基本目录开头。

下面是一些简单的 Java 代码示例,用于根据用户输入验证文件的规范路径:

File file = new File(BASE_DIRECTORY, userInput);

if (file.getCanonicalPath().startsWith(BASE_DIRECTORY)) {

// process file

}

靶场复盘链接:

文件路径遍历的简单案例

使用绝对路径绕过过滤器

使用双重字符绕过过滤器

使用URL编码绕过过滤器

文件起始路径条件

空字节扩展名欺骗文件过滤器

文章目录