Abusing PHP Wrappers

Intro:

As per standard PHP manual the description is as below.

PHP provides a number of miscellaneous I/O streams that allow access to PHP’s own input and output streams, the standard input, output and error file descriptors, in-memory and disk-backed temporary file streams, and filters that can manipulate other file resources as they are read from and written to.

Let’s see in our own terminology it is as simple as “Code that surrounds other Code

It is fundamentally ~any~ code that encloses or utilizes some other piece of code. It is not something specific. A “wrapper” is not like a “function”, “class”, “variable”, “array”, etc… it isn’t anything specific — it is terminology (like the term “polymorphism”, it basically describes something).

Easy right…!!

Here is an example how it really looks like.

Suppose you had two functions… “getWhales” and “getAnimal”. And you had code like:

function getWhales()
{
return getAnimal('whales');
}

This is a simple demonstration. You could say: “getWhales() is a wrapper of getAnimal()”.

PHP wrappers can write functions such as file_get_contents, fopen, include, system, exec and require etc. Using these functions we can include files from our own server or remote.

file://         Accessing local file system
http://         Accessing HTTP(s) URLs
ftp://          Accessing FTP(s) URLs
php://          Accessing various I?O streams
zlib://         Compression streams
data://         Data
glob://         Find path names and matching patterns
phar://         PHP Archive
ssh2://         Secure shell 2
rar://          RAR
ogg://          Audio streams
expect://       Process interaction streams etc.

You can find more at PHP Protocols/Wrappers.

How to Use:

Let’s have developer point of view which actually help us to understand the concept in depth to see how exactly they implement it in most of the applications.

<?php 
if (isset($_POST['pass'])) 
{ 
include ($_POST['pass']); 
}
else 
{
echo 'error';
}
?>

A simple functionality described above will look for page attribute. Once if page parameter value is passed as input to the application it will make use of php wrapper mentioned above and it will fetch the other piece of code.

The following demo application will make that very clear.

Once you click on Account Settings page it will call “pass.php” another piece of code. We can see below the actual request.

This is how applications make use of other piece of code from either same or different application on server. Basically we can say it very similar to the concept of inheritance.

How to Abuse:

Our main goal is to do something that is differ than the developer’s intention. We need to think about why only “pass.php” why not it will be an /etc/passwd or some other file on same or remote server (LFI/RFI) which can make us so happy.

Our simple and favorite encoding schema – Base64 and our payload is like

data://text/plain;base64,PD89aHRtbGVudGl0aWVzKHNoZWxsX2V4ZWMoJ2NhdCBkYi5waHAnKSk7Pz4=

which is normally <?=htmlentities(shell_exec(‘cat db.php’));?>

Finally here is the beauty 🙂

Looks so simple right.

Why only LFI/RFI. Can we elevate this to a critical RCE..??

Answer is yes. A fellow bug bounty hunter @smiegles thought the same and here is the complete writeup from LFI to RCE takeover – Upgrade from LFI to RCE.

What else ..??

Hmmm. In some cases we can see Server Side Request Forgery issues via wrapper techniques. We can see a clear Proof of Concept here. ESEA SSRF

How to Protect ..??

  • Trust No One – Remember this and sanitize everything that comes from front end users.
  • Defense in Depth – Implementation of proper access controls for wrappers will mitigate the issue.

Reference :

Null4DM!N

Security Researcher and Exploit writer.

More Posts - Website

Leave A Comment

Your email address will not be published. Required fields are marked *