当前位置:网站首页>【安全攻防】序列化与反序列,你了解多少?
【安全攻防】序列化与反序列,你了解多少?
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
?>
arg
unserialize()
demo
__destruct()
__destruct()
arg
arg
unserialize()
__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()

边栏推荐
- 苹果CMS仿西瓜视频大气响应式视频模板源码
- Leetcode skimming: binary tree 09 (minimum depth of binary tree)
- Restore the subtlety of window position
- 【微服务|openfeign】feign的两种降级方式|Fallback|FallbackFactory
- One click compilation and deployment of MySQL
- (指针)编写函数void fun(int x,int *pp,int *n)
- Virtual commodity account trading platform source code_ Support personal QR code collection
- (指针)自己写一个比较字符串大小的函数,功能与strcmp类似。
- 架构训练毕业设计+总结
- (指針)自己寫一個比較字符串大小的函數,功能與strcmp類似。
猜你喜欢
Keysight N9320B射频频谱分析仪解决轮胎压力监测方案
leetcode刷题:二叉树07(二叉树的最大深度)
Ppt tutorial, how to save a presentation as a PDF file in PowerPoint?
leetcode刷题:二叉树06(对称二叉树)
Imitation of "game bird" source code, mobile game issue evaluation, open service, open test collection, game download website template
I Build a simple microservice project
干货!基于GAN的稀有样本生成
tdk-lambda电源主要应用
Leetcode skimming: binary tree 07 (maximum depth of binary tree)
【微信小程序】好看的轮播图组件
随机推荐
RHCSA 06 - suid, sgid, sticky bit(待补充)
96% of the collected traffic is prevented by bubble mart of cloud hosting
How was my life in 2021
Katalon uses script to query list size
透过JVM-SANDBOX源码,了解字节码增强技术原理
leetcode刷题:二叉树08(N叉树的最大深度)
(指針)自己寫一個比較字符串大小的函數,功能與strcmp類似。
RHCSA 03 - 文件的基础权限
Pointer array and array pointer
Global exposure and roller shutter exposure of industrial cameras
Common methods of threads
2021 RSC | Drug–target affinity prediction using graph neural network and contact maps
Redis:有序集合zset类型数据操作命令
领导:谁再用redis过期监听实现关闭订单,立马滚蛋!
虚拟商品帐号交易平台源码_支持个人二维码收款
Leetcode skimming: binary tree 08 (maximum depth of n-ary tree)
Flink学习7:应用程序结构
C语言单向链表练习
Emlog user registration plug-in is worth 80 yuan
JS realizes the effect of text scrolling marquee