PHP serialize && unserialize Security Risk Research(undone)

目录

1. 序列化的定义
2. serialize:序列化
3. unserialize:反序列化
4. 序列化、反序列化存在的安全风险

 

1. 序列化的定义

序列化在计算机科学中通常有以下定义:

1. 对同步控制而言,表示强制在同一时间内进行单一存取 
2. 在数据储存与传送的部分是指将一个对象存储至一个储存媒介,例如档案或是记亿体缓冲等,或者透过网络传送资料时进行编码的过程,可以是字节或是XML等格式。而字节的或XML编码格式可以还原完全相等的对象。这程序被应用在不同应用程序之间传送对象,以及服务器将对象储存到档案或数据库。相反的过程又称为反序列化 

序列化有多个优点 

1. 一个简单和持久的方法使对象持续
2. 一个发起远程过程调用的方法,例如在SOAP内的 
3. 一个分发对象的方法,尤其是在如COM及CORBA的软件组件化内

Relevant Link:

http://zh.wikipedia.org/wiki/%E5%BA%8F%E5%88%97%E5%8C%96
http://baike.baidu.com/view/160029.htm

 

2. serialize:序列化

serialize: 产生一个可存储的值的表示
serialize() 返回字符串,此字符串包含了表示 value 的字节流,可以存储于任何地方。这有利于存储或传递 PHP 的值,同时不丢失其类型和结构
serialize() 可处理除了 resource 之外的任何类型,包括

1. 指向其自身引用的数组
2. serialize() 的数组/对象中的引用也将被存储(引用本身也会被序列化)
3. ...

从本质上来讲,序列化的过程是一个"对象(广义上的对象,包括integer、float、string、array、object)"进行"对象销毁",然后转换为一个通用的中间可存储字符串,在整个序列化过程中,对象经历的声明周期如下

1. __sleep(): 在执行对象销毁前获得执行权限
2. __destruct():执行实际的对象销毁操作

code

<?php
    class Connection 
    {
        var $protected_var;
        var $private_var;
        
        public function __construct($server, $username, $password, $db)
        {
            echo "function __construct() is called" . "</br>";
            $this->protected_var = "protected_var";
            $this->private_var = "private_var";
        }
        
        function __destruct() 
        {
            echo "function __destruct() is called" . "</br>";
           }
        
        public function __sleep()
        {
            echo "function __sleep() is called" . "</br>";
        }
        
        public function __wakeup()
        {
            echo "function __wakeup() is called" . "</br>";
        }
    }

    //initialize a var
    $obj = new Connection();

    //var_dump($obj);

    $result = serialize($obj);

    //var_dump($result);

    unserialize($result);
?>

Relevant Link:

http://php.net/manual/zh/function.serialize.php
http://php.net/manual/zh/language.oop5.magic.php#object.wakeup
http://php.net/manual/zh/language.oop5.decon.php

 

3. unserialize:反序列化

从已存储的表示中创建 PHP 的值
unserialize() 对单一的已序列化的变量进行操作,将其转换回 PHP 的值

在反序列化中,经历的对象声明周期为

1. __construct():执行对象注册、包括对象中成员的注册
2. __wakeup:在构造函数执行后获得执行权限

Relevant Link:

http://php.net/manual/zh/function.unserialize.php

 

4. 序列化、反序列化存在的安全风险

0x1: 对象注入

<?php
    #GOAL: get the secret;
     
    class just4fun 
    {
        var $enter;
        var $secret;
    }
     
    if (isset($_GET[pass])) 
    {
        $pass = $_GET[pass];
     
        if(get_magic_quotes_gpc())
        {
        $pass=stripslashes($pass);
        }
     
        $o = unserialize($pass);
     
        if ($o) 
        {
        $o->secret = "?????????????????????????????";
        if ($o->secret === $o->enter)
            echo "Congratulation! Here is my secret: ".$o->secret;
        else
            echo "Oh no... You can‘t fool me";
        }
        else echo "are you trolling?";
    }
?>

serialize一个just4fun的对象,序列化之前先进行引用赋值

$o->enter = &$o->secret

0x2: PHP Session 序列化及反序列化处理器

http://drops.wooyun.org/tips/3909

0x3: 基于序列化、反序列化的Webshell隐藏技巧

http://www.cnblogs.com/LittleHann/p/3522990.html
搜索:0x22: PHP的序列化、反序列化特性布置后门 

Relevant Link:

http://drops.wooyun.org/papers/660

 

Copyright (c) 2014 LittleHann All rights reserved

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。