文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

php浅析反序列化结构

2024-04-02 19:55

关注

简介

序列化的目的是方便数据的传输和存储,在PHP中,序列化和反序列化一般用做缓存,比如session缓存,cookie等。

反序列化中常见的魔术方法

  1. __wakeup() //执行unserialize()时,先会调用这个函数
  2. __sleep() //执行serialize()时,先会调用这个函数
  3. __destruct() //对象被销毁时触发
  4. __call() //在对象上下文中调用不可访问的方法时触发
  5. __callStatic() //在静态上下文中调用不可访问的方法时触发
  6. __get() //用于从不可访问的属性读取数据或者不存在这个键都会调用此方法
  7. __set() //用于将数据写入不可访问的属性
  8. __isset() //在不可访问的属性上调用isset()或empty()触发
  9. __unset() //在不可访问的属性上使用unset()时触发
  10. __toString() //把类当作字符串使用时触发
  11. __invoke() //当尝试将对象调用为函数时触发

反序列化绕过小Trick

php7.1+反序列化对类属性不敏感

我们前面说了如果变量前是protected,序列化结果会在变量名前加上\x00*\x00

但在特定版本7.1以上则对于类属性不敏感,比如下面的例子即使没有\x00*\x00也依然会输出abc

<?php
class test{
    protected $a;
    public function __construct(){
        $this->a = 'abc';
    }
    public function  __destruct(){
        echo $this->a;
    }
}
unserialize('O:4:"test":1:{s:1:"a";s:3:"abc";}');

绕过_wakeup(CVE-2016-7124)

版本:

​ PHP5 < 5.6.25

​ PHP7 < 7.0.10

利用方式:序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行

对于下面这样一个自定义类

<?php
class test{
    public $a;
    public function __construct(){
        $this->a = 'abc';
    }
    public function __wakeup(){
        $this->a='666';
    }
    public function  __destruct(){
        echo $this->a;
    }
}

如果执行unserialize('O:4:"test":1:{s:1:"a";s:3:"abc";}');输出结果为666

而把对象属性个数的值增大执行unserialize('O:4:"test":2:{s:1:"a";s:3:"abc";}');输出结果为abc

绕过部分正则

preg_match('/^O:\d+/')匹配序列化字符串是否是对象字符串开头,这在曾经的CTF中也出过类似的考点

利用加号绕过(注意在url里传参时+要编码为%2B)

serialize(array(a ) ) ; / / a));//a));//a为要反序列化的对象(序列化结果开头是a,不影响作为数组元素的$a的析构)

<?php
class test{
    public $a;
    public function __construct(){
        $this->a = 'abc';
    }
    public function  __destruct(){
        echo $this->a.PHP_EOL;
    }
}
function match($data){
    if (preg_match('/^O:\d+/',$data)){
        die('you lose!');
    }else{
        return $data;
    }
}
$a = 'O:4:"test":1:{s:1:"a";s:3:"abc";}';
// +号绕过
$b = str_replace('O:4','O:+4', $a);
unserialize(match($b));
// serialize(array($a));
unserialize('a:1:{i:0;O:4:"test":1:{s:1:"a";s:3:"abc";}}');

利用引用

<?php
class test{
    public $a;
    public $b;
    public function __construct(){
        $this->a = 'abc';
        $this->b= &$this->a;
    }
    public function  __destruct(){

        if($this->a===$this->b){
            echo 666;
        }
    }
}
$a = serialize(new test());

上面这个例子将$b设置为$a的引用,可以使$a永远与$b相等

16进制绕过字符的过滤

O:4:“test”:2:{s:4:“%00*%00a”;s:3:“abc”;s:7:“%00test%00b”;s:3:“def”;}

可以写成

O:4:“test”:2:{S:4:“\00*\00\61”;s:3:“abc”;s:7:“%00test%00b”;s:3:“def”;}

表示字符类型的s大写时,会被当成16进制解析。

到此这篇关于php浅析反序列化结构的文章就介绍到这了,更多相关php反序列化内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