1、写在前面

OK 兄弟们,这几天一直在面试,发现很多 HR 喜欢问反序列化相关的内容,今天咱们就从最简单的 PHP 原生反序列化入手,带大家入门反序列化

2、PHP 序列化

在 PHP 中,有反序列化,就有序列化,我们先来解释一下序列化。

所谓序列化,就是将 PHP 的一个对象,序列化为一串字符串的过程,其所用的函数就是serialize()

对象:一个对多种信息描述的整体

类:一个储存信息的共享的模板,以class开头

我们先试着创建一个新的类

<?php
class seren //定义一个类
{
//变量
public $a = 'hello';
private $b = 'world';
//方法
public function print_var()
{
echo $this->a;
}
}
?>

上面就是一个很简单的类,我们来看一下,首先使用class声明了一个类seren,在这个seren类里,我们有两个变量a和b,还有一个方法print_var

现在我们要去使用这个类,就需要把这个类实例化为一个对象

//创建一个对象
$object = new seren();
//调用一个方法
$object->print_var();

我们可以使用new,将seren类实例化为一个object对象,如果我们想要使用这个类的方法,可以直接使用 $object->print_var(); 的方法来调用这个方法。

接下来,我们试着使用serialize函数,将这个对象给序列化

<?php
class seren //定义一个类
{
//变量
public $a = 'hello';
private $b = 'world';
//方法
public function print_var()
{
echo $this->a;
}
}
$object = new seren();
$c = serialize($object);
echo $c;
?>

此处我们使用 serialize 将object这个对象,序列化为c,并打印出c

此处可以看到打印出的字符串

O:5:"seren":2:{s:1:"a";s:5:"hello";s:8:" seren b";s:5:"world";}

接下来我们就把这串字符串逐个解释一下。

首先是前面的 O,代表这是一个Object,也就是一个对象,然后是 O 后面的5,代表这个对象的名称为 5 个长度,再后面的seren就是我们对象的名称,后面的 2 就是我们对象里变量的个数。

然后就是大括号里面的内容,里面都是对我们对象里的变量的描述。

第一个s:1:"a";,表示为string类型,这个变量的名称长度为 1,变量名称为 a

后面的s:5:"hello";,表示为string类型,这个值的长度为 5,值为 hello

其实从这里我们就可以发现出规律,这个字符串对对象的描述都是类型+长度+名称的格式

比较特殊的就是后面的s:8:" seren b";,此处我们可以看到似乎有点不一样,这里的长度变成了 8,并且名称变成了serenb

我们回到上面,看我们创建这个类的时候,b 的类型为private,所以就可以知道,根据规定,private类型的变量在序列化后,名称会变为类名+变量名的格式,但是serenb也只有 6 个长度,但是他提示我们有 8 个长度

其实是因为在seren的前后有两个我们不可见的%00,他真正的内容应该是%00seren%00b,%00 算是一个长度,所以一共是 8 个长度。

3、PHP 反序列化

讲完了序列化,接下来就是反序列化,反序列化的函数是unserialize(),他可以将我们的序列化后的字符串,反序列化为对象

<?php
class seren //定义一个类
{
//变量
public $a = 'hello';
private $b = 'world';
//方法
public function print_var()
{
echo $this->a;
}
}
$object = new seren();
$c = serialize($object);
$object2 = unserialize($c);
var_dump($object2);
?>

此处我们使用unserialize函数将字符串 c 反序列化为了对象object2

4、魔术方法

魔术方法是 php 反序列化漏洞利用中很重要的一环,一般以两个下划线开头,如果这个类里面存在魔术方法,他就会优先调用魔术方法

_construct()  //当一个对象创建时被调用
_destruct() //对象被销毁时触发
_wakeup() //反序列化前触发
_sleep() //序列化前触发
_toString() //把类当作字符串使用时触发
_get() //用于从不可访问的属性读取数据
_set() //用于将数据写入不可访问的属性
_isset() //在不可访问的属性上调用isset()或empty()触发
_unset() //在不可访问的属性上使用unset时触发
_invoke() //当脚本尝试将对象调用为函数时触发

我们试着在类里创建一个魔术方法wakeup

<?php
class seren //定义一个类
{
//变量
public $a = 'hello';
private $b = 'world';
//方法
public function print_var()
{
echo $this->a;
} public function __wakeup()
{
// TODO: Implement __wakeup() method.
echo 'Follow SerenSec!';
}
}
$object = new seren();
$c = serialize($object);
$object2 = unserialize($c);
?>

运行后发现输出了Follow SerenSec!

5、PHP 反序列化漏洞

我们可以试着在反序列化的时候,寻找一些比较危险的魔术方法,从而达成 RCE 的目的,这就是反序列化漏洞

下面是一个很简单的例子

<?php
class seren //定义一个类
{
//变量
public $a = 'hello';
private $b = 'world';
public $hack;
//方法
public function print_var()
{
echo $this->a;
}
public function __construct($hack) {
$this->hack = $hack;
}
public function __wakeup()
{
// TODO: Implement __wakeup() method.
echo shell_exec($this->hack);
}
}
$object2 = unserialize($_GET['hack']);
?>

此时我们发现有 __wakeup 魔术方法,其中存在 shell_exec 函数,可以执行命令,并且其中的 hack 变量是可控的

我们先构造出序列化后的字符串

O:5:"seren":3:{s:1:"a";s:5:"hello";s:8:"%00seren%00b";s:5:"world";s:4:"hack";s:6:"whoami"}

然后构造 payload

http://localhost/test.php?hack=O:5:%22seren%22:3:{s:1:%22a%22;s:5:%22hello%22;s:8:%22%00seren%00b%22;s:5:%22world%22;s:4:%22hack%22;s:6:%22whoami%22}

成功执行命令

6、结语

PHP 原生反序列化比较简单,后面会有一些拓展内容,像是POP 链Phar 协议,这些是比较绕的地方,各位可以自行探索。

从零开始的PHP原生反序列化漏洞的更多相关文章

  1. Weblogic反序列化漏洞补丁更新解决方案

    Weblogic反序列化漏洞的解决方案基于网上给的方案有两种: 第一种方案如下 使用SerialKiller替换进行序列化操作的ObjectInputStream类; 在不影响业务的情况下,临时删除掉 ...

  2. Java反序列化漏洞总结

    本文首发自https://www.secpulse.com/archives/95012.html,转载请注明出处. 前言 什么是序列化和反序列化 Java 提供了一种对象序列化的机制,该机制中,一个 ...

  3. 原来不只是fastjson,这个你每天都在用的类库也被爆过反序列化漏洞!

    GitHub 15.8k Star 的Java工程师成神之路,不来了解一下吗! GitHub 15.8k Star 的Java工程师成神之路,真的不来了解一下吗! GitHub 15.8k Star ...

  4. 通过WebGoat学习java反序列化漏洞

    首发于freebuff. WebGoat-Insecure Deserialization Insecure Deserialization 01 概念 本课程描述了什么是序列化,以及如何操纵它来执行 ...

  5. 【CVE-2020-1948】Apache Dubbo Provider反序列化漏洞复现

    一.实验简介 实验所属系列: 系统安全 实验对象:本科/专科信息安全专业 相关课程及专业: 计算机网络 实验时数(学分):2 学时 实验类别: 实践实验类 二.实验目的 Apache Dubbo是一款 ...

  6. 反序列化漏洞问题研究之php篇

    php的反序列化反序列化漏洞又称php对象注入(php Object Injection)产生的问题主要分以下两类: 将传来的序列化数据直接unserilize,造成魔幻函数的执行.这种情况在一般的应 ...

  7. Java反序列化漏洞执行命令回显实现及Exploit下载

    原文地址:http://www.freebuf.com/tools/88908.html 本文原创作者:rebeyond 文中提及的部分技术.工具可能带有一定攻击性,仅供安全学习和教学用途,禁止非法使 ...

  8. Java反序列化漏洞通用利用分析

    原文:http://blog.chaitin.com/2015-11-11_java_unserialize_rce/ 博主也是JAVA的,也研究安全,所以认为这个漏洞非常严重.长亭科技分析的非常细致 ...

  9. Java反序列化漏洞分析

    相关学习资料 http://www.freebuf.com/vuls/90840.html https://security.tencent.com/index.php/blog/msg/97 htt ...

  10. 小白审计JACKSON反序列化漏洞

    1. JACKSON漏洞解析 poc代码:main.java import com.fasterxml.jackson.databind.ObjectMapper; import com.sun.or ...

随机推荐

  1. C#/.NET/.NET Core技术前沿周刊 | 第 25 期(2025年2.1-2.9)

    前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录.追踪C#/.NET/.NET Core领域.生态的每周最新.最实用.最有价值的技术文章.社区动态.优质项目和学习资源等. ...

  2. Plotly.NET 一个为 .NET 打造的强大开源交互式图表库

    前言 今天大姚给大家分享一个 .NET 强大.免费.开源的交互式图表库:Plotly.NET. 项目介绍 Plotly.NET 一个为 .NET 打造的强大.免费.开源的交互式图表库,支持 C# 和 ...

  3. copilot插件使用介绍

    Copilot插件是一个由GitHub开发的人工智能代码助手,可以为开发人员提供代码自动补全和建议功能.Copilot使用了机器学习技术,通过分析大量的开源代码来自动生成代码片段和建议. 使用Copi ...

  4. 机器学习 | 强化学习(2) | 动态规划求解(Planning by Dynamic Programming)

    动态规划求解(Planning by Dynamic Programming) 动态规划概论 动态(Dynamic):序列性又或是时序性的问题部分 规划(Programming):最优化一个程序(Pr ...

  5. 面试题55 - I. 二叉树的深度

    地址:https://leetcode-cn.com/problems/er-cha-shu-de-shen-du-lcof/ <?php /** 面试题55 - I. 二叉树的深度 输入一棵二 ...

  6. 复杂任务分解:Tree of Thought

    像搭乐高一样玩转AI思考 今天要带大家解锁一个让AI从"单细胞生物"进化成"八爪鱼思考者"的神技--Tree of Thought(思维树).准备好了吗?我们要 ...

  7. C系统级编程-复习

    数组对象类型 Array of Type,它是多个相同对象类型的一维派生类型,包含两要素:元素个数,元素的对象类型 所谓多维数组,不过是元素的迭代衍生,本质还是一维的 声明 对象标识的名称 对象类型 ...

  8. NumPy学习3

    继续学习NumPy,今天学习以下3个章节: 7,NumPy高级索引 8,NumPy广播机制 9,NumPy遍历数组 numpy_test3.py : import numpy as np ''' 7, ...

  9. Linux下配置系统ipv6环境

    一:检查Linux是否已经开启ipv6 1.使用 ifconfig 查看自己的IP地址是否含有IPv6地址. inet6 addr: fe80::213:d4f*:****:****/64 Scope ...

  10. WebGL 的简易入门教程

    目录 前言 第一节 绘制出了一个点 效果演示 逐行解释 向量类型 第二节 动态传递点数据 变量修饰符 完整代码 第三节 缓冲区和画线 类型化数组 绘制的方式 完整代码 第四节 彩色线段 精度修饰符 完 ...