当前位置:网站首页>【安全攻防】序列化与反序列,你了解多少?
【安全攻防】序列化与反序列,你了解多少?
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()
边栏推荐
猜你喜欢

Activiti7 task service - process variables (setvariable and setvariablelocal)

Leetcode skimming: binary tree 09 (minimum depth of binary tree)

Modstartblog modern personal blog system v5.2.0 source code download

Keysight N9320B射频频谱分析仪解决轮胎压力监测方案

透过JVM-SANDBOX源码,了解字节码增强技术原理

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

Flink learning 7: application structure

苹果CMS仿西瓜视频大气响应式视频模板源码

Flink learning 6: programming model

旭化成首次参展第五届中国国际进口博览会(5th CIIE)
随机推荐
Emlog用户注册插件 价值80元
Redis cluster view the slots of each node
Pytest基础自学系列(一)
leetcode刷题:二叉树07(二叉树的最大深度)
Leetcode skimming: binary tree 07 (maximum depth of binary tree)
R语言dplyr中的Select函数变量列名
2020 Bioinformatics | TransformerCPI
(指针)编写函数void fun(int x,int *pp,int *n)
R语言中如何查看已安装的R包
RHCSA 07 - 用户与群组管理
ROS2中CMake编译选项的设置
Flink学习7:应用程序结构
Flink learning 7: application structure
Programmers' telecommuting is mixed | community essay solicitation
毕业设计:设计秒杀电商系统
多位科技公司创始人向Entrepreneur First提供高达1.58亿美元的C轮融资,协助其投资下一代全球创新者
Confession code collection, who says program apes don't understand romance
dried food! Generation of rare samples based on GaN
Perf simple process for multithreaded profile
Interpretation of leveldb source code skiplist