php浅析反序列化结构

作者:哇咔哇咔哇咔哇咔 时间:2023-11-17 17:34:37 

简介

序列化的目的是方便数据的传输和存储,在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:&ldquo;test&rdquo;:2:{s:4:&ldquo;%00*%00a&rdquo;;s:3:&ldquo;abc&rdquo;;s:7:&ldquo;%00test%00b&rdquo;;s:3:&ldquo;def&rdquo;;}

可以写成

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

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

来源:https://blog.csdn.net/qq_63267612/article/details/125961096

标签:php,反序列化,序列化
0
投稿

猜你喜欢

  • 浅谈Python中os模块及shutil模块的常规操作

    2022-05-02 21:42:50
  • SpringSecurity框架简介及与shiro特点对比

    2023-01-03 13:56:25
  • vue el-upload上传文件的示例代码

    2024-05-11 09:13:47
  • 对Python中一维向量和一维向量转置相乘的方法详解

    2022-01-24 12:44:14
  • JavaScript正则表达式之multiline属性的应用

    2024-05-11 10:24:56
  • js实现简单放大镜特效

    2024-04-30 08:51:48
  • python3实现字符串的全排列的方法(无重复字符)

    2022-04-14 19:47:56
  • FrontPage2003 中网页布局功能的应用

    2007-11-18 14:43:00
  • SQL Server 交叉表查询 case

    2024-01-18 19:05:48
  • SQL 2008邮件故障排除:发送测试电子邮件

    2008-12-02 14:28:00
  • HTML5设计原则

    2012-04-26 16:46:45
  • python requests证书问题解决

    2023-10-12 22:58:12
  • python如何求解两数的最大公约数

    2021-01-16 07:38:18
  • Python基础之高级变量类型实例详解

    2021-11-09 11:07:40
  • Mysql中复制详细解析

    2024-01-13 20:46:25
  • python3 图片 4通道转成3通道 1通道转成3通道 图片压缩实例

    2021-04-01 05:54:41
  • Python利用prettytable实现格式化输出内容

    2023-10-17 11:02:32
  • python求斐波那契数列示例分享

    2022-07-20 19:32:10
  • 利用Python实现自动生成数据日报

    2022-08-26 11:12:48
  • Python实现定制自动化业务流量报表周报功能【XlsxWriter模块】

    2022-02-12 01:25:05
  • asp之家 网络编程 m.aspxhome.com