提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
序列化即将对象转化为字节流,便于保存在文件,内存,数据库中;反序列化即将字节流转化为对象。也就是说,把数据转化为一种可逆的数据结构,再把这种可逆的数据结构转化回数据,这就是序列化与反序列化。
比如,买一个柜子,从北京运到上海,由于柜子形状怪异,不方便运输,先把它拆成板子,再装到箱子里(序列化),顺丰邮到买家手里,把板子拼装回柜子(反序列化)。
①反序列化漏洞的产生原理,即黑客通过构造恶意的序列化数据,从而控制应用在反序列化过程中需要调用的类方法,最终实现任意方法调用。如果在这些方法中有命令执行的方法,黑客就可以在服务器上执行任意的命令。
②各种语言都有反序列化漏洞。
①大型网站中类创建的对象多的时候会占用大量的空间
②部分配置文件通过序列化进行文件存储或者传递,然后再进行对象化会比较方便,一次采用序列化存储数据。
①.serialize()
当在PHP中创建了一个对象后,可以通过serialize()把这个对象转变成一个字符串,保存对象的值之后方便之后的传递与使用
②.unserialize()
与serialize()对应,unserialize()可以从已存储的表示中创建PHP的值,可以从序列化后的结果中恢复对象(object)
例如:
$a = array('a' => 'Apple' ,'b' => 'banana' , 'c' => 'Coconut');
//序列化数组
$s = serialize($a);
echo "序列化:",$s,"
";
//反序列化数组
$aa = unserialize($s);
echo "反序列化:",$aa,"
";
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;以此类推}
①存在文件1.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 "
";
$seri = unserialize($test1);//反序列化参数
require "test.php"; //运行写入的文件
?>
②构造payload
一个Test类,有一个test参数,test="":
O:4:"Test":1:{
s:4:"test";s:18:"";}
③打开php页面时在地址栏传入参数:
1.php?test=O:4:"Test":1:{
s:4:"test";s:18:"";}
可以创建一个test.php文件,并把Test类中的test变量的值即"" 写进了test.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";
?>
1.出现的原因:
①unserialize()传入参数可控
②存在某些魔术方法可用
__construct()当一个对象创建时被调用
__destruct()当一个对象销毁时被调用
__toString()当一个对象被当作一个字符串时使用
__sleep() 在对象在被序列化之前运行
__wakeup() 如果有,在反序列化之前调用
③没有过滤或者过滤不完善
2.防御:
在反序列化函数内部添加正则过滤,以防构造payload进行攻击
https://www.cnblogs.com/bmjoker/p/13742666.html
https://www.cnblogs.com/bmjoker/p/13831713.html
如果Java应用对用户输入,即不可信数据做了反序列化处理,那么攻击者可以通过构造恶意输入,让反序列化产生非预期的对象,非预期的对象在产生过程中就有可能带来任意代码执行。
类ObjectInputStream在反序列化时,没有对生成的对象的输入做限制,使攻击者利用反射调用函数进行任意命令执行。CommonsCollections组件中对于集合的操作存在可以进行反射调用的方法
Apache Commons Collections允许链式的任意的类函数反射调用
问题函数:org.apache.commons.collections.Transformer接口
https://www.cnblogs.com/ssooking/p/5875215.html
对于反序列化漏洞的防御,我们主要考虑两个方面:认证和检测。对于面向内部的接口和服务,我们可以采取认证的方式,杜绝它们被黑客利用的可能。另外,我们也需要对反序列化数据中的调用链进行黑白名单检测。成熟的第三方序列化插件都已经包含了这个功能,暂时可以不需要考虑。最后,如果没有过多的性能考量,我们可以通过 RASP 的方式,来进行一个更全面的检测和防护。