零基础入门——从零开始学习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)是电脑编程语言,因此也能让开发者藉以编写出让电脑听命行事的程序.以简单的方 ...
随机推荐
- mysql-高级功能(触发器、存储过程、视图、事务)
目录 触发器-created trigger 1.触发器分为六种情况 2.语法结构 3.创建触发器 4.查询/删除触发器 存储过程-created procedure 1.创建存储过程 2.使用存储过 ...
- 猿人学内部js练习平台习题记录
猿人学内部js练习平台习题记录 根据课程更新 当前先完成第7题和第10题 第7题 骚操作 请求规律检测1 - post 1)通过fiddler抓包,看看请求头和请求体有什么骚操作的地方,如果没有反爬就 ...
- 2021-10-15:单词拆分。给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。说明:拆分时可以重复使用字典中的单词。你
2021-10-15:单词拆分.给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词.说明:拆分时可以重复使用字典中的单词.你 ...
- DataGridView数据内容自适应列宽
数据自适应宽度某一列dataGridView1.Columns[@"列名"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCe ...
- 【GiraKoo】常用编码的对比(ASCII,GB2312,GBK,GB18030,UCS,Unicode)
常用编码的对比(ASCII,GB2312,GBK,GB18030,UCS,Unicode) 在程序开发中,文字编码一直扮演着人畜无害,却背后捅一刀的角色. 可能在源代码文件中,注释莫名其妙地变成了乱码 ...
- pytest在conftest里添加钩子函数进行失败处截图,并绑定到allure报告里
在conftest里要先定义一个selenium之类的driver. @pytest.hookimpl(tryfirst=True, hookwrapper=True)def pytest_runte ...
- java通用xls导出设计
背景 在后端日常开发中总会有各种各样的导出需求,实现这个需求必须要解决的两个问题: 1.表头不能直接使用字段名,需要显示为中文,甚至还需要考虑国际化 2.值需要翻译,比如性别.状态之类的字段 现状 现 ...
- C#/VB.NET:如何从 PowerPoint 演示文稿中提取文本
在学习或者日常工作中,有时我们需要把幻灯片的东西整理成文字,而从 PowerPoint 演示文稿中一张一张的整理手动复制粘贴,整个过程会非常费精力且耗时.那么怎么样才能比较轻松且快速地提取PowerP ...
- Galaxy Project | 生信人最值得学习的开源项目之一
我与 Galaxy Project 的渊源可以追溯到我刚毕业,还在华大实习的那一段时间,这个项目应该是我职业生涯中最重要的一段经历.虽然这么对年以来一直都关注着这个项目,但大多数都是浅尝辄止,对源码层 ...
- 今天在内部 Galaxy 分析平台操作探针引物设计小工具程序,调用 Ensembl API 获取相关序列和信息时,发现官网 MySQL server 异常,报告问题后当天晚上就收到了回复,并且修......
本文分享自微信公众号 - 生信科技爱好者(bioitee).如有侵权,请联系 support@oschina.cn 删除.本文参与"OSC源创计划",欢迎正在阅读的你也加入,一起分 ...