Skip to content

Latest commit

 

History

History
187 lines (116 loc) · 5.57 KB

path_traversal.md

File metadata and controls

187 lines (116 loc) · 5.57 KB

Path Traversal

A Path Traversal vulnerability allows you to view the contents of files outside of the web server root directory.

Local File Inclusion vulnerabilties usually involve Path Traversal techniques. This document is specifically about those traversal techniques and not LFI in general.

The impact is usually Information Disclosure (e.g. usernames, passwords, keys, source code). But it can also lead to exploit chains resulting in code execution (RCE) if the included file gets executed (e.g. an included script file or poisoned log file) by an interpreter like PHP.

Vanilla example

For example a web application might serve files based on an HTTP GET url parameter:

http://server.example/index.php?image=cats.jpg
http://server.example/index.php?image=dogs.jpg
http://server.example/index.php?image=boats.png

The developers intended this functionality to only serve files from a dedicated web server directory, e.g.: /var/www/html/animalpics/

If the file loading functionality is implemented naively then a user might able to input absolute paths instead:

http://server.example/index.php?image=/etc/passwd

Which loads an arbitrary file on the server accessible by the user that executes the web server application.

A common target and proof-of-concept is loading the /etc/passwd file which leaks all the usernames of local users on the server host.

If file loading functionality does not allow absolute paths, then it might allow relative paths:

http://server.example/index.php?image=../../../../../../etc/passwd

This would navigate six or less directories up from the current working directory (e.g. /var/www/html/) until it reaches the root directory (/) and from there accesses the same file /etc/passwd.

Depending on the current working directory of the server application more ../ might be required for this work.

In rare cases the number of ../ must be exact, so in the case of /var/www/html/ you would have to be navigate exactly three directories up.

Url-Encoding Reference

Encoding and double encoding:

../
%2e%2e%2f
%2e%2e/
..%2f
..%c0%af

Windows backslash style:

..\
%2e%2e%5c
%2e%2e\
..%5c
%252e%252e%255c
..%255c
..%c1%9c

Note: If you manually input a backslash (\) in a web browser url bar then it will usually replace it with a regular slash (/) unless you url-encode it first.

Common Proof-of-Concept Examples

Linux:

https://vulnerable.example/loadImage?filename=../../../../etc/passwd

Windows:

https://vulnerable.example/loadImage?filename=..\..\..\windows\win.ini 

Null Byte

Sometimes the file inclusion has hardcoded strings appended after the input.

The most common case would be a file extension like .jpg or .php appended after the input.

For example there might be an url:

http://server.example/index.php?navigation=calendar

Behind the scenes the server performs something like (PHP example):

$input = $_GET['navigation'];
$filetarget = $input . '.php'; // input + '.php'
include($filetarget);

This would still allow a path traversal. But the included filename would have to end with .php

Often this can be circumvented by using a Null byte:

http://server.example/index.php?navigation=../../../../../etc/passwd%00

%00 is the url-encoded Null byte.

In many applications the ending of a string is marked by a Null byte. So the parts of the string after an inserted %00 will be ignored.

These kinds of strings are called "C-style strings" because the C Programming Language traditionally uses Null termination.

PHP is written in C and C++ and was vulnerable to the this trick for a long time. But this trick won't work past PHP version 5.3.4

It might still work with other server applications though.

Another use case might be a filter that ensures that included urls must end with a certain string like .jpg.

This could be possibly be circumvented by using:

http://server.example/index.php?navigation=../../../../../etc/passwd%00.jpg

Filter Bypass: Naive Replace

A naive "fix" for a path traversal vulnerability might be the use of a non-recursive replaceAll() type function, which removes all occurances of ../ from the input string.

This can be circumvented with:

....//....//....//....//etc/passwd

After the replaceAll() each ....// becomes a regular ../

Obviously even if the replaceAll() is repeated multiple times, you could just keep multiplying the characters for each iteration. A recursive replace would defeat this though.

Filter Bypass: Unnecessary Urldecoding

If...

  • the input gets url-decoded (usually happens automatically by web server frameworks)
  • a filter removes all occurances of . and / or a combination thereof
  • the input gets url-decoded again unnecessarily

If that is the case then simply url-encode your ../ twice.

../
%2e%2e%2f
%25%32%65%25%32%65%25%32%66

The second server-side url-decode will restore the ../ past the filtering.

Filter Bypass: startswith

Another naive "fix" for a path traversal might be a startswith() function that ensures the input path starts with a certain directory or does not start with ../.

For example:

?filename=/var/www/images/cats.jpg

And the server application rejects input that does not start with /var/www/images/.

Then the bypass is:

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

References