当前位置:网站首页>【安全攻防】序列化与反序列,你了解多少?
【安全攻防】序列化与反序列,你了解多少?
2022-07-04 03:53:00 【InfoQ】
1.序列化与反序列化
serialize()对象数组<?php
highlight_file(__FILE__);
$sites=array('I', 'Like', 'PHP');
echo'<br/>';
var_dump(serialize($sites)); //把这个对象进行序列化
echo'<br/>';
classman{
public$name="xiaocui";
public$sex="man";
private$age=26;
}
$M=newman();//创建一个对象
var_dump(serialize($M)); //把这个对象进行序列化
?>
string(47) "a:3:{i:0;s:1:"I";i:1;s:4:"Like";i:2;s:3:"PHP";}"
string(79) "O:3:"man":3:{s:4:"name";s:7:"xiaocui";s:3:"sex";s:3:"man";s:8:"manage";i:26;}"
数组的序列化:
a 代表一数组
3 代表数组中有3个元素
i 代表数组的下标
0 代表I元素的下标值
s 代表元素I的数据类型为字符型
1 代表元素I的长度为1
对象的序列化:
O 代表是一个对象
3 代表类名man的长度
3 代表类中的字段数
s 代表属性name的类型为字符型
4 代表属性name的长度
//后面的以此类推,序列化字符串中字段内容以{开始,;}结束
unserialize()原来的数组或对象<?php
highlight_file(__FILE__);
$sites=array('I', 'Like', 'PHP');
echo'<br/>';
echo$ser=serialize($sites).'<br/>'; //把这个对象进行序列化
var_dump(unserialize($ser)); //把序列化的字符串进行反序列化
echo'<br/>';
classman{
public$name="xiaocui";
public$sex="man";
private$age=26;
}
$M=newman();//创建一个对象
echo$ser=serialize($M).'<br/>'; //把这个对象进行序列化
var_dump(unserialize($ser)); //把序列化的字符串进行反序列化
?>
a:3:{i:0;s:1:"I";i:1;s:4:"Like";i:2;s:3:"PHP";}
array(3) { [0]=>string(1) "I"[1]=>string(4) "Like"[2]=>string(3) "PHP"}
O:3:"man":3:{s:4:"name";s:7:"xiaocui";s:3:"sex";s:3:"man";s:8:"manage";i:26;}
object(man)#2 (3) { ["name"]=> string(7) "xiaocui" ["sex"]=> string(3) "man" ["age":"man":private]=> int(26) }
2.魔术方法
____PHP中常见魔术方法
__construct()
<?php
highlight_file(__FILE__);
classdemo{
public$name="xiaocui";
public$sex="man";
private$age=26;
publicfunction__construct()
{
echo"<br/>"."类被实例化时调用我!";
}
}
$D=newdemo(); //实例化对象
?>
类被实例化时调用我!
__destruct()
<?php
highlight_file(__FILE__);
class demo{
public $name="xiaocui";
public $sex="man";
private $age=26;
public function __construct()
{
echo "<br/>"."类被实例化时调用我!"."<br/>";
}
public function num($a,$b){
echo $c = $a + $b.'<br/>';
return $c;
}
public function __destruct(){
echo "当类中的所有方法都被销毁时调用我!";
}
public function person($per){
echo "We are $per !!!".'<br/>';
}
}
$D=new demo(); //实例化对象
$D->num(5,6); //调用num()方法
$D->person(man); //调用person()方法
?>
类被实例化时调用我!
11
Weareman!!!
当类中的所有方法都被销毁时调用我!
__construct()num(5,6)person(nanren)__destruct()__construct()num()person()__destruct()__wakeup()
unserialize()__wakeup()<?php
highlight_file(__FILE__);
classdemo{
public$name="xiaocui";
protected$sex="man";
private$age=26;
publicfunction__construct()
{
echo"<br/>"."类被实例化时调用我!"."<br/>";
}
publicfunction__destruct(){
echo"<br/>"."当类中的所有方法都被销毁时调用我!"."<br/>";
}
publicfunction__wakeup()
{
echo"<br/>"."当反序列时首先调用我 !".'<br/>';
}
}
$D=newdemo(); //实例化对象
echo$ser=serialize($D); //序列化对象$D
var_dump(unserialize($ser)); //反序列化字符串$ser
?>
$age类被实例化时调用我!
O:4:"demo":3:{s:4:"name";s:7:"xiaocui";s:6:"*sex";s:3:"man";s:9:"demoage";i:26;}
当反序列时调用我 !
object(demo)#2
(3) { ["name"]=> string(7) "xiaocui" ["sex":protected]=>
string(3) "man" ["age":"demo":private]=> int(26) }
当类中的所有方法都被销毁时调用我!
当类中的所有方法都被销毁时调用我!
__construct()serialize($D)__wakeup()unserialize($ser)__destruct()__destruct()__construct()serialize($D)__wakeup()unserialize($ser)__destruct()__destruct()__toString()
__toString()<?php
highlight_file(__FILE__);
class demo{
public $name="xiaocui";
protected $sex="man";
private $age=26;
public function __construct()
{
echo "<br/>"."类被实例化时调用我!"."<br/>";
}
public function __destruct(){
echo "<br/>"."当类中的所有方法都被销毁时调用我!"."<br/>";
}
public function __wakeup()
{
echo "<br/>"."当反序列时调用我 !".'<br/>';
}
public function __toString(){
return "<br/>"."类被当成字符串处理时调用我!"."<br/>";
}
}
$D=new demo(); //实例化对象
echo $D; //类被当成字符串输出
?>
类被实例化时调用我!
类被当成字符串处理时调用我!
当类中的所有方法都被销毁时调用我!
echo__toString()__toString()Catchablefatalerror: ObjectofclassdemocouldnotbeconvertedtostringinD:\XXXX\phpstudy_pro\WWW\two\demo.phponline30
__sleep()
serialize()__sleep()__sleep()<?php
highlight_file(__FILE__);
class demo{
public $name="xiaocui";
protected $sex="man";
private $age=26;
public function __construct()
{
echo "<br/>"."类被实例化时调用我!"."<br/>";
}
public function __destruct(){
echo "<br/>"."当类中的所有方法都被销毁时调用我!"."<br/>";
}
public function __wakeup()
{
echo "<br/>"."当反序列时调用我 !".'<br/>';
}
public function __sleep(){
echo "<br/>"."当序列时调用我 !".'<br/>';
return array("name","sex","age"); //这里必须返回一个数值,里边的元素表示返回的属性名称
}
}
$D=new demo(); //实例化对象
echo $ser = serialize($D); //序列化对象
?>
类被实例化时调用我!
当序列时调用我!
O:4:"demo":3:{s:4:"name";s:7:"xiaocui";s:6:"*sex";s:3:"man";s:9:"demoage";i:26;}
当类中的所有方法都被销毁时调用我!
__sleep()__invoke()
__invoke<?php
highlight_file(__FILE__);
class demo{
public $name="xiaocui";
protected $sex="man";
private $age=26;
public function __construct()
{
echo "<br/>"."类被实例化时调用我!"."<br/>";
}
public function __destruct(){
echo "<br/>"."当类中的所有方法都被销毁时调用我!"."<br/>";
}
public function __wakeup()
{
echo "<br/>"."当反序列化时调用我 !".'<br/>';
}
public function __sleep(){
echo "<br/>"."当序列化时调用我 !".'<br/>';
return array("name","sex","age");
}
public function __invoke()
{
echo "<br/>"."当以函数的方式调用对象时会调用我!".'<br/>';
}
}
$D=new demo(); //实例化对象
$D(); //以函数的方式调用对象
?>
类被实例化时调用我!
当以函数的方式调用对象时会调用我!
当类中的所有方法都被销毁时调用我!
__invoke()Fatalerror:
UncaughtError:
FunctionnamemustbeastringinD:\xxxxx\phpstudy_pro\WWW\two\demo.php:42Stacktrace:
#0 {main} thrown in D:\xxxxx\phpstudy_pro\WWW\two\demo.php on line 42
__call()
__call<?php
highlight_file(__FILE__);
class demo{
public $name="xiaocui";
protected $sex="man";
private $age=26;
public function __construct()
{
echo "<br/>"."类被实例化时调用我!"."<br/>";
}
public function num($a,$b){
echo "<br/>".$c = $a + $b.'<br/>';
return $c;
}
public function __destruct(){
echo "<br/>"."当类中的所有方法都被销毁时调用我!"."<br/>";
}
public function person($per){
echo "<br/>"."We are $per !!!".'<br/>';
}
public function __wakeup()
{
echo "<br/>"."当反序列化时调用我 !".'<br/>';
}
public function __sleep(){
echo "<br/>"."当序列时调用我 !".'<br/>';
return array("name","sex","age");
}
public function __call($arg1,$arg2){
echo "<br/>"."当对象调用一个不存在或者不可访问的方法时调用我!".'<br/>';
}
}
$D=new demo(); //实例化对象
$D->num1(1,2); //调用一个不存在的方法
?>
类被实例化时调用我!
当对象调用一个不存在或者不可访问的方法时调用我!
当类中的所有方法都被销毁时调用我!
__set()
__set<?php
highlight_file(__FILE__);
class demo extends demo1{
public $name="xiaocui";
protected $sex="man";
private $age=26;
public function __construct()
{
echo "<br/>"."类被实例化时调用我!"."<br/>";
}
public function __destruct(){
echo "<br/>"."当类中的所有方法都被销毁时调用我!"."<br/>";
}
public function person($per){
echo "<br/>"."We are $per !!!".'<br/>';
}
public function __set($arg1,$arg2){
echo "<br/>"."当给不存在或者不可访问的属性赋值时调用我!"."<br/>";
}
}
class demo1{
private $weight;
public $height;
public function people(){
echo $this->weight;
echo $this->height;
}
}
$D=new demo(); //实例化对象
$D->weight=74; //给不可访问的属性赋值
?>
类被实例化时调用我!
当给不存在或者不可访问的属性赋值时调用我!
当类中的所有方法都被销毁时调用我!
__isset()
isset()empty()__iset()__unset()
unset()__unset()__get()
__get<?php
highlight_file(__FILE__);
class demo extends demo1{
public $name="xiaocui";
protected $sex="man";
private $age=26;
public function __construct()
{
echo "<br/>"."类被实例化时调用我!"."<br/>";
}
public function __destruct(){
echo "<br/>"."当类中的所有方法都被销毁时调用我!"."<br/>";
}
public function __get($arg1){
echo "<br/>"."读取不存在或不可访问的属性时调用我!";
}
}
class demo1{
private $weight = 0;
public $height;
public function people(){
echo $this->weight;
echo $this->height;
}
}
$D=new demo(); //实例化对象
$D->weight; //读取父类中不可访问的属性
?>
类被实例化时调用我!
读取不存在或不可访问的属性时调用我!
当类中的所有方法都被销毁时调用我!
3.反序列化漏洞
3.1 反序列化漏洞利用条件
① unserialize()函数中参数可控
② 存在可利用的类,且类中有魔术方法
<?php
highlight_file(__FILE__);
class demo
{
public $arg1 = "0";
public function __destruct()
{
echo $this->arg1; //输出用户传递的arg1值
}
}
$a=$_GET['arg']; //接收前端传递的arg1变量
$unser = unserialize($a); //反序列化传递的arg1
?>
argunserialize()demo__destruct()__destruct()argargunserialize()__destruct()XSS

<?php
highlight_file(__FILE__);
class demo
{
public $arg1 = "0";
public function __destruct()
{
eval($this->arg1); //eval()去执行用户传递的arg1值
}
}
$a=$_GET['arg']; //接收前端传递的arg1变量
$unser = unserialize($a); //反序列化传递的arg1
var_dump($unser);
?>
eval()RCE
3.2 __wakeup()函数绕过
__wakeup()<?php
highlight_file(__FILE__);
class demo
{
public $arg1 = "0";
public function __destruct()
{
eval($this->arg1); //eval()去执行用户传递的arg1值
}
public function __wakeup(){
foreach(get_object_vars($this) as $k => $v) {
$this->$k = ''; //将传入的参数遍历,全部赋值为空
}
}
}
$a=$_GET['arg']; //接收前端传递的arg1变量
$unser = unserialize($a); //反序列化传递的arg1
var_dump($unser);
?>
__wakeup()
__wakeup()
边栏推荐
- UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0x98 in position 1093: illegal multibyte sequence
- leetcode刷题:二叉树06(对称二叉树)
- [microservices openfeign] two degradation methods of feign | fallback | fallbackfactory
- 【愚公系列】2022年7月 Go教学课程 001-Go语言前提简介
- 网络 - VXLAN
- ModStartBlog 现代化个人博客系统 v5.2.0 源码下载
- Unity 绘制弹球和台球的运动轨迹
- leetcode刷题:二叉树09(二叉树的最小深度)
- Configuration and hot update of nocturnal simulator in hbuildx
- 【微服务|openfeign】feign的两种降级方式|Fallback|FallbackFactory
猜你喜欢

【微服务|openfeign】@FeignClient详解

2020 Bioinformatics | TransformerCPI

5张图告诉你:同样是职场人,差距怎么这么大?

【云原生】那些看起来很牛X,原理却很简单的一行代码

博朗与Virgil Abloh于2021年为纪念博朗品牌100周年而联合打造的“功能性艺术”将在博物馆展出Abloh作品期间首次亮相

深入解析结构化异常处理(SEH) - by Matt Pietrek

Restore the subtlety of window position

Graduation project: design seckill e-commerce system

ModStartBlog 现代化个人博客系统 v5.2.0 源码下载

2021 RSC | Drug–target affinity prediction using graph neural network and contact maps
随机推荐
仿《游戏鸟》源码 手游发号评测开服开测合集专区游戏下载网站模板
Apple CMS imitation watermelon video atmospheric response video template source code
Parameterization of controls in katalon
leetcode刷题:二叉树05(翻转二叉树)
架构实战营 - 第 6 期 模块九之毕业设计
I.MX6U-ALPHA开发板(模仿STM32驱动开发实验)
什么是上下文?
网络 - VXLAN
R语言中如何查看已安装的R包
陪驾注意事项 这23点要注意!
Configuration and hot update of nocturnal simulator in hbuildx
The difference between bagging and boosting in machine learning
Wechat brain competition answer applet_ Support the flow main belt with the latest question bank file
新手找陪驾要注意什么
UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0x98 in position 1093: illegal multibyte sequence
【云原生】那些看起来很牛X,原理却很简单的一行代码
Tcp- simple understanding of three handshakes and four waves
[webrtc] M98 Ninja build and compile instructions
Unity draws the trajectory of pinball and billiards
Leetcode brush questions: binary tree 05 (flip binary tree)