diaoyudao 发表于 2017-12-31 08:35:46

PHP 中Session 反序列化机制的三种方法

  �php.ini中存在三项配置项:
  session.save_path="" --设置session的存储路径
  session.save_handler=""--设定用户自定义存储函数,如果想使用PHP内置会话存储机制之外的可以使用本函数(数据库等方式)
  session.auto_start boolen--指定会话模块是否在请求开始时启动一个会话默认为0不启动
  session.serialize_handler string--定义用来序列化/反序列化的处理器名字。默认使用php
  以上的选项就是与PHP中的Session存储和序列话存储有关的选项。
  在使用xampp组件安装中,上述的配置项的设置如下:
  session.save_path="D:\xampp\tmp"表明所有的session文件都是存储在xampp/tmp下
  session.save_handler=files 表明session是以文件的方式来进行存储的
  session.auto_start=0表明默认不启动session
  session.serialize_handler=php 表明session的默认序列话引擎使用的是php序列话引擎
  在上述的配置中,session.serialize_handler是用来设置session的序列话引擎的,除了默认的PHP引擎之外,还存在其他引擎,不同的引擎所对应的session的存储方式不相同。
  php_binary:存储方式是,键名的长度对应的ASCII字符+键名+经过serialize函数序列化处理的值
  php:存储方式是,键名+竖线+经过serialize函数序列处理的值
  php_serialize(php>5.5.4):存储方式是,经过serialize函数序列化处理的值
  在PHP中默认使用的是PHP引擎,如果要修改为其他的引擎,只需要添加代码ini_set('session.serialize_handler', '需要设置的引擎');。示例代码如下:
  <?php
  ini_set(&apos;session.serialize_handler&apos;&apos;php_serialize&apos;);
  session_start;
  // do something
  存储机制
  php中的session中的内容并不是放在内存中的,而是以文件的方式来存储的,存储方式就是由配置项session.save_handler来进行确定的,默认是以文件的方式存储。
  存储的文件是以sess_sessionid来进行命名的,文件的内容就是session值的序列话之后的内容。
  假设我们的环境是xampp,那么默认配置如上所述。
  在默认配置情况下:
  <?php
  session_start
  $_SESSION[&apos;name&apos;]=&apos;spoock&apos;;
  var_dump;
  ?>
  最后的session的存储和显示如下:
  可以看到PHPSESSID的值是jo86ud4jfvu81mbg28sl2s56c2,而在xampp/tmp下存储的文件名是sess_jo86ud4jfvu81mbg28sl2s56c2,文件的内容是name|s:6:"spoock";。name是键值,s:6:"spoock";是serialize("spoock")的结果。
  在php_serialize引擎下:
  <?php
  ini_set(&apos;session.serialize_handler&apos;&apos;php_serialize&apos;);
  session_start;
  $_SESSION[&apos;name&apos;]=&apos;spoock&apos;;
  var_dump;
  ?>
  SESSION文件的内容是a:1:{s:4:"name";s:6:"spoock";}。a:1是使用php_serialize进行序列话都会加上。同时使用php_serialize会将session中的key和value都会进行序列化。
  在php_binary引擎下:
  <?php
  ini_set(&apos;session.serialize_handler&apos;&apos;php_binary&apos;);
  session_start;
  $_SESSION[&apos;name&apos;]=&apos;spoock&apos;;
  var_dump;
  ?>
  SESSION文件的内容是names:6:"spoock";。由于name的长度是4,4在ASCII表中对应的就是EOT。根据php_binary的存储规则,最后就是names:6:"spoock";。(突然发现ASCII的值为4的字符无法在网页上面显示,这个大家自行去查ASCII表吧)
  序列化简单利用
  test.php
  <?php
  classsyclover{
  var$func="";
  function__construct{
  $this->func="phpinfo";
  }
  function__wakeup{
  eval($this->func);
  }
  }
  unserialize($_GET[&apos;a&apos;]);
  ?>
  在11行对传入的参数进行了序列化。我们可以通过传入一个特定的字符串,反序列化为syclover的一个示例,那么就可以执行eval方法。我们访问localhost/test.php?a=O:8:"syclover":1:{s:4:"func";s:14:"echo "spoock";";}。那么反序列化得到的内容是:
  object(syclover)
  public&apos;func&apos;=>string&apos;echo "spoock";&apos;(length=14)
  最后页面输出的就是spoock,说明最后执行了我们定义的echo "spoock";方法。
  这就是一个简单的序列化的漏洞的演示
  PHP Session中的序列化危害
  PHP中的Session的实现是没有的问题,危害主要是由于程序员的Session使用不当而引起的。
  如果在PHP在反序列化存储的$_SESSION数据时使用的引擎和序列化使用的引擎不一样,会导致数据无法正确第反序列化。通过精心构造的数据包,就可以绕过程序的验证或者是执行一些系统的方法。例如:
  $_SESSION[&apos;ryat&apos;]=&apos;|O:11:"PeopleClass":0:{}&apos;;
  上述的$_SESSION的数据使用php_serialize,那么最后的存储的内容就是a:1:{s:6:"spoock";s:24:"|O:11:"PeopleClass":0:{}";}。
  但是我们在进行读取的时候,选择的是php,那么最后读取的内容是:
  array(size=1)
  &apos;a:1:{s:6:"spoock";s:24:"&apos;=>
  object(__PHP_Incomplete_Class)

  There are multiple header layouts available that allow you to utilize background images, office locations and hours and social media links. Multi-lingual sites even have the ability to add a language drop down menu. On a>  WordPress Customizer
  Consulting WP is compatible with the WordPress Customizer, which you can use to preview changes to the theme’s options in real-time.
  Create Your Own Layouts
  With the included Visual Composer page builder plugin, you can create your own complex page layouts without having to touch code.
  Features that Work for Business
页: [1]
查看完整版本: PHP 中Session 反序列化机制的三种方法