当前位置:网站首页>【安全攻防】序列化与反序列,你了解多少?
【安全攻防】序列化与反序列,你了解多少?
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()
边栏推荐
- I Build a simple microservice project
- Pointer array and array pointer
- 微信公众号无限回调授权系统源码
- RHCSA 01 - 创建分区与文件系统
- The interactive solution of JS and app in the H5 page embedded in app (parameters can be transferred and callbacks can be made)
- 01 QEMU starts the compiled image vfs: unable to mount root FS on unknown block (0,0)
- Keysight N9320B射频频谱分析仪解决轮胎压力监测方案
- 干货!基于GAN的稀有样本生成
- 资深开发人员告诉你,怎样编写出优秀的代码?
- Activiti7 task service - process variables (setvariable and setvariablelocal)
猜你喜欢

R语言中如何查看已安装的R包

Graduation project: design seckill e-commerce system

Unity draws the trajectory of pinball and billiards

User defined path and file name of Baidu editor in laravel admin

Leetcode brush question: binary tree 06 (symmetric binary tree)

毕业设计:设计秒杀电商系统

Redis:集合Set类型数据的操作命令

Two commonly used graphics can easily realize data display

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

How to telecommute more efficiently | community essay solicitation
随机推荐
(指针)自己写一个比较字符串大小的函数,功能与strcmp类似。
I.MX6U-ALPHA开发板(C语言版本LED驱动实验)
NFT新的契机,多媒体NFT聚合平台OKALEIDO即将上线
RPC技术
Redis cluster view the slots of each node
Use NRM and NVM to manage your NPM source and node versions
Understand the principle of bytecode enhancement technology through the jvm-sandbox source code
Unity 绘制弹球和台球的运动轨迹
仿《游戏鸟》源码 手游发号评测开服开测合集专区游戏下载网站模板
【微服务|openfeign】使用openfeign远程调用文件上传接口
RHCSA 06 - suid, sgid, sticky bit(待补充)
Virtual commodity account trading platform source code_ Support personal QR code collection
C语言单向链表练习
[csrf-01] basic principle and attack and defense of Cross Site Request Forgery vulnerability
精品网址导航主题整站源码 wordpress模板 自适应手机端
leetcode刷题:二叉树08(N叉树的最大深度)
Leetcode skimming: binary tree 09 (minimum depth of binary tree)
Three years of graduation, half a year of distance | community essay solicitation
I.MX6U-ALPHA开发板(模仿STM32驱动开发实验)
Confession code collection, who says program apes don't understand romance