反序列化无论在CTF比赛中,抑或是实战渗透中都起着重要作用,而这一直都是我的弱项之一,所以写一篇反序列化利用总结来深入学习一下
!--more--
简单介绍
(反)序列化只是给我们传递对象提供了一种简单的方法。
serialize()将一个对象转换成一个字符串
unserialize()将字符串还原为一个对象
在本质上,反序列化的数据是没有危害的,但是当反序列化数据是用户可控时,这时就会产生一些预期外的结果,也就可能存在危害
因此,反序列化的危害,关键在于可控或不可控,而我们找反序列化漏洞时,数据的可控与不可控也是一处着力点
在本文,不会着重讨论反序列化漏洞的形成原理,这已经被其他师傅讲得很透彻了,我在这里只是稍微总结一下思路,仅此而已
漏洞成因即利用思路
才疏学浅,若有错误,多加包涵
Magicfunction
Magicfunction,即我们常说的魔术方法,我们的反序列化漏洞也常常与这些相挂钩
__construct():构造函数,当对象创建(new)时会自动调用。但在unserialize()时是不会自动调用的。
__destruct():析构函数,类似于C++。会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行,当对象被销毁时会自动调用。
__wakeup():如前所提,unserialize()时会检查是否存在__wakeup(),如果存在,则会优先调用__wakeup()方法。
__toString():用于处理一个类被当成字符串时应怎样回应,因此当一个对象被当作一个字符串时就会调用。
__sleep():用于提交未提交的数据,或类似的清理操作,因此当一个对象被序列化的时候被调用。
利用方式
__wakeup()
对应的CVE编号:CVE--
存在的php版本:PHP5.6.25之前版本和7.0.10之前的7.x版本
漏洞成因:当对象的属性(变量)数大于实际的个数时,__wakeup可以被被绕过
demo
?phphighlight_file(__FILE__);error_reporting(0);classconvent{var$warn="Nohacker.";function__destruct(){eval($this-warn);}function__wakeup(){foreach(get_object_vars($this)as$k=$v){$this-$k=null;}}}$cmd=$_POST[cmd];unserialize($cmd);?
这边的__wakeup是事件型的,如果没遇到unserialize就永远不会触发了,所以我们得先搞清楚先执行哪个方法,再执行哪个方法。
在这里,经过测试,我们可以得出__wakeup优先级高于__destruct()
因为遇到了unserialize得先执行__wakeup里面的内容,才能跑到我们想要的__destruct()里面,所以得绕过这个__wakeup
怎么绕过?
只要对象的属性(变量)数大于实际的个数时,__wakeup就可以被被绕过
?phpclassconvent{var$warn="phpinfo();";function__destruct(){}}$a=newconvent();$b=serialize($a);print_r($b);//O:7:"convent":1:{s:4:"warn";s:10:"phpinfo();";}?
然后更改变量数即可
O:7:"convent":1:{s:4:"warn";s:10:"phpinfo();";}O:7:"convent":2:{s:4:"warn";s:10:"phpinfo();";}
存在多个魔法方法时,要弄清哪个魔法方法的优先级高
PHPsession反序列化
这在我之前一篇文章其实已经介绍得差不多了
漏洞成因:其主要原理就是利用序列化的引擎和反序列化的引擎不一致时,引擎之间的差异产生序列化注入漏洞
demo
在之前的高校战疫中考查过,利用的就是phpsession的序列化机制差异导致的注入漏洞
相关题目: