详解PHP反序列化漏洞示例与原理

 更新时间:2022年09月02日 11:15:37   作者:icewolf00  
PHP反序列化漏洞也叫PHP对象注入,是一个非常常见的漏洞,这种类型的漏洞虽然有些难以利用,但一旦利用成功就会造成非常危险的后果。本文将详细讲讲PHP反序列化漏洞的原理及示例,感兴趣的可以了解一下

预备知识

PHP序列化与反序列化

序列化:将一个复杂的数据类型(如对象、数组、变量等)转换为字符串表示,以便于在网络中传输和在数据库中存储。在PHP语言中使用serialize()函数实现。

反序列化:将一个序列化的字符串重新转换为一个具体的数据类型。在PHP语言中使用unserialize()函数实现。 PHP对象中只有数据会被序列化,方法不会被序列化。

序列化字符串格式

PHP中经过序列化的字符串格式如下:

类型:类名长度:“类名”:类属性数量:{属性类型:属性长度:“属性内容”}

序列化字符串中的属性命名规则:如果变量为public,则值保持不变;如果变量为private,则在值开头加上类名前缀;如果变量为protected,则在值开头加*符号。

下面给出序列化字符串中的属性类型:

类型解释
s:length:“value”字符串
i:value整数值
d:value浮点数值
b:value布尔值
a:length:{…}数组
O:length:“name”:number:{…}对象
NNULL

PHP魔术方法

简介:魔术方法是一种以2个下划线开头的特殊方法,对一个对象执行魔术方法时会覆盖PHP默认的操作。

常见的PHP魔术方法如下:

方法调用时间
__construct(构造函数)创建新对象时
__destruct (析构函数)销毁对象时
__call在对象中调用不可用方法时
__callStatic在上下文中调用不可用方法时
__get读不可用值时
__set写不可用值时
__isset对不可用值调用isset()empty()
__unset对不可用值调用unset()
__sleep序列化对象时
__wakeup反序列化对象时
__toString对象被作为字符串使用时
__invoke尝试以调用函数方式调用对象时

示例

<?php
    class Test{
        public $a="aaa";
        private $b="bbb";
        protected $c=123;
        function __construct($a,$b,$c)
        {
            $this->a=$a;
            $this->b=$b;
            $this->c=$c;
            echo("Constructor called.<br>");
        }
        function __destruct()
        {
            echo("Destructor called.<br>");
        }
        function show()
        {
            echo($this->a."\n".$this->b."\n".$this->c."<br>");
        }
    }
    $data=new Test("a",1,1.1);
    $data_str=serialize($data);
    echo($data_str."\n");
    $data_new=unserialize($data_str);
    echo("<br>");
    $data_new->show();
?>

反序列化漏洞

反序列化漏洞指网站未对被用户所控制的序列化字符串做检查,攻击者提交了精心构造的有害序列化字符串,导致恶意代码被执行。常见于PHP、Python、Java等允许对象序列化功能的编程语言中。

在PHP中,导致反序列化漏洞的原因大多是魔术方法的不规范使用。(如输出变量内容、写文件操作、写数据库操作等参数用户可控)

构造函数&析构函数

假设网站页面部分代码编写如下:

<?php
    class Test
    {
        var $a="aaa";
        function __construct($a)
        {
            $this->a=$a;
            echo("Info:<br>".$a);
        }
    }
    $data_new=unserialize($_GET['data']);
    var_dump($data_new);
?>

当对象创建(或销毁)时,程序会输出对象中三个成员变量的值;程序还从API接口读取了一个序列化字符串并试图将其反序列化。此时如果将序列化字符串中的值修改为恶意代码,类名修改为Test,会导致反序列化漏洞攻击。

EXP:O:4:“Test”:1:{s:4:“test”;s:29:“<script>alert(‘xss’)</script>”;}

CVE-2016-7124

PHP5 <5.6.25PHP7 <7.0.10的环境中,如果类中存在__wakeup魔术方法,则在反序列化之前会先调用该方法。但当序列化字符串中属性数量大于真实属性数量时,该方法不会执行。

<?php
    class Test
    {
        var $mess="111";
        function __wakeup()
        {
            $this->mess="failed";
            echo("Please try again.<br>");
        }
    }
    $new_data=unserialize($_GET['ins']);
    var_dump($new_data);
?>

代码中,当反序列化一个字符串时,程序会执行__wakeup方法,将$mess设置为字符串,并显示失败信息。此时把序列化字符串中的属性数量值改大,__wakeup方法会失效。

EXP:http://127.0.0.1/serialize.php?ins=O:4:“Test”:2:{s:4:“mess”;s:25:"

<script>alert(1)</script>";}

到此这篇关于详解PHP反序列化漏洞示例与原理的文章就介绍到这了,更多相关PHP反序列化漏洞内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • ThinkPHP5+PhpSpreadsheet实现批量导出数据

    ThinkPHP5+PhpSpreadsheet实现批量导出数据

    由于PHPExcel不再维护,所以建议使用PhpSpreadsheet来导出exlcel,但是PhpSpreadsheet由于是个新的类库,所以只支持PHP7.1及以上的版本,本文给大家介绍了ThinkPHP5+PhpSpreadsheet实现批量导出数据,需要的朋友可以参考下
    2024-10-10
  • PHP实现bitmap位图排序与求交集的方法

    PHP实现bitmap位图排序与求交集的方法

    这篇文章主要介绍了PHP实现bitmap位图排序与求交集的方法,结合实例形式分析了php位图排序及求交集运算的相关实现技巧,需要的朋友可以参考下
    2016-07-07
  • php-redis中的sort排序函数总结

    php-redis中的sort排序函数总结

    这篇文章主要介绍了php-redis中的sort排序函数总结,本文讲解了了按字母排序、排序取部分数据、使用外部key进行排序等排序方法,同时给出代码实例,需要的朋友可以参考下
    2015-07-07
  • php你的验证码安全码?

    php你的验证码安全码?

    php你的验证码安全码?...
    2007-01-01
  • 浅谈php字符串反转 面试中经常遇到

    浅谈php字符串反转 面试中经常遇到

    下面小编就为大家分享一篇浅谈php字符串反转 面试中经常遇到的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • PHP7中对十六进制字符串处理的问题详解

    PHP7中对十六进制字符串处理的问题详解

    在本篇文章里小编给大家整理的是一篇关于PHP7中对十六进制字符串处理的问题详解内容,有需要的朋友们可以跟着学习下。
    2021-11-11
  • PHP检测用户是否关闭浏览器的方法

    PHP检测用户是否关闭浏览器的方法

    这篇文章主要介绍了PHP检测用户是否关闭浏览器的方法,通过connection_status获取连接状态实现针对浏览器关闭的判定功能,需要的朋友可以参考下
    2016-02-02
  • php-fpm reload 会取消正在处理请求的解决方案

    php-fpm reload 会取消正在处理请求的解决方案

    这篇文章主要介绍了php-fpm reload 会取消正在处理请求的解决方案,文章通过围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • php读取远程gzip压缩网页的方法

    php读取远程gzip压缩网页的方法

    这篇文章主要介绍了php读取远程gzip压缩网页的方法,当站点使用gzip压缩时,使用常规的远程获取方法会得到乱码结果,使用本文方法即可解决这个问题,需要的朋友可以参考下
    2014-12-12
  • 解析PHP中的file_get_contents获取远程页面乱码的问题

    解析PHP中的file_get_contents获取远程页面乱码的问题

    本篇文章是对PHP中的file_get_contents获取远程页面出现乱码的问题进行了详细的分析介绍,需要的朋友参考下
    2013-06-06

最新评论