php反序列化(复习)(第一章)

因为最近在学java,学完基础知识想从Java的反序列化继续学习,借着这个机会来复习一下php的反序列化

一、序列化基础知识

1、序列化的定义

序列化(串行化):是将变量转换为可保存或传输的字符串的过程; 反序列化(反串行化):就是在适当的时候把这个字符串再转化成原来的变量使用; 这两个过程结合起来,可以轻松地存储和传输数据,使程序更具维护性; 常见的php序列化和反序列化方式主要有:serialize,unserialize

2、表达方式

复制代码
<?php
  class Person
  {                                                                      
  public $name;        
public $age;        
public $sex;        

public function __construct($name="张三", $sex="男", $age=22)
  {      
    $this->name = $name;
    $this->sex = $sex;
    $this->age = $age;
  }
public function say()
  { 
    echo "我叫:" . $this->name . ",性别:" . $this->sex . ",年龄:" . $this->age;
  }                                                                                
}
$Person1 = new Person();
echo serialize(($Person1));

回显为

复制代码
O:6:"Person":3:{s:4:"name";s:6:"张三";s:3:"age";i:22;s:3:"sex";s:3:"男";}
O代表object
6代表对象名长度
Person代表对象名称
3代表对象中的变量个数
s和i等代表变量数据类型
s代表 string
i代表 int
变量是int型时,没有长度,不加引号
4代表变量名长度
name代表变量名

3.public、protected、private下序列化对象的区别

复制代码
php v7.x反序列化的时候对访问类别不敏感
public变量
直接变量名反序列化出来
protected变量
\x00 + * + \x00 + 变量名
可以用S:5:"\00*\00op"来代替s:5:"?*?op"
private变量
\x00 + 类名 + \x00 + 变量名

反序列化中s和S的区别

如果类型是s,会调用以下函数,简单来说就是将\解释成十六进制,来转成字符

复制代码
static zend_string *unserialize_str(const unsigned char **p, size_t len, size_t maxlen)
{
	size_t i, j;
	zend_string *str = zend_string_safe_alloc(1, len, 0, 0);
	unsigned char *end = *(unsigned char **)p+maxlen;

	if (end < *p) {
		zend_string_efree(str);
		return NULL;
	}

	for (i = 0; i < len; i++) {
		if (*p >= end) {
			zend_string_efree(str);
			return NULL;
		}
		if (**p != '\\') {
			ZSTR_VAL(str)[i] = (char)**p;
		} else {
			unsigned char ch = 0;

			for (j = 0; j < 2; j++) {
				(*p)++;
				if (**p >= '0' && **p <= '9') {
					ch = (ch << 4) + (**p -'0');
				} else if (**p >= 'a' && **p <= 'f') {
					ch = (ch << 4) + (**p -'a'+10);
				} else if (**p >= 'A' && **p <= 'F') {
					ch = (ch << 4) + (**p -'A'+10);
				} else {
					zend_string_efree(str);
					return NULL;
				}
			}
			ZSTR_VAL(str)[i] = (char)ch;
		}
		(*p)++;
	}
	ZSTR_VAL(str)[i] = 0;
	ZSTR_LEN(str) = i;
	return str;
}

二、反序列化特性

1、反序列化之后的内容为一个对象。

2、反序列化生成的对象里的值,由反序列化里的值提供,与原有类预定义的值无关。

3、反序列化不触发类的成员方法(成员函数)(魔术方法除外),需要调用方法后才能触发。

三、魔术方法的构造和解析

__construct() 类的构建函数

__destruct() 类的析构函数

__call() 在对象中调用一个不可以访问方法时调用

__callStatic() 用静态方式中调用一个不可以访问方法时调用

__get() 获得一个类的成员变量时调用

__isset() 当对不可访问属性调用isset()或empyt()时调用

__set() 设置一个类的成员变量时调用

__unset() 当对不可访问属性调用unset()时被调用

__sleep() 执行serialize()时,先会调用这个函数

__wakeup() 执行unserialize()时,会先调用这个函数

__toString() 类被当成字符串时的回应方法

__invoke() 调用函数的方式调用一个对象时的回应方法

__set_state() 调用var_export()导出类时,此静态方法被调用

__clone() 当对象复制完成时调用

__autoload() 尝试加载未定义的类

__debuginfo() 打印所需调式信息

1、什么是魔术方法

一个预定义好的,在特定情况下自动触发的行为方法。

2、魔术方法的作用

反序列化漏洞的成因:

反序列化的过程中,unserialize()接收的值(字符串)可控;

通过更改这个值(字符串),得到所需要的代码;

通过调用方法,触发代码执行。

魔术方法的作用就是在特定条件下自动调用相关方法,最终导致触发代码

3、魔术方法相关机制

1、触发机制(动作不同,触发的魔术方法也不同)

2、功能

3、参数(一些特殊魔术方法会传参)

4、返回值

四、常见的序列化格式

  1. 二进制格式
  2. 字节数组
  3. json字符串
  4. xml字符串
相关推荐
千里马学框架3 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台3 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone3 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc3 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo3 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077003 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼3 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone3 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen3 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone3 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui