phar反序列化
参考资料
https://blog.csdn.net/q20010619/article/details/120833148
https://xz.aliyun.com/t/3692#toc-4
https://zhuanlan.zhihu.com/p/285187017
这是一篇从零开始的Phar学习笔记。
Phar基础
phar简介
phar全程【PHP Archive】,是PHP里一种类似于JAR的打包文件。与JAR最大的不同是,由于PHP是不编译的,Phar包实际上只是将代码原样的进行打包。
有了phar,我们就可以更好的将PHP项目做成Java项目那样的目录形式。不过,感觉在真实环境中,Phar包很少得到使用。
事实上,我刚开始是准备写一个Phar示例的,我准备把【buuoj_ciscn2019_dropbox】的php源码本身压成phar包。但是在操作的时候,我发现【Header("Location:xxx")】失效了,且我改不好(或许就是不支持)。查阅一些资料之后,发现Phar在用于封装一些内部公用库函数时效果还不错。那就不搞了。
phar结构
一个phar文件分为四部分:
1、stub
用于使PHP的phar扩展能够识别phar文件;必须以__HALT_COMPILER();
来结尾。
2、a manifest describing the contents
先是用户自定义的meta-data;然后是每个后面每个文件的权限和属性等信息。
3、the file contents
被压缩文件的内容
4、signature
签名,放在末尾,用于确认phar文件完整性。
下面一组图给出了一个实例phar文件以及其四部分的具体区分。这个phar文件stub是自定义的,想伪造成GIF;meta-data有个自己加的“jiliguala“;共打包进去两个文件,分别是【shell.txt】和【second.txt】,内容在haha后面分界。第三张图后面未被选中的内容就是签名,一般是PHP自己生成的。
其对应了这段生成代码。
php.ini设置phar.readonly=Off,否则Phar文件就无法生成。
$phar = new Phar("shell.phar"); //生成一个phar文件,文件名为shell.phar
$phar-> startBuffering();
$phar->setStub("GIF89a<?php __HALT_COMPILER();?>"); //设置stub
$phar->setMetadata($user); //将对象user写入到metadata中
#$phar->setMetadata("jiliguala");
$phar->addFromString("shell.txt","haha"); //添加压缩文件,文件名字为shell.txt,内容为haha
$phar->addFromString("second.txt","this_is_the_content_in_the_second_file");
$phar->stopBuffering();
?>
Phar_CTF
讲了这么多,其实Phar在CTF里的利用反倒比较简单。
(1)Phar文件中的meta-data字段是以序列化形式存储的,也就是说,在执行setMetadata()
时隐含的执行了一次serialize()
。
(2)更重要的是,在很多系统函数通过phar://
伪协议解析文件时,会将meta-data反序列化,等于隐式执行了一次unserialize()
当我们发现有参数可控的这些函数,并有文件上传功能时,就应该第一时间想到Phar反序列化攻击。
至于payload构造,Phar部分几乎是固定的(上述生成代码的内容),变化的是序列化链。这就不是此处要讲的内容了。
例题推荐:
1、BUUweb---->CISCN专题---->Dropbox