php 反序列化漏洞总结

  • serialize 把一个对象转成字符串形式, 可以用于保存
  • unserialize 把serialize序列化后的字符串变成一个对象

php魔法函数

__construct()当一个对象创建时被调用

__destruct()当一个对象销毁时被调用

__toString()当一个对象被当作一个字符串使用

__sleep() 在对象在被序列化之前运行

__wakeup将在序列化之后立即被调用

等方法在 PHP 中被称为”魔术方法”,详情见http://php.net/manual/zh/language.oop5.magic.php

漏洞成因

如果服务器能够接收我们反序列化过的字符串、并且未经过滤的把其中的变量直接放进这些魔术方法里面的话,那么反序列化过来的对象通过自动调用魔法就容易造成很严重的漏洞了。

举个别人的例子:

 

http://127.0.0.1/hh.php?test=O:1:”A”:1:{s:4:”test”;s:30:”<script>alert(‘1234’)</script>”;}

构造以上payload,甚至可以反射xss

CTF题型

题型1:将传来的序列化数据直接unserilize,造成魔幻函数的执行或者直接执行。

例题:  jarvis oj 神盾局的秘密

原题链接 http://web.jarvisoj.com:32768/

打开链接,是一张图片,查看源代码

<img src=”showimg.php?img=c2hpZWxkLmpwZw==” width=”100%“/>

将c2hpZWxkLmpwZw== base64解码后得shield.jpg,将showimg.php,index.php,以及发现的shield.php base64编码后输入读出源码。

 

从代码可以看出flag应该就在pctf.php中,而且pctf.php是无法直接读出来的。

从index.php和shield.php中可以看到,我们可以构造序列化字符串,反序列化时,调用echo $x->readfile();就可以将pctf.php中内容打印出来。所以我们可以在本地构建。

访问http://web.jarvisoj.com:32768/?class=O:6:”Shield”:1:{s:4:”file”;s:8:”pctf.php”;}即可。

题型2:PHP Session 序列化及反序列化处理器设置使用不当会带来的安全隐患。

原因是未正确处理\’|\’,如果以php_serilize方式存入,比如我们构造出”|” 伪造的序列化值存入,但之后解析又是用的php处理器的话,那么将会反序列化伪造的数据(\’|\’之前当作键名,\’|\’之后当作键值。

所以,如果在一个页面中,如果php.ini中设置的session序列化处理器为php_serilize,而当前页面设置为php。那么我们只要将序列化字符串注入到session中,那么反序列化出来的对象,就会执行。

例题: jarvis oj PHPINFO

题目链接:http://web.jarvisoj.com:32784/

从以上代码中可以清楚得看到, __destruct()魔法函数中有eval()函数,大概率就是漏洞所在之处。再看到ini_set('session.serialize_handler', 'php'); 将本页面session反序列化处理器设置为php,在url后输入?phpinfo=123,可以查看到phpinfo,搜索可以发现php.ini 中为默认的php_serialize.

那么现在的问题就在于怎么把我们需要的反序列化数据注入到session中,由phpinfo()页面知,session.upload_progress.enabled为On。当一个上传在处理中,同时POST一个与INI中设置的session.upload_progress.name同名变量时,当PHP检测到这种POST请求时,它会在$_SESSION中添加一组数据。所以可以通过Session Upload Progress来设置session。

将以上代码保存本地运行,首先随便上传一个文件,burp抓包。

再来考虑序列化的问题,将以下代码本地保存运行,得到序列化结果:

为防止转义,在所有引号前加上\。

从phpinfo可知当前目录:

再构造序列化字符串:

可得flag:

 

 

参考:https://chybeta.github.io/2017/07/05/jarvisoj-web-writeup/#PHPINFO

            http://www.91ri.org/15925.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注