零基础入门——从零开始学习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)是电脑编程语言,因此也能让开发者藉以编写出让电脑听命行事的程序.以简单的方 ...
随机推荐
- 云原生时代崛起的编程语言Go常用标准库实战
@ 目录 基础标准库 简述 字符串-string 底层结构 函数 长度 格式化输出 模版-template text/template html/template 正则表达式-regexp 编码-en ...
- #PowerBi 1分钟学会,以“万”为单位显示数据
PowerBi是一款强大的数据分析和可视化工具,它可以帮助我们快速地制作出各种图表和报表,展示数据的价值和洞察. 但是,有时候我们的数据量太大,导致图表上的数字难以阅读和比较.例如,如果我们想要查看某 ...
- 2022-07-01:某公司年会上,大家要玩一食发奖金游戏,一共有n个员工, 每个员工都有建设积分和捣乱积分, 他们需要排成一队,在队伍最前面的一定是老板,老板也有建设积分和捣乱积分, 排好队后,所有
2022-07-01:某公司年会上,大家要玩一食发奖金游戏,一共有n个员工, 每个员工都有建设积分和捣乱积分, 他们需要排成一队,在队伍最前面的一定是老板,老板也有建设积分和捣乱积分, 排好队后,所有 ...
- 2021-04-10:给定两个可能有环也可能无环的单链表,头节点head1和head2。请实现一个函数,如果两个链表相交,请返回相交的 第一个节点。如果不相交,返回null。【要求】如果两个链表长度之和为N,时间复杂度请达到O(N),额外空间复杂度 请达到O(1)。
2021-04-10:给定两个可能有环也可能无环的单链表,头节点head1和head2.请实现一个函数,如果两个链表相交,请返回相交的 第一个节点.如果不相交,返回null.[要求]如果两个链表长度之 ...
- 2022-01-25:序列化和反序列化 N 叉树。 序列化是指将一个数据结构转化为位序列的过程,因此可以将其存储在文件中或内存缓冲区中,以便稍后在相同或不同的计算机环境中恢复结构。 设计一个序列化和反
2022-01-25:序列化和反序列化 N 叉树. 序列化是指将一个数据结构转化为位序列的过程,因此可以将其存储在文件中或内存缓冲区中,以便稍后在相同或不同的计算机环境中恢复结构. 设计一个序列化和反 ...
- 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 ...
- LINIUX 查询命令的 区别 chich whereis locate fing
我们经常在linux要查找某个文件,但不知道放在哪里了,可以使用下面的一些命令来搜索: which 查看可执行文件的位置. whereis 查看文件的位置. locate 配合数据库查看文件位置 ...
- .Net后台调用js,提示、打开新窗体、关闭当前窗体
.Net后台调用js,提示.关闭当前窗体.打开新窗体 Response.Write("<script>window.alert('支付成功!');window.open('/Jk ...
- Java 网络编程 —— 客户端协议处理框架
概述 Java 对客户程序的通信过程进行了抽象,提供了通用的协议处理框架,该框架封装了 Socket,主要包括以下类: URL 类:统一资源定位符,表示客户程序要访问的远程资源 URLConnecti ...
- Post-Exploitation Basics
开发后基础知识 https://tryhackme.com/room/postexploit 使用 mimikatz.bloodhound.powerview 和 msfvenom 学习后期开发和维护 ...