Directory Traversals

Directory traversals come from a lack of filtering/encoding of information used as part of a path by an application.

As with other vulnerabilities, you can use the "same value technique" to test for this type of issue.

For example, if the path used by the application inside a parameter is /images/photo.jpg. You can try to access:

  • /images/./photo.jpg: you should see the same file.

  • /images/../photo.jpg: you should get an error.

  • /images/../images/photo.jpg: you should see the same file again.

  • /images/../IMAGES/photo.jpg: you should get an error (depending on the file system), or something weird is going on.

If you don't have the value images and the legitimate path looks like photo.jpg, you will need to work out what the parent repository is.

Once you have tested that, you can try to retrieve other files.

On Linux/Unix the most common test case is the /etc/passwd.

You can test: `images/../../../../../../../../../../../etc/passwd`

If you get the passwd file, the application is vulnerable. The good news is that you don't need to know the number of ../. If you put too many, it will still work.

Another interesting thing to know is that if you have a directory traversal in Windows, you will be able to access test/../../../file.txt, even if the directory test does not exist.

This is not the case on Linux.

This can be really useful where the code concatenates user-controlled data, to create a file name.

For example, the following PHP code is supposed to add the parameter `id` to get a file name (`example_1.txt` for example). 

On Linux, you won't be able to exploit this vulnerability if there is no directory starting with example_, whereas on Windows, you will be able to exploit it, even if there is no such directory.

$file = "/var/files/example_".$_GET['id'].".txt";

In these exercises, the vulnerabilities are illustrated by a script used inside an <img tag.

You will need to read the HTML source (or use "Copy image URL") to find the correct link, and start exploiting the issue.

The first example is a really simple directory traversal. You just need to go up in the file system, and then back down, to get any files you want. In this instance, you will be restricted by the file system permissions, and won't be able to access /etc/shadow, for example.

In this example, based on the header sent by the server, your browser will display the content of the response. Sometimes the server will send the response with a header Content-Disposition: attachment, and your browser will not display the file directly. You can open the file to see the content. This method will take you some time for every test.

Using a Linux/Unix system, you can do this more quickly, by using wget or curl.

In this example, you can see that the full path is used to access the file.

However, if you try to just replace it with /etc/passwd, you won't get anything.

It looks like a simple check is performed by the PHP code.

However, you can bypass it by keeping the beginning of the path and adding your payload at the end, to go up and back down within the file system.

This example is based on a common problem when you exploit directory traversal: the server-side code adds its own suffix to your payload.

This can be easily bypassed, by using a NULL BYTE (which you need to URL-encode as %00).

Using NULL BYTE to get rid of any suffix added by the server-side code, is a common bypass, and works really well in Perl and older versions of PHP.

For Windows

On Linux, we usually use the /etc/passwd file to test directory traversal vulnerabilities. On Windows, we can use the file C:\Windows\System32\drivers\etc\hosts to test directory traversal vulnerabilities, which is readable by all local users. By displaying this file, we can confirm the vulnerability exists and understand how the web application displays the contents of files. After confirming the vulnerability, we can try to specify files containing sensitive information such as configuration files and logs.

In general, it is more difficult to leverage a directory traversal vulnerability for system access on Windows than Linux. In Linux systems, a standard vector for directory traversal is to list the users of the system by displaying the contents of /etc/passwd, check for private keys in their home directory, and use them to access the system via SSH. This vector is not available on Windows and unfortunately, there is no direct equivalent. Additionally, sensitive files are often not easily found on Windows without being able to list the contents of directories. This means to identify files containing sensitive information, we need to closely examine the web application and collect information about the web server, framework, and programming language.

Once we gather information about the running application or service, we can research paths leading to sensitive files. For example, if we learn that a target system is running the Internet Information Services (IIS) web server, we can research its log paths and web root structure. Reviewing the Microsoft documentation,6 we learn that the logs are located at C:\inetpub\logs\LogFiles\W3SVC1. Another file we should always check when the target is running an IIS web server is C:\inetpub\wwwroot\web.config, which may contain sensitive information like passwords or usernames.

In this section, we used the ../ sequence for directory traversal on Linux. As shown, Windows uses backslashes instead of forward slashes for file paths. Therefore, ..\ is an important alternative to ../ on Windows targets. While RFC 17387 specifies to always use slashes in a URL, we may encounter web applications on Windows which are only vulnerable to directory traversal using backslashes. Therefore, we should always try to leverage both forward slashes and backslashes when examining a potential directory traversal vulnerability in a web application running on Windows.

Last updated