* 最近再次遇见了反序列化漏洞,感觉还是很有意思,就又又又学习了一下。😅
PHP对象序列化 (手册 )
序列化(serialize()) 对象->字符串
反序列化(unserialize()) 字符串->对象
反序列化漏洞
序列化与反序列化本身没有漏洞,触发漏洞的点如下:
1 2 反序列化函数 unserialize() 中存在可控参数 魔术方法中有敏感操作
魔术方法
php中的魔术方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 函数名 函数作用 __construct() 类的构造函数 __destruct() 类的析构函数 __call() 在对象中调用一个不可访问方法时调用 __callStatic() 用静态方式中调用一个不可访问方法时调用 __get() 获得一个类的成员变量时调用 __set() 设置一个类的成员变量时调用 __isset() 当对不可访问属性调用isset()或empty()时调用 __unset() 当对不可访问属性调用unset()时被调用 __sleep() 执行serialize()时,先会调用这个函数 __wakeup() 执行unserialize()时,先会调用这个函数 __toString() 类被当成字符串时的回应方法 __invoke() 调用函数的方式调用一个对象时的回应方法 __set_state() 调用var_export()导出类时,此静态方法会被调用 __clone() 当对象复制完成时调用 __debugInfo() 当调用var_dump()打印对象时被调用(当你不想打印所有属性)适用于PHP5.6版本
示例
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 <?php class test { public $nae; public function __construct () { echo '__construct is ok' ; echo '<br/>' ; } public function __call ($name,$arguments) { echo '__call is ok' ; echo '<br/>' ; } public static function __callStatic ($name, $arguments) { echo '__callStatic is ok' ; echo '<br/>' ; } public function __get ($name) { echo '__get is ok' ; echo '<br/>' ; } public function __set ($name,$value) { echo '__set is ok' ; echo '<br/>' ; } public function __isset ($name) { echo '__isset is ok' ; echo '<br/>' ; } public function __unset ($name) { echo '__unset is ok' ; echo '<br/>' ; } public function __sleep () { echo '__sleep is ok' ; echo '<br/>' ; return array ('nae' ); } public function __wakeup () { echo '__wakeup is ok' ; echo '<br/>' ; } public function __toString () { echo '__toString is ok' ; echo '<br/>' ; return '111<br/>' ; } public function __invoke () { echo '__invoke is ok' ; echo '<br/>' ; } public static function __set_state ($arr) { return '__set_state is ok' ; } public function __clone () { echo '__clone is ok' ; echo '<br/>' ; } public function __destruct () { echo '__destruct is ok' ; echo '<br/>' ; } public function __debugInfo () { echo '__debugInfo is ok' ; echo '<br/>' ; } }
执行语句:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 $a=new test(); $a->xvalue='test' ; $a->nofun(); echo $a->xvalue;isset ($a->xvalue);unset ($a->xvalue);$a(); $a::nofo(); $a1 = clone $a; $c=serialize($a); echo $a;eval ( '$a2 = ' . var_export ( $a , true ) . ';' );var_dump($a2);echo '<br/>' ;unserialize($c); var_dump($a);
结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 __construct is ok __set is ok __call is ok __get is ok __isset is ok __unset is ok __invoke is ok __callStatic is ok __clone is ok __sleep is ok __toString is ok 111 C:\phpStudy\WWW\test2.php:91 :string '__set_state is ok' (length=17 ) __wakeup is ok __destruct is ok __debugInfo is ok C:\phpStudy\WWW\test2.php:96 : object(test)[1 ] __destruct is ok __destruct is ok