序列化

在PHP中,序列化用于存储或传递 PHP 的值的过程中,同时不丢失其类型和结构。

序列化函数:

string serialize ( mixed $value )

说明:

返回对象的字符串表示。

返回值:

返回对象的字符串表示或者 NULL 。

参数:

任意类型。

对象的序列化

注意:序列化担当着对象析构器的角色。在此方法之后,__destruct() 方法将不会被调用。

<?php
class aa{
    public $a;
    public $b;
    public function __construct()
    {
        # 构造函数
        $this->a='hello';
        $this->b='world';
    }
}
$obj = new aa;
$str=serialize($obj);
var_dump($str);
?>

输出结果:

string(53) "O:2:"aa":2:{s:1:"a";s:5:"hello";s:1:"b";s:5:"world";}" 

解释:
string(53):指序列化后的字符类型为字符串长度为53。

 O:strlen(object name):object name:object size:{s:strlen(property name):property name:property definition;(repeated per property)}

数组的序列化

<?php
$a=array('aaaa',100,2.5,true);
$str=serialize($a);
var_dump($str);
?>

输出结果:

string(49) "a:4:{i:0;s:4:"aaaa";i:1;i:100;i:2;d:2.5;i:3;b:1;}" 

解释:

a:size:{key 类型:key长度:key的值;value类型:value长度:value的值;(repeated per element)}
默认int,double,bool不显示长度

字符串的反序列化

<?php
$a='asdf';
$str=serialize($a);
var_dump($str);
?>

输出结果:

string(11) "s:4:"asdf";" 

解释:

s:size:value;

数字的序列化

<?php
$a=6;
$b=6.6;
$str1=serialize($a);
$str2=serialize($b);
var_dump($str1);
echo "<br>";
var_dump($str2);
?>

输出结果:

string(4) "i:6;"
string(21) "d:6.5999999999999996;" 

解释:

 i:value;
 d:value;

这里至于为什么是6.5999999999999996,我也不知道。

布尔和NULL的序列化

<?php
$a=false;
$b=NULL;
$str1=serialize($a);
$str2=serialize($b);
var_dump($str1);
echo "<br>";
var_dump($str2);
?>

输出结果:

string(4) "b:0;"
string(2) "N;" 

解释:

b:value;(保存10)
N;

反序列化

反序列化函数:

mixed unserialize ( string $str )

unserialize()反序列化函数用于将单一的已序列化的变量转换回序列化之前的值。

参数:

对象的字符串表示。

返回值:

返回没有序列化之前的原始值。

对象的反序列化

<?php
class aa{
    public $a;
    public $b;
    public function __construct()
    {
        # 构造函数
        $this->a='hello';
        $this->b='world';
    }
    public function __toString(){
        #对象以字符串形式输出时自动调用
        echo '调用了__toString()函数';
        return $this->a;
    }
}
// $obj = new aa;
// $str=serialize($obj);
// var_dump($str);
$str='O:2:"aa":2:{s:1:"a";s:5:"hello";s:1:"b";s:5:"world";}';
$obj=unserialize($str);
var_dump($obj);
echo "<br>";
echo $obj;
?>

输出结果:

object(aa)#2 (2) { ["a"]=> string(5) "hello" ["b"]=> string(5) "world" }
调用了__toString()函数hello 

解释:
object(aa):指反序列化后的值为对象,类名为aa。

注意:这里生成了一个对象但没有调用构造函数

这里我们可以改变里面的变量值:

<?php
class aa{
    public $a;
    public $b;
    public function __construct()
    {
        # 构造函数
        $this->a='hello';
        $this->b='world';
    }
    public function __toString(){
        echo '调用了__toString()函数';
        return $this->a;
    }
}
// $obj = new aa;
// $str=serialize($obj);
// var_dump($str);
$str='O:2:"aa":2:{s:1:"a";s:3:"asd";s:1:"b";s:5:"world";}';
$obj=unserialize($str);
var_dump($obj);
echo "<br>";
echo $obj;
?>

输出结果:

object(aa)#2 (2) { ["a"]=> string(3) "asd" ["b"]=> string(5) "world" }
调用了__toString()函数asd 

说明我们已经改变啦变量a的值。所以这里存在漏洞。

数组的反序列化

<?php
// $a=array('a'=>'aaaa',100,2.5,true);
// $str=serialize($a);
// var_dump($str);
$b='a:4:{s:1:"a";s:4:"aaaa";i:0;i:100;i:1;d:2.5;i:2;b:1;}';
$arr=unserialize($b);
echo "<pre>";
print_r($arr);
echo "</pre>";
?>

输出结果:

Array
(
    [a] => aaaa
    [0] => 100
    [1] => 2.5
    [2] => 1
)

