Exploiting Path Traversal
Author: HollyGraceful Published: 07 June 2021 Last Updated: 03 November 2022
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:
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:
The above is the equivalent of:
The `../` effectively moves the attacker up one directory, if too many of those sequences are supplied, generally any additional ones are simply ignored, so:
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:
To exploit the issue we simply place one of the payloads in the target URL:
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.