PHP反序列化漏洞总结

什么是序列化?

  • 序列化就是将对象转换为字符串,反序列化相反。序列化利于对象的保存和传输
serialize()             //序列化函数
unserialize()           //反序列化函数
  • 举个例子
<?php
    class test
    {
        public $name = 'tesName';
    }

    $o = new test();
    $s = serialize($o);
    echo $s;    //输出对象$o的序列化字符串
?>
  • O:4:"test":1:{s:4:"name";s:7:"tesName";}
  • O 代表这是一个对象,还有可能出现a,a表示为数组
  • 4 代表这个对象名长度为4
  • test 是对象名称
  • 1 表示这个对象的属性个数,这里为1
  • s 表示属性数据类型,s为string,i为int
  • name 表示属性名称
  • s:7:"tesName" 整个表示属性的值

漏洞原理

  • 未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致代码执行、SQL注入、目录遍历等不可控后果。在反序列化的过程中自动触发了某些魔术方法。当进行反序列化的时候就有可能会触发对象中的一些魔术方法。

触发条件

  1. unserialize()的参数可控,这样我们才能够构造特定的序列化字符串
  2. 文件中存在可利用的类,类中有魔术方法

PHP常见魔术方法

__construct()   //创建对象时触发
__destruct()    //对象被销毁时触发
__call()        //在对象中调用一个不可访问方法(经常是不存在的类)时触发
__get()         //读取不可访问属性的值时触发
__set()         //在给不可访问属性赋值时触发
__isset()       //当对不可访问属性调用 isset() 或 empty() 时触发
__unset()       //当对不可访问属性调用 unset() 时触发
__toString()    //当一个类被当成字符串时触发,echo或者拼接字符串时都会触发
__invoke()      //当尝试以调用函数的方式调用一个对象时触发
__sleep()       //执行serialize()时,先会调用这个函数
__wakeup()      //执行unserialize()时,先会调用这个函数

漏洞分类

无类问题

  • 无类指的是不调用类来利用反序列化漏洞,通常是对序列化后的字符串进行有关字符上的操作

有类问题

  • 有类指的是通过调用类中的魔术方法来利用反序列化漏洞,重点在于找到可利用的魔术方法(通常是好几个类的魔术方法构成一个利用链,和套娃差不多)

文章作者: MissPower007
文章链接: http://time.pings.fun
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 MissPower007 !
评论
  目录