值得一看
正规流量卡

PHP反序列化漏洞说明

------正文内容展示,开始汲取新知识啦------

接上述栗子:

<?php
class Test{
         public $a = 'ThisA';
         protected $b = 'ThisB';
         private $c = 'ThisC';
         public function test(){
                  return'this is test';
         }
}
$test = new Test();
$sTest = serialize($test);
$usTest = unserialize($sTest);
var_dump($usTest);
?>

输出结果:

object(Test)#2 (3) { 
    ["a"]=> string(5) "ThisA" 
    ["b":protected]=> string(5) "ThisB" 
    ["c":"Test":private]=> string(5) "ThisC" 
}

序列化和反序列化的原理其实很简单,序列化给我们传递对象提供了一种简单的方法,serialize()将一个对象转换成一个字符串,unserialize()将字符串还原为一个对象,与Java的 writeObjectreadObject,其原理基本一致。

PHP应用中,序列化和反序列化一般用做缓存,比如session缓存,cookie等。

从以上栗子来看似乎没有问题,那么反序列化漏洞是如何形成的呢?

这就要引入PHP里面魔术方法的概念了。

魔术方法

反序列化漏洞的形成通常和以下魔术方法有关:

__construct()    #类似C构造函数,当一个对象创建时被调用,但在unserialize()时是不会自动调用的
__destruct()    #类似C析构函数,当一个对象销毁时被调用
__toString()    #当一个对象被当作一个字符串使用时被调用
__sleep()       #serialize()时会自动调用   
__wakeup()      #unserialize()时会自动调用   
__call()        #当调用对象中不存在的方法会自动调用该方法。
__get()         #在调用私有属性的时候会自动执行
__isset()       #在不可访问的属性上调用isset()或empty()触发
__unset()       #在不可访问的属性上使用unset()时触发

由前面可以看出,当传给 unserialize() 的参数可控时,我们可以通过传入一个精心构造的序列化字符串,从而控制对象内部的变量甚至是函数。

利用__destruct

<?php
class test{
    var $test = "hello";
    function __destruct(){
            echo $this->test;
    }
}
$a = $_GET['id'];
$a_u = unserialize($a);
?>

构造payload如下:

127.0.0.1/Unserialize/test.php
?id=O:4:"test":1:{s:4:"test";s:40:"<script>alert(/you are hacked/)</script>";}

1 2 3 4 5 6 7

------本页内容已结束,喜欢请分享------

感谢您的来访,获取更多精彩文章请收藏本站。

© 版权声明
THE END
喜欢就支持一下吧
点赞1633赞赏 分享
抢沙发

请登录后发表评论

    暂无评论内容