• 不安全的反序列化


    绪论

    为什么要序列化?

    序列化,“将对象的状态信息转换为可以存储或传输的形式的过程”,这种形式⼤多为字节流、字符串、json 串。在序列化期间内,将对象当前状态写⼊到临时或永久性的存储区。以后,就可以通过从存储区中读取或还原(反序列化)对象的状态,重新创建该对象。简单的说,序列化就是把一个对象变成可以传输的字符串,可以以特定的格式在进程之间跨平台安全的进⾏通信。

    1.序列化与反序列化

    1.1 引例

    JSON 数据是数据的一种表达形式,与Python ⾥的字典类似。

    // json.php
    
    $stu = array(
    'name'   => 'cgjil', 'age'	=> 18,
    'sex'	=> true, 'score' => 89.9
    );
    
    // echo $stu;
    // var_dump($stu);
    
    $stu_json = json_encode($stu); echo $stu_json;
    
    echo "
    "
    ; $stu_json = isset($_GET['stu'])?$_GET['stu']:$stu_json; $stu = json_decode($stu_json); var_dump($stu);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    验证:

    ?stu={"name":"cgjil","age":19,"sex":true,"score":89.9}
    
    • 1
    1.2 序列化实例
    1.2.1 定义一个类
    //   stu.class.php
    
    class Stu{
    public $name; public $age; public $sex; public $score;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1.2.2 创建对象

    创建一个对象,并对该对象进⾏序列化操作,将对象转化为可以存储、传输的字符串

    // serialize.php
    include   "./stu.class.php";
    $stu1 = new Stu();
    $stu1 -> name	= "cgjil";		//$stu1.name
    $stu1 -> age	= 24;
    $stu1 -> sex	= true;
    $stu1 -> score   = 99.9;
    
    // echo $stu1;
    // var_dump($stu1);
    
    $_stu1 = serialize($stu1); echo $_stu1;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    序列化后的字符串:

    O:3:"Stu":4:{s:4:"name";s:5:"cgjil";s:3:"age";i:24;s:3:"sex";b:1;s:5:"score";d:99.900000000000006;}
    
    • 1
    1.2.3 反序列化

    将字符串转化为对象。

    //   unserialize.php
    
    include "./stu.class.php";
    
    $stu1_ser = 'O:3:"Stu":4: {s:4:"name";s:5:"cgjil";s:3:"age";i:24;s:3:"sex";b:1;s:5:"score";d:99.900000000000006;}';
    
    $stu1_obj = unserialize($stu1_ser); var_dump($stu1_obj);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1.2.4 对象注⼊

    如果反序列化字符串,Web ⽤⼾可以控制,则造成对象注⼊。

    // $stu1_seria = 'O:3:"Stu":4: {s:4:"name";s:5:"cgjil";s:3:"age";i:24;s:3:"sex";b:1;s:5:"score";d:99.900000000000006;}';
    $stu1_ser = $_GET['obj'];
    
    
    • 1
    • 2
    • 3

    PHP 的反序列化漏洞也叫PHP 对象注⼊,是一个⾮常常⻅的漏洞,这种漏洞在某些场景下虽然有些难以利⽤,但是一旦利⽤成功就会造成⾮常危险的后果。

    2.漏洞何在

    2.1 漏洞触发
    2.1.1 有一个类
    //  vul.class.php
    
    class Vul{
    public $str = "cgjil";
    function __destruct(){
    
    //echo "This is function __destruct()"; @eval($this -> str);
    
    }
    
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    2.1.2 有一个对象
    // test.php
    
    include './vul.class.php';
    $s = new Vul(); echo serialize($s); echo "
    "
    ; $_s = isset($_GET['s_ser'])?$_GET['s_ser']:'O:3:"Vul":1:{s:3:"str";s:5:"cgjil";}'; $s = unserialize($_s); var_dump($s);
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    序列化后:

    O:3:"Vul":1:{s:3:"str";s:5:"cgjil";}
    
    • 1
    2.1.3 反序列化执⾏代码
    ?obj=O:3:"Vul":1:{s:3:"str";s:10:"phpinfo();";}
    
    • 1
    2.2 为什么会这样

    __destruct(),会被对象⾃动调⽤。

    以 __ 开头的函数,是PHP 中的魔术⽅法。类中的魔术⽅法,在特定情况下会⾃动调⽤。即使魔术⽅法在类中没有被定义,也是真实存在的。

    魔术⽅法触发条件
    __construct()在创建对象时⾃动调⽤,构造函数
    __destruct()在销毁对象时⾃动调⽤,析构函数
    __call(); 
    __callStatic();
    __get();
    __set();
    __isset();
    __unset();
    __sleep(); 
    __wakeup(); 
    __toString();
    __invoke(); 
    __set_state();
    __clone(); 
    __debuginfo();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    漏洞形成的根本原因就是程序没有对⽤⼾输⼊的反序列化字符串进⾏检测,导致反序列化过程可以被恶意控制,进而造成代码执⾏、GetShell 等一系列不可控的后果。反序列化漏洞并不是PHP 特有的,也存在于Java、Python 语⾔中,其原理基本相同。

    3.反序列化漏洞攻防

    3.1 PHP 反序列化实例

    typecho 反序列化漏洞

    **3.2 Java 反序列化实例

    Weblogic < 10.3.6 ‘wls-wsat’ XMLDecoder 反序列化漏洞

    S2-045 Remote Code Execution Vulnerablity

    JBoss 5.x/6.x 反序列化漏洞

    fastjson 1.2.24 反序列化导致任意命令执⾏漏洞

    Fastjson 1.2.47 远程命令执⾏漏洞

    Apache Shiro 1.2.4反序列化漏洞(CVE-2016-4437)

    3.3 反序列化漏洞防御

    升级组件到最新版本

    ⿊⽩名单过滤敏感字符禁⽤反序列化功能

    部署安全设备

  • 相关阅读:
    LeetCode 面试题 08.02. 迷路的机器人
    SpringBoot整合篇 04、Springboot整合Redis
    2022年Redis最新面试题 - Redis运维和部署
    rv1126-rv1109-sfc-分区表获取流程分析
    STM32Cube学习(2)——定时器中断
    mysql基本操作增删改查
    【大模型应用极简开发入门(2)】GPT模型简史:从GPT-1到GPT-4:从小数据量的微调到大数据量的强化学习不断优化模型
    【Docker】Docker持续集成与持续部署(四)
    【AtomicReference、AtomicStampedReference】常规用法
    2022 极术通讯-搭载安谋科技“星辰”STAR-MC1处理器的上海航芯ACM32磁链观测器算法方案
  • 原文地址:https://blog.csdn.net/cgjil/article/details/132776975