反序列化漏洞

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一、什么是反序列化漏洞?

1.序列化与反序列化

序列化即将对象转化为字节流,便于保存在文件,内存,数据库中;反序列化即将字节流转化为对象。也就是说,把数据转化为一种可逆的数据结构,再把这种可逆的数据结构转化回数据,这就是序列化与反序列化。
比如,买一个柜子,从北京运到上海,由于柜子形状怪异,不方便运输,先把它拆成板子,再装到箱子里(序列化),顺丰邮到买家手里,把板子拼装回柜子(反序列化)。

2.反序列化漏洞

①反序列化漏洞的产生原理,即黑客通过构造恶意的序列化数据,从而控制应用在反序列化过程中需要调用的类方法,最终实现任意方法调用。如果在这些方法中有命令执行的方法,黑客就可以在服务器上执行任意的命令。
②各种语言都有反序列化漏洞。

二、PHP反序列化漏洞

1.php中必须出现反序列化的原因

①大型网站中类创建的对象多的时候会占用大量的空间
②部分配置文件通过序列化进行文件存储或者传递,然后再进行对象化会比较方便,一次采用序列化存储数据。

2.序列化和反序列化的函数

①.serialize()
当在PHP中创建了一个对象后,可以通过serialize()把这个对象转变成一个字符串,保存对象的值之后方便之后的传递与使用
②.unserialize()
与serialize()对应,unserialize()可以从已存储的表示中创建PHP的值,可以从序列化后的结果中恢复对象(object)
例如:

<?php
$a = array('a' => 'Apple' ,'b' => 'banana' , 'c' => 'Coconut');
 
//序列化数组
$s = serialize($a);
echo "序列化:",$s,"<br>";
//反序列化数组
$aa = unserialize($s);
echo "反序列化:",$aa,"<br>";
print_r($aa);
?>

运行结果为:
a:3:{s:1:“a”;s:5:“Apple”;s:1:“b”;s:6:“banana”;s:1:“c”;s:7:“Coconut”;}
数组:3个对象:{1个字符串类型a;5个字符串类型Apple;以此类推}
在这里插入图片描述

3.php反序列化漏洞示例(PHP对象注入漏洞)

①存在文件1.php如下:

<?php  

class Test{
    var $test = "123";
	//__wakeup() 如果有,在反序列化之前调用
    function __wakeup(){
        $fp = fopen("test.php", 'w');
        fwrite($fp, $this -> test);//把test变量写入test.php文件中
        fclose($fp);
    }
}
 
$test1 = $_GET['test'];//页面url传参
print_r($test1);//输出参数
echo "<br />";
$seri = unserialize($test1);//反序列化参数

require "test.php";  //运行写入的文件
?> 

②构造payload
一个Test类,有一个test参数,test="<?php phpinfo();?>":

O:4:"Test":1:{s:4:"test";s:18:"<?php%20phpinfo();?>";}

③打开php页面时在地址栏传入参数:

1.php?test=O:4:"Test":1:{s:4:"test";s:18:"<?php%20phpinfo();?>";}

可以创建一个test.php文件,并把Test类中的test变量的值即"<?php phpinfo();?>" 写进了test.php文件,最后运行:
在这里插入图片描述

再比如:

<?php 
class Test1{
    function __construct($test){
        $fp = fopen("shell.php", "w");
        fwrite($fp, $test);
        fclose($fp);
    }
}

class Test2{
    var $test = "123";
    function __wakeup(){
        $obj = new Test1($this -> test);
    }
}

$test = $_GET['test'];
unserialize($test);

require "shell.php";
?>

4.PHP反序列化漏洞分析

1.出现的原因:
①unserialize()传入参数可控
②存在某些魔术方法可用
__construct()当一个对象创建时被调用
__destruct()当一个对象销毁时被调用
__toString()当一个对象被当作一个字符串时使用
__sleep() 在对象在被序列化之前运行
__wakeup() 如果有,在反序列化之前调用
③没有过滤或者过滤不完善
2.防御:
在反序列化函数内部添加正则过滤,以防构造payload进行攻击

5.补充

https://www.cnblogs.com/bmjoker/p/13742666.html
https://www.cnblogs.com/bmjoker/p/13831713.html

二、Java反序列化漏洞

1.引发

如果Java应用对用户输入,即不可信数据做了反序列化处理,那么攻击者可以通过构造恶意输入,让反序列化产生非预期的对象,非预期的对象在产生过程中就有可能带来任意代码执行。

2.原因

类ObjectInputStream在反序列化时,没有对生成的对象的输入做限制,使攻击者利用反射调用函数进行任意命令执行。CommonsCollections组件中对于集合的操作存在可以进行反射调用的方法

3.根源

Apache Commons Collections允许链式的任意的类函数反射调用
问题函数:org.apache.commons.collections.Transformer接口

学习资料

https://www.cnblogs.com/ssooking/p/5875215.html

三、反序列化漏洞的防御?

对于反序列化漏洞的防御,我们主要考虑两个方面:认证和检测。对于面向内部的接口和服务,我们可以采取认证的方式,杜绝它们被黑客利用的可能。另外,我们也需要对反序列化数据中的调用链进行黑白名单检测。成熟的第三方序列化插件都已经包含了这个功能,暂时可以不需要考虑。最后,如果没有过多的性能考量,我们可以通过 RASP 的方式,来进行一个更全面的检测和防护。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值