实例
在反序列化过程中,其功能就类似于创建了一个新的对象(复原一个对象可能更恰当),并赋予其相应的属性值。如果让攻击者操纵任意反序列数据有可控的反序列化点, 那么攻击者就可以实现任意类对象的创建,如果一些类存在一些自动触发的方法(魔术方法),那么就有可能以此为跳板进而攻击系统应用。
挖掘反序列化漏洞的条件是:
1. 代码中有可利用的类,并且类中有__wakeup(),__sleep(),__destruct()这类特殊条件下可以自己调用的魔术方法。
2. unserialize()函数的参数可控。
代码:
<?php class A{ var $test = "demo"; function __destruct(){ @eval($this->test); } } $test = $_POST['test']; $len = strlen($test)+1; $p = "O:1:\"A\":1:{s:4:\"test\";s:".$len.":\"".$test.";\";}"; // 构造序列化对象 $test_unser = unserialize($p); // 反序列化同时触发_destruct函数 ?>
这里可控的反序列化点在$p,来构造序列号的对象,最后反序列化$p回调__destruct()函数,我们注入payload,需要对$test
的值进行覆盖,可以用hackbar来改。
这是控制序列化的点,比如可以直接改$p 在__destruct方法执行eval之前就把变量$test的值替换成payload了。
实例
<?php class test{ var $test = '123'; function __wakeup(){ $fp = fopen("flag.php","w"); fwrite($fp,$this->test); fclose($fp); } } $a = $_GET['id']; print_r($a); echo "</br>"; $a_unser = unserialize($a); require "flag.php"; ?>
这是通过魔术方法__wakeup把test的值写入flag.php中,调用unserialize()反序列化时候会调用__wakeup(),构造payload:
然后再id处注入就可以了,在执行unserialize()方法时会触发__wakeup()方法执行,将传入的字符串反序列化后,会替换掉test类里面$test变量的值,
将php探针写入flag.php文件中,并通过下面的require引用实现代码执行.