热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【CyberSecurityLearning69】反序列化漏洞

目录反序列化为什么要序列化PHP中序列化与反序列化*简单的例子*序列化Demo*漏洞何在?创建一个类,一个对象并将其序列化和反序列化反序列化

目录

反序列化

为什么要序列化

PHP 中序列化与反序列化

*简单的例子

*序列化Demo

*漏洞何在?

@ 创建一个类,一个对象并将其序列化和反序列化

@ 反序列化注入

*为什么会这样呢



 


反序列化


为什么要序列化

class   类
obj      对象

百度百科关于序列化的定义是,将对象的状态信息转换为可以存储或传输的形式(字符串)的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区(把存储放在数据库中,首选数据库是Redis,或者是类型Redis这种键值对型数据库,可以理解为Redis数据库就是一个大数组通过键值对的方式去访问,关系型数据库就是一张大的Excel表格)。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

简单地说,序列化就是把一个对象变成可以传输的字符串(便于传输),反序列化就是将字符串转换成对象的过程(如果这个字符串客户端可控,就可以让web应用反序列化任意对象,严重的是我们在反序列化过程中会触发一些可执行的PHP代码,比如说phpinfo),可以以特定的格式在进程之间跨平台、安全的进行通信。

class Stu{public $name;public $sex;public $agel;public $score;
}
$stu1= new Stu();//创建了一个对象 new
$stu1->name="ZQX";
$stu1->sex=true;
$stu1->age=16;
$stu1->score=60;$stu2= new Stu();
$stu2->name="HMM";
$stu2->sex=false;
$stu2->age=16;
$stu2->score=90;echo $stu1->name."'s score = ".$stu1->score; //ZQX's score = 60 先找到对象名,再找到他的属性
echo $stu2->name."'s score = ".$stu2->score;
echo "


";
var_dump($stu1);
//把stu1这个对象,一个抽象的数据结构转化成字符串并存储在硬盘的文件当中,这个过程叫序列化
//序列化好处:我们可以把一个用户的状态相当做一个暂停,等用户激活的时候再从硬盘把字符串取出来,再反序列化成一个对象,然后再存储在内存中让他工作。
?>

PHP 中序列化与反序列化

PHP 反序列化漏洞也叫PHP 对象注入,是一个常见的漏洞,这种类型的漏洞虽然有些难以利用,但一旦利用成功就会造成非常威胁的后果。漏洞的形成的根本原因是程序员没有对用户输入的反序列化字符串进行检测,导致反序列化过程可以被恶意控制,进而造成代码执行、getshell 等一系列不可控的后果。反序列化漏洞并不是PHP 特有的,也存在于Java、Python 等语言之中但其原理基本相通。

PHP中的序列化与反序列化,基本都是围绕serialize()和 unserialize() 两个函数展开的。
 


*简单的例子

我们可以用json(json这种格式就是格式化的一个字符串,也就是说Json格式的数据具备自己一定的格式) 格式数据的编码与解码,来理解序列化与反序列化过程。虽然json 数据与反序列化漏洞没有什么关系,但是这个例子有助于我们理解。

测试代码:

$stu=array('name'=>'Waffle','age'=>20,'SEX'=>true,'score'=>96.6);
echo $stu; //echo是不能输出数组的
echo "


";
$stu_json=json_encode($stu);//但是如果我们把 数字$stu做一个json的格式转换json_encode
//array一个抽象的数组,经过json的格式编码之后他就会变成一个字符串,变成字符串之后就可以用echo来输出
echo $stu_json;
?>

我们定义一个数组,数组属于抽象的数据结构,为了方便跨平台传输,可以将其进行json 编码。json 格式的数据是以键值对的形式出现的。


Array{"name":"Waffle","age":20,"SEX":true,"score":96.6}


class Stu{public $name;public $sex;public $agel;public $score;
}
$stu1= new Stu();//创建了一个对象 new
$stu1->name="ZQX";
$stu1->sex=true;
$stu1->age=16;
$stu1->score=60;$stu2= new Stu();
$stu2->name="HMM";
$stu2->sex=false;
$stu2->age=16;
$stu2->score=90;echo $stu1->name."'s score = ".$stu1->score; //ZQX's score = 60 先找到对象名,再找到他的属性
echo $stu2->name."'s score = ".$stu2->score;
echo "


";
//var_dump($stu1);
//把stu1这个对象,一个抽象的数据结构转化成字符串并存储在硬盘的文件当中,这个过程叫序列化
//序列化好处:我们可以把一个用户的状态相当做一个暂停,等用户激活的时候再从硬盘把字符串取出来,再反序列化成一个对象,然后再存储在内存中让他工作。
//echo $stu1;//(x)不能以字符串方式去输出,接下来我们需要将stu1做一个转换
echo serialize($stu1);//serialize这个函数会把我们的对象作一个序列化,把它序列化成一个字符串
//O:3:"Stu":5:{s:4:"name";s:3:"ZQX";s:3:"sex";b:1;s:4:"agel";N;s:5:"score";i:60;s:3:"age";i:16;}
//O代表object,3是类名的长度,5说明我们类中有四个属性,每句话以分号结束,s表示string类型,b表示bool类型
?>

*序列化Demo

序列化会将一个抽象的转换为字符串。

我们可以写一个Demo 来说明序列化的过程,首先创建一个类,代码如下

class Stu{
public $name;
public $sex;
public $age;
public $score;
}
?>

类名是Stu ,有四个变量。

下面我们创建一个对象,并给对象中变量赋值。代码如下

include "classStu.php";
$stu1 = new Stu();
$stu1->name = "Waffle";
$stu1->sex = true;
$stu1->age = 18;
$stu1->score = 89.9;
echo serialize($stu1);
?>

我们最后使用serialize() 函数,将$stu1 这个对象序列化成一个字符串。这样的字符串,就很容易传输和存储。如下


    O:3:"Stu":4:   //O 代表Object 对象;3对象名有三个字符;对象中有4个变量

    {s:4:"name";s:3:"GGG";

    s:3:"sex";b:1;

    s:3:"age";i:18;

    s:5:"score";d:89.900000000000006;}
 


同样,我们也可以使用unserialize()函数,将字符串反序列化为一个对象。由于字符串中含有双引号,我们可以使用定界符,代码如下

HTML;$stu1=unserialize($stu1);var_dump($stu1);?>

运行这个脚本,我们可以看到反序列化后的对象


    object(Stu)#1 (4) { ["name"]=> string(3) "GGG" ["sex"]=> bool(true) ["age"]=> int(18) ["score"]=> float(89.9) }



*漏洞何在?


@ 创建一个类,一个对象并将其序列化和反序列化

str);}
}$test = new Test();
echo serialize($test);//serialize是序列化的意思 //O:4:"Test":1:{s:3:"str";s:6:"Waffle";}这里面只有属性没有方法
echo "


";
//$t=serialize($test);
//var_dump(unserialize($t)); //object(Test)#2 (1) { ["str"]=> string(6) "Waffle" }
var_dump(unserialize($_GET['obj'])); //反序列化一下 ?>


@ 反序列化注入

构造序列化字符


…/class/loudong.php?obj=O:4:"Test":1:{s:3:"str";s:10:"phpinfo();";}


会发现phpinfo() 函数被执行了

由以上代码可以发现,PHP的反序列化漏洞需要与其他漏洞配合,比如代码执行SQLi等

 


*为什么会这样呢

我们注入的字符串[phpinfo()],为什么会作为PHP 语句运行呢?观察代码,发现在类中有一个函数 __destruct() 并且这个函数调用的eval 语句,执行$this->str 变量。为什么__destruct() 没有被调用,函数内的语句就被执行了呢?
可以用如下代码测试 __destruct() 函数

str);}}$test = new Test();echo serialize($test);echo "


";var_dump(unserialize($_GET['obj']));?>

我们会发现,在销毁实例化类(就是对象)的时候,__destruct() 函数会被调用,并输出字符串

 

以 __ 开头的方法,是PHP 中的魔术方法,类中的魔术方法,在特定的情况下会被自动调用。主要魔术方法如下


__construct()

在创建对象时自动调用

__destruct()

 在销毁对象时自动调用

__call()

 在对象中调用一个不可访问方法时,__call() 会被调用

__callStatic()

 在静态上下文中调用一个不可访问方法时调用

__get()

读取不可访问属性的值时,__get() 会被调用

__set()

在给不可访问属性赋值时,__set() 会被调用

__isset()

当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用

__unset()

当对不可访问属性调用 unset() 时,__unset() 会被调用

__sleep()

serialize() 函数会检查类中是否存在一个魔术方法__sleep() ,如果存在,该方法会先被调用,然后再执行序列化操作

__wakeup()

unserialize() 会检查是否存在一个 __wakeup() 方法,如果存在会先调用__wakeup方法,预先准备对象需要的资源

__toString()

__toString() 方法用于一个类被当成字符串时应增氧回应

__invoke()

当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用

__set_state()

字PHP 5.1.0 起调用 var_export() 导出类时,此静态 方法会被调用

__clone()

当复制完成时,如果定义了 __clone 方法,则新创建的对象(复制生成的对象)中的 __clone() 方法会被调用,可用于修改属性的值。

__debugInfo()This method is called by var_dump() anobject to get the properties that should be shown .If the method isn't on an object ,then all public ,protec‘’ted and private propertieswill be shown.

参考链接:
http://www.freebuf.com/articles/web/167721.html
https://baike.baidu.com/item/%E5%BA%8F%E5%88%97%E5%8C%96/2890184?fr=aladdin
https://www.cnblogs.com/magic-zero/p/7737274.html
https://mp.weixin.qq.com/s?__biz=MzAxNDY2MTQ2OQ==&mid=2650942666&idx=1&sn=5c84d6d69463a0a430e01dfa68c2d3ab&chksm=80796ef8b70ee7ee8ba5d88feb8d794bee19a55b6e17dff45fcee6ba6ee726fb4e2e029d50bd&scene=0#rd
 


推荐阅读
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 本文介绍了一个免费的asp.net控件,该控件具备数据显示、录入、更新、删除等功能。它比datagrid更易用、更实用,同时具备多种功能,例如属性设置、数据排序、字段类型格式化显示、密码字段支持、图像字段上传和生成缩略图等。此外,它还提供了数据验证、日期选择器、数字选择器等功能,以及防止注入攻击、非本页提交和自动分页技术等安全性和性能优化功能。最后,该控件还支持字段值合计和数据导出功能。总之,该控件功能强大且免费,适用于asp.net开发。 ... [详细]
  • Tomcat安装与配置教程及常见问题解决方法
    本文介绍了Tomcat的安装与配置教程,包括jdk版本的选择、域名解析、war文件的部署和访问、常见问题的解决方法等。其中涉及到的问题包括403问题、数据库连接问题、1130错误、2003错误、Java Runtime版本不兼容问题以及502错误等。最后还提到了项目的前后端连接代码的配置。通过本文的指导,读者可以顺利完成Tomcat的安装与配置,并解决常见的问题。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • 导出功能protectedvoidbtnExport(objectsender,EventArgse){用来打开下载窗口stringfileName中 ... [详细]
  • 背景应用安全领域,各类攻击长久以来都危害着互联网上的应用,在web应用安全风险中,各类注入、跨站等攻击仍然占据着较前的位置。WAF(Web应用防火墙)正是为防御和阻断这类攻击而存在 ... [详细]
  • EPPlus绘制刻度线的方法及示例代码
    本文介绍了使用EPPlus绘制刻度线的方法,并提供了示例代码。通过ExcelPackage类和List对象,可以实现在Excel中绘制刻度线的功能。具体的方法和示例代码在文章中进行了详细的介绍和演示。 ... [详细]
  • 手把手教你使用GraphPad Prism和Excel绘制回归分析结果的森林图
    本文介绍了使用GraphPad Prism和Excel绘制回归分析结果的森林图的方法。通过展示森林图,可以更加直观地将回归分析结果可视化。GraphPad Prism是一款专门为医学专业人士设计的绘图软件,同时也兼顾统计分析的功能,操作便捷,可以帮助科研人员轻松绘制出高质量的专业图形。文章以一篇发表在JACC杂志上的研究为例,利用其中的多因素回归分析结果来绘制森林图。通过本文的指导,读者可以学会如何使用GraphPad Prism和Excel绘制回归分析结果的森林图。 ... [详细]
  • java drools5_Java Drools5.1 规则流基础【示例】(中)
    五、规则文件及规则流EduInfoRule.drl:packagemyrules;importsample.Employ;ruleBachelorruleflow-group ... [详细]
  • 本文介绍了在go语言中利用(*interface{})(nil)传递参数类型的原理及应用。通过分析Martini框架中的injector类型的声明,解释了values映射表的作用以及parent Injector的含义。同时,讨论了该技术在实际开发中的应用场景。 ... [详细]
  • Spring框架《一》简介
    Spring框架《一》1.Spring概述1.1简介1.2Spring模板二、IOC容器和Bean1.IOC和DI简介2.三种通过类型获取bean3.给bean的属性赋值3.1依赖 ... [详细]
  • Redis API
    安装启动最简启动命令行输入验证动态参数启动配置文件启动常用配置通用命令keysbdsize计算key的总数exists判断是否存在delkeyvalue删除指定的keyvalue成 ... [详细]
  • 面试经验分享:华为面试四轮电话面试、一轮笔试、一轮主管视频面试、一轮hr视频面试
    最近有朋友去华为面试,面试经历包括四轮电话面试、一轮笔试、一轮主管视频面试、一轮hr视频面试。80%的人都在第一轮电话面试中失败,因为缺乏基础知识。面试问题涉及 ... [详细]
  • Redis的默认端口、数据库使用和多端口配置
    本文介绍了Redis的默认端口、数据库使用和多端口配置的方法。通过选择不同的数据库和使用flushdb命令可以实现对不同数据库的访问和清除数据。同时,本文还介绍了在同一台机器上启用多个Redis实例的方法,并讨论了配置认证密码的步骤和注意事项。 ... [详细]
author-avatar
脉趣小鱼
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有