PHP反序列化产生函数

作者: 康康 分类: Web安全 发布时间: 2018-03-10 23:56

序列化一下然后反序列化,为什么就能产生漏洞了呢?

这个时候,我们就要了解一下PHP里面的魔术方法了,魔法函数一般是以__开头,通常会因为某些条件而触发不用我们手动调用:

在研究反序列化漏洞的时候,碰见这几个魔法函数就要仔细研究研究了:

__construct()当一个对象创建时被调用

__destruct()当一个对象销毁时被调用

__toString()当一个对象被当作一个字符串使用

__sleep() 在对象在被序列化之前运行

__wakeup将在序列化之后立即被调用

这些就是我们要关注的几个魔术方法了,如果服务器能够接收我们反序列化过的字符串、并且未经过滤的把其中的变量直接放进这些魔术方法里面的话,就容易造成很严重的漏洞了。

举个别人的例子:

<?php
class A{
    var $test = "demo";
    function __destruct(){
            echo $this->test;
    }
}
$a = $_GET['test'];
$a_unser = unserialize($a);
?>

这里我们只要构造payload:

http://127.0.0.1/test.php?test=O:1:”A”:1:{s:4:”test”;s:5:”hello”;}

就能控制echo出的变量,比如你能拿这个来进行反射型xss。。。(听你扯了半天你就给我看这个)

0×04 实例分析

这里实战一题比较简单的ctf题目吧

<?php 
    require_once('shield.php');
    $x = new Shield();
    isset($_GET['class']) && $g = $_GET['class'];
    if (!empty($g)) {
        $x = unserialize($g);
    }
    echo $x->readfile();
?>

可以看见 先是包含了shield.php 然后从中new了个新的实例出来 最后接收用户的反序列化 输出readfile()方法

跟进:

<?php
    //flag is in pctf.php
    class Shield {
        public $file;
        function __construct($filename = '') {
            $this -> file = $filename;
        }
        function readfile() {
            if (!empty($this->file) && stripos($this->file,'..')===FALSE  
            && stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) {
                return @file_get_contents($this->file);
            }
        }
    }
?>

这里我们可以看见只要操控$file这个参数为pctf.php就可以了,这里construct函数在实例被创建的时候(也就是new Shield()的时候)执行,所以不会影响我们对$file的操作

直接构造序列化对象传过去 O:6:”Shield”:1:{s:4:”file”;s:8:”pctf.php”;} 就行了

发表评论

电子邮件地址不会被公开。 必填项已用*标注