PHP 反序列化

序列化与反序列化漏洞

承接上面的例子,可以有一个这样的猜测,如果我们将序列化的字符串按格式要求随意更改,是不是可以控制intro()方法的打印信息?答案是肯定的。事实上,序列化与反序列化漏洞也正是由此而来。(简单提一下)

假设有这样一个环境:

存在url:

127.0.0.1/ser.php

其对应的后台代码如下:

<?php
    class person {
        public $name="echo 'I am isee'";

        public function __wakeup(){
            eval ("$this->name;");
        }
    }


    if (isset($_GET['mid'])){
        $mid=$_GET['mid'];
        unserialize("$mid");
    }

    else{
        echo "<h1>hello!!!<h1/>";
    }
//如果传递参数把参数进行反序列化,然后代码执行
//如果没有,直接打印hello!!!


如果带上?mid参数服务器后端对应的PHP代码将会反序列化这个用户传参,此时如果我们在本地正常序列化这个**person类并拼接到?mid的结果是这样的

本地正常序列化**person类

<?php
class person
{
    public $name = "echo 'I am isee'";

    public function __wakeup()
    {
        eval ("$this->name;");
    }
}
$person1=new person();
$mid=serialize($person1);
var_dump($mid);
//序列化后的字符串
//O:6:"person":1:{s:4:"name";s:16:"echo 'I am isee'";}

url拼接mid参数后访问服务器:

可以清楚的看到,传递序列化后的字符串成功的被后台的unserialize()还原成了原本的person类,从而触发了__wakeup魔术方法,最终eval()成功的将$name的值 echo 'I am isee'将PHP代码解析,输出了I am isee字样

如果我们自定义这个序列化后的特殊字符串,会怎样?

可以看到,ping命令被成功的执行,这也说明,其他的任意命令也可以执行了。

因此,简单小结一下PHP序列化与反序列化漏洞的成因:

序列化的字符串可以保存类的基本信息,反序列化的过程可以将这个特殊的字符串重新还原成类,虽然在整个序列化与反序列化的过程中我们无法控制类方法的改变(这个主要指后台的自定义函数),但是我们却可以通过复写变量并借用类中自定义好的方法(服务器上的)或魔术方法(服务器存在的或本地自定义的),并借用敏感函数来达到恶意效果。

关键点就在于PHP序列化与反序列化的过程用户可控。

常见需要注意的魔术方法

本次讨论如下几个魔术方法:

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


 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值