利用 __toString
这么简单,反序列化漏洞就讲完了吗,no no no,平常经常看别的文章经常看到POP链这个名词,那到底是神马?
POP gadget
如果一次unserialize()中并不会直接调用的魔术函数,比如前面提到的 __construct()
,是不是就没有利用价值呢?
非也,类似于栈溢出中的ROP gadget,有时候反序列化一个对象时,由它调用的 __wakeup()
中又去调用了其他的对象,由此可以溯源而上,利用一次次的”gadget”找到漏洞点。
实验如下:
<?php
class test1{
function __construct($test){
$fp = fopen("flag.php","w") ;
fwrite($fp,$test);
fclose($fp);
}
}
class test2{
var $test = '123';
function __wakeup(){
$obj = new test1($this->test);
}
}
$a = $_GET['id'];
print_r($a);
echo "</br>";
$a_unser = unserialize($a);
require "flag.php";
?>
分析以上代码,我们可以给id传入构造好的序列化字符串,进行反序列化时会自动调用 test2
中的 __wakeup
方法,从而在 newtest1($this->test)
时会调用 test1
中的 __construct()
方法,从而把 把 <?php phpinfo();?>
写入到 flag.php中,达到上面一样的效果。
细心的朋友可能已经发现了,以上我们都是利用魔术方法这种自动调用的方法来利用反序列化漏洞的,如果缺陷代码存在类的普通方法中,就不能指望通过”自动调用”来达到目的了。
利用普通方法
当我们能利用的只有类中的普通方法时,这时我们需要寻找相同的函数名,把敏感函数和类联系在一起。
如下实验:
<?php
class main {
var $test;
function __construct() {
$this->test = new test1();
}
function __destruct() {
$this->test->action();
}
}
class test1 {
function action() {
echo "hello world";
}
}
class test2 {
var $test2;
function action() {
eval($this->test2);
}
}
$a = new main();
unserialize($_GET['test']);
?>
暂无评论内容