php反序列化总结

    xiaoxiao2023-11-27  151

    反序列化漏洞黑盒很难发现,即使发现了也好难利用。不过危害很大。 序列化使用函数serialize()来返回一个包含字节流的字符串来表示。unserialize()函数能够重新把字符串变回php原来的值。 序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字。 序列化结果

    string(5) "i:34;" //number string(13) "s:6:"uusama";" //str string(4) "b:1;" //bool string(2) "N;" //null string(30) "a:2:{s:1:"a";i:1;s:1:"b";i:2;}" //array('a' => 1, 'b' => 2); string(52) "O:2:"CC":2:{s:4:"data";s:2:"uu";s:8:" CC pass";b:1;}" //new CC('uu', true);

    几个相关的魔术方法:

    __wakeup() //使用unserialize时触发 __sleep() //使用serialize时触发 该方法挑选一些特定的变量名称进行下一步序列化,而不是使用类中所有变量进行序列化 __destruct() //对象被销毁时触发 __call() //在对象上下文中调用不可访问的方法时触发 __callStatic() //在静态上下文中调用不可访问的方法时触发 __get() //用于从不可访问的属性读取数据 __set() //用于将数据写入不可访问的属性 __isset() //在不可访问的属性上调用isset()或empty()触发 __unset() //在不可访问的属性上使用unset()时触发 __toString() //把类当作字符串使用时触发,返回值需要为字符串 __invoke() //当脚本尝试将对象调用为函数时触发

    PHP预定义序列化接口Serializable https://stitcher.io/blog/new-in-php-74 反序列化漏洞举例:

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

    变量$a从url中test参数获取到内容,并且在反序列化的时候通过__destruct()直接将传入的数据不经过任何处理,echo出来,这里就存在反射型xss漏洞了。 当脚本结束运行时,所有的对象都会销毁,就会自动调用__destruct方法。要关注__wakeup和__destruct,追踪是否存在可利用的函数。 高危函数:

    exec() passthru() popen() system() file_put_contents() file_get_contents() unlink() 。。。

    PHP的 unserialize() 函数只能反序列化在当前程序上下文中已经被定义过的类.在传统的PHP中你需要通过使用一大串的include() 或者 require()来包含所需的类定义文件。于是后来出现了 autoloading 技术,他可以自动导入需要使用的类,再也不需要程序员不断地复制粘贴 那些include代码了。这种技术同时也方便了我们的漏洞利用.因为在我们找到一个反序列化点的时候我们所能使用的类就多了,那么实现漏洞利用的可能性也就更加高。

    还有一个东西要提一下,那就是Composer,这是一个php的包管理工具,同时他还能自动导入所以依赖库中定义的类。这样一来 unserialize() 函数也就能使用所有依赖库中的类了,攻击面又增大不少。

    1.Composer配置的依赖库存储在vendor目录下

    2.如果要使用Composer的自动类加载机制,只需要在php文件的开头加上

    require __DIR__ . '/vendor/autoload.php';

    参考: https://www.cnblogs.com/youyoui/p/8610068.html https://blog.csdn.net/qq_33020901/article/details/80743728

    RFC for a Secure Unserialization Mechanism in PHP https://wiki.php.net/rfc/custom_object_serialization

    最新回复(0)