We can upload an image file (e.g.
image.jpg
), and store a PHP web shell code within it ‘instead of image data’, and if we include it through the LFI vulnerability, the PHP code will get executed and we will have remote code execution.
As mentioned in the first section, the following are the functions that allow executing code with file inclusion, any of which would work with this section’s attacks:
Function | Read Content | Execute | Remote URL |
---|---|---|---|
PHP | |||
include() /include_once() | ✅ | ✅ | ✅ |
require() /require_once() | ✅ | ✅ | ❌ |
NodeJS | |||
res.render() | ✅ | ✅ | ❌ |
Java | |||
import | ✅ | ✅ | ✅ |
.NET | |||
include | ✅ | ✅ | ✅ |
Image Upload
Craft Malicious Image
Let’s create a malicious gif
file as such:
Note: We are using a
GIF
image in this case since its magic bytes are easily typed, as they are ASCII characters, while other extensions have magic bytes in binary that we would need to URL encode. However, this attack would work with any allowed image or file type.
Now we go to Profile Settings
and click on the avatar image to select and upload our malicious image.
Uploaded File Path
Once we’ve uploaded our file, all we need to do is include it through the LFI vulnerability.
Let’s inspect the source code after uploading the image.
We can get its upload URL:
With the uploaded file path at hand, all we need to do is to include the uploaded file in the LFI vulnerable function, and the PHP code should get executed, as follows:
Zip Upload
There are a couple of other PHP-only techniques that utilize PHP wrappers to achieve the same goal. These techniques may become handy in some specific cases where the above technique does not work.
We can start by creating a PHP web shell script and zipping it into a zip archive (named shell.jpg
), as follows:
Note: Even though we named our zip archive as (shell.jpg), some upload forms may still detect our file as a zip archive through content-type tests and disallow its upload, so this attack has a higher chance of working if the upload of zip archives is allowed.
Once we upload the shell.jpg
archive, we can include it with the zip
wrapper as (zip://shell.jpg
), and then refer to any files within it with #shell.php
(URL encoded). Finally, we can execute commands as we always do with &cmd=id
, as follows:
Phar Upload
Finally, 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:
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:
Once we upload it to the web application, we can simply call it with phar://
:
Note: There is another (obsolete) LFI/uploads attack worth noting, which occurs if file uploads is enabled in the PHP configurations and the
phpinfo()
page is somehow exposed to us. However, this attack is not very common, as it has very specific requirements for it to work (LFI + uploads enabled + old PHP + exposed phpinfo()). If you are interested in knowing more about it, you can refer to This Link.