反序列化漏洞

序列化与反序列

序列化:把对象转换为字节序列的过程称为对象的序列化

反序列化:把字节序列恢复为对象的过程称为对象的反序列化

漏洞成因及本质

成因:反序列化对象中存在魔术方法,而且魔术方法中的代码可以被控制,漏洞根据不同的代码可以导致各种攻击,如代码注入、SQL注入、目录遍历等等。

本质:unserialize函数的变量可控、php文件中存在可利用的类,类中有魔术方法。

魔术方法

魔术方法触发条件
__wakeup()使用unserialize时触发
__sleep()使用serialize时触发
__destruct()对象被销毁时触发
__call()在对象上下文中调用不可访问的方法时触发
__callStatic()在静态上下文中调用不可访问的方法时触发
__get()用于从不可访问的属性读取数据
__set()用于将数据写入不可访问的属性
__isset()在不可访问的属性上调用isset()或empty()触发
__unset()在不可访问的属性上使用unset()时触发
__toString()把类当作字符串使用时触发
__invoke()当脚本尝试将对象调用为函数时触发

代码展示

首先先展示序列化和反序列的原理,因为不同的变量属性序列化的结果也不尽相同。

<?php
	class test{
    private $test1 = "SQYY 2018";
/*    public $test2 = "<?php phpinfo();?>";*/
    public $test2 = "SQYY 2018";
    protected $test3 = "SQYY 2018";
}
$test = new test();
echo serialize($test);

在这里插入图片描述
这里解释一下,O表示有4个对象,一个test类,s代表字节数,有关序列化参数的可以参考以下链接
https://www.cnblogs.com/wayne173/p/3747465.html

接下来我们展示因为反序列化时参数可控引发的反序列化漏洞导致代码执行

<?php

class A{
    var $a = 'test';
    public function __destruct()
    {
        // TODO: Implement __destruct() method.
        $fp = fopen("C:\Program Files\PHPStudy\WWW\PHP\hello.php","w");
        fputs($fp,$this->a);
        fclose($fp);
    }
}
//$b = new A();
//echo serialize($b);
$object = unserialize($_POST['obj']);
require "C:\Program Files\PHPStudy\WWW\PHP\hello.php";

这是是将反序列化的结果存进一个hello.php的文件中,接下来我们展示攻击过程,可以看到上面的$object变量可控,因此我们改变序列化中对应参数的值,从而导致恶意代码的执行

首先我们先把序列化的结果打印输出,这里提示我们缺少了一个obj参数,这个是可控变量,等会儿通过POST方式传入
在这里插入图片描述
然后我们更改序列化参数的值,执行输出<?php phpinfo();?>这段恶意代码,因为这段代码总共包含18个字节,因此将s的值更改为18,代码执行成功
在这里插入图片描述

这里分享一个Freebuf大佬在CTF中遇见的PHP反序列化漏洞
https://www.freebuf.com/news/172507.html

总结:因为PHP反序列化漏洞是一个非常重要的漏洞之一,无论是在实战还是在比赛中,都是代码审计的热点漏洞,因此我们一定要熟练掌握这个漏洞的原理和攻击过程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

平凡的学者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值