解释:
如果bool类型的值在转化回数组的过程中1转换为1,0转换为空。

字符串反序列化

<?php
// $a='asdf';
// $str=serialize($a);
// var_dump($str);
$b='s:4:"asdf";';
$str=unserialize($b);
echo $str;
?>

输出结果:

asdf

数字的反序列化

<?php
// $a=6;
// $b=6.6;
// $str1=serialize($a);
// $str2=serialize($b);
// var_dump($str1);
// echo "<br>";
// var_dump($str2);
$a='i:6;';
$b='d:6.5999999999999996;';
$str1=unserialize($a);
$str2=unserialize($b);
var_dump($str1);
echo "<br>";
var_dump($str2);
?>

输出结果:

int(6)
float(6.6) 

发现:小数点后有14位时开始对十分位四舍五入。

布尔值和NULL的反序列化

<?php
// $a=false;
// $b=NULL;
// $str1=serialize($a);
// $str2=serialize($b);
// var_dump($str1);
// echo "<br>";
// var_dump($str2);
$a='b:0;';
$b='N;';
$str1=unserialize($a);
$str2=unserialize($b);
var_dump($str1);
echo "<br>";
var_dump($str2);
?>

输出结果:

bool(false)
NULL 

总结

序列化和反序列化是个很神奇的东西。需要多多了解和掌握。

如有不足请指出。

  • phpinfo中的敏感信息

    phpinfo的基本信息服务器系统:详细的操作系统信息,为提权做准备 extension_dirphp扩展的路径: 真实ip:或web根目录配置文件位置(php.ini): 重要配置allow_url_include 远程文件包含,但...

    phpinfo中的敏感信息
  • linux三剑客

    前言之前用一些脚本都经常用到grep,sed,awk。但是一直不太熟悉,今天来学习一下,做个备忘录。 grep格式: grep [OPTIONS] PATTERN [FILE...] grep [OPTIONS] [-e PATTER...

    linux三剑客
  • i春秋2020新春战“疫”网络安全公益赛 web Writeup

    前言这次比赛题目质量挺好的,除啦环境可能有时候有点问题。(就让我遇到了。心态炸了一天。。。)其他都挺好的。 DAY1简单的招聘系统知识点:sql注入的联合注入或盲注存在注册和登陆功能,首先进行注册后登陆进系统,发现有一个模块是管理员才...

    i春秋2020新春战“疫”网络安全公益赛 web Writeup
  • 计算机组成原理学习

    计算机组成原理第一章 计算机系统概论计算机系统的层次结构 冯·诺依曼计算机的特点 计算机由运算器、存储器、控制器、输入设备和输出设备五大部件组成 指令(程序)和数据以二进制同等地位地存储在存储器中,可按址寻访 指令由操作码和地址码组...

    计算机组成原理学习
  • 2019安洵杯+2019广外比赛web部分题解

    2019安洵杯easy_web知识点:MD5强碰撞,命令执行这个题比较简单,看题目发现传入参数img和cmd,然而图片是传入的img参数控制,让我想到ddctf的一道题,然后发现img是通过把文件名进行转十六进制后两次base64编码...

    2019安洵杯+2019广外比赛web部分题解
  • bypass disfunction

    前言PHP 的 disabled_functions主要是用于禁用一些危险的函数防止攻击者执行系统命令。但是有一些绕过方法。这里做个总结。 基本思路有四种绕过 disable_functions 的手法:第一种,攻击后端组件,寻找存在...

    bypass disfunction
  • 2019极客大挑战RCE ME

    题目环境:http://114.116.44.23:40001/ 题目还是老样子。无字母数字rce。知识点其实都有写过,就不说了。详细参见:【RCE提高篇】题目源码: <?php ini_set("display_errors"...

    2019极客大挑战RCE ME
  • RCE提高篇

    前言首先,需要了解一下命令执行的函数,这里推荐几篇文章,来认识这些函数。浅谈eval和assert从底层分析eval和assert的区别命令执行与代码执行的小结巧用命令注入的N种方式命令注入绕过姿势我就不在说这几个东西,大牛们都说的很...

    RCE提高篇
  • buuctf刷题记录(序)

    love math知识点:代码审计,绕waf直接给出源码: <?php error_reporting(0); //听说你很喜欢数学,不知道你是否爱它胜过爱flag if(!isset($_GET['c'])){ sho...

    buuctf刷题记录(序)
  • phar拓展反序列化攻击面

    pharphar扩展提供了一种将整个php应用程序放入名为“phar”(php archive)的单个文件中的方法,以便于分发和安装。除了提供这个服务之外,phar扩展还提供了一个文件格式抽象方法,用于通过phardata类创建和操作...

    phar拓展反序列化攻击面