当前位置: 首页 > news >正文

[CISCN2019 总决赛 Day1 Web4]Laravel1

1.打开是一个反序列化的入口

<?php //backup in source.tar.gz namespace App\Http\Controllers; class IndexController extends Controller { public function index(\Illuminate\Http\Request $request){ $payload=$request->input("payload"); if(empty($payload)){ highlight_file(__FILE__); }else{ @unserialize($payload); } } }

首先是使用namespace导入一个命名空间,后面是他的路径 App\Http\Controllers

定义一个名为IndexController的类,它是继承Controller类的

定义一个公共的index方法,里面是Laravel路由默认调用的动作,参数\Illuminate\Http\Request $request ,使用完整命名空间\Illuminate\Http\Request,明确指定 类型。$request是Laravel封装的HTTP请求对象,用于获取用户传入的数据,如POST/GET参数,触发了会获取请求中名为payload的参数值支持POST、GET、JSON body等多种方式传参,然后赋值给$payload,然后if判断$payload是否为空,如果为空就高亮显示当前文件,否的话对他进行反序列化的操作,还提示了源码的位置source.tar.gz,下载下来分析源码

2.分析源码

他这是个Laravel框架的源码

头一次审框架的反序列化,有点看不懂,就按照wp的步骤来做一些这题

第一步:

首先先找function __destruct()方法,因为在unserialize的时候会触发他,也是链子的启动部分

phpstorm中英文状态 ctrl+shift+f搜索 一下function __destruct()

在TagAwareAdapter.php中发现了一个可以调用方法的地方,追进看看

agAwareAdapter.php文件部分代码

public function commit() { return $this->invalidateTags([]); } public function __destruct() { $this->commit(); }

首先destruct方法触发了会调用本类的commit方法,上面是commit方法,触发了会返回本类的invalidateTags方法,参数为一个数组 ,向上找,找invalidateTags方法

public function invalidateTags(array $tags) { $ok = true; $tagsByKey = []; $invalidatedTags = []; foreach ($tags as $tag) { CacheItem::validateKey($tag); $invalidatedTags[$tag] = 0; } if ($this->deferred) { $items = $this->deferred; foreach ($items as $key => $item) { if (!$this->pool->saveDeferred($item)) { unset($this->deferred[$key]); $ok = false; } }

首先将$ok设置为true,然后设置$tagsByKey为空数组,还有一个$invalidatedTags为空数组,然后循环遍历将$tags的值 遍历到$tag中,然后调用CacheItem类中的validateKey方法,里面的参数为$tag,然后下面是一个$invalidatedTags参数,他的索引值为$tag,赋值为0

if语句这个是关键代码,他首先判断本类的deferred属性是否存在,如果存在,就将他的值赋值给$items,然后使用循环遍历,给$items转换成键值对的形式,又是一个if语句,如果$this->pool对象没有saveDeferred方法,就unset销毁本类的 deferred属性,然后将$ok设置为false

第二步:

看到invalidateTags方法中的这个$this->pool->saveDeferred($item),可以$this->pool可以修改然后就能任意调用类调用saveDeferred方法

但是在他的construct方法中又要求了他带是AdapterInterface接口的

class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterface, PruneableInterface, ResettableInterface

全局搜索一下saveDeferred方法,需要是AdapterInterface接口的

在PhpArrayAdapter.php文件中 找到一个saveDeferred方法,追进 看看

public function saveDeferred(CacheItemInterface $item) { if (null === $this->values) { $this->initialize(); } return !isset($this->keys[$item->getKey()]) && $this->pool->saveDeferred($item); }

一个公共的saveDeferred方法,里面参数为CacheItemInterface $item, CacheItemInterface是一个接口,然后$item是个参数,只允许这个接口的对象来填入,就相当于$item是个坑位,而这个坑位指定了只能由符合CacheItemInterface要求的对象来填入,触发了是一个if语句,需要让本类的values属性强等于为空,那么就会调用本类的initialize方法,又是一环,接下来寻找initialize方法,但是这个方法本类中没有定义,而因为trait这个关键词修饰的类中trait PhpArrayTrait

trait这个关键词是php为了解决单继承的问题而特意建立的,在java这种面向对象的语言中,继承都是单继承的,一个类只能继承一个父类,从下面这副流程图中可以看到PhpArrayAdapter这个类的继承关系

既然这里没有肯定到他的父类中寻找,到父类中搜索initialize方法

PhpArrayTrait.php

private function initialize() { if (!file_exists($this->file)) { $this->keys = $this->values = []; return; } $values = (include $this->file) ?: [[], []]; if (2 !== \count($values) || !isset($values[0], $values[1])) { $this->keys = $this->values = []; } else { list($this->keys, $this->values) = $values; } }

他是一个私有属性,触发了有一个if语句 ,判断本类的file属性是否存在这个文件,如果不存在,就将空数组赋值给本类的values属性,在赋值给本类的keys属性,然后返回为空,if语句外是一个三元运算符的简写,如果include包含$this->file文件不成功,就返回[[],[]],这里也是最后的结尾,可以进行一个文件包含

捋一下思路

首先是搜索 destruct方法,因为unserialize会触发他,

此时是在这个命名空间namespace Symfony\Component\Cache\Adapter的TagAwareAdapter.php文件下

然后destruct方法触发 会调用本类的commit方法,到了commit方法,会返回调用本类的invalidateTags()方法,然后到了本类的invalidateTags()方法中 ,首先判断本类的deferred属性不能为空,并且是个数组,因为后面会循环遍历成键值对形式,接下来就是控制$this->pool的值,来让他调用对应类中的saveDeferred方法了

此时还是在namespace Symfony\Component\Cache\Adapter命名空间中

接下来就找saveDeferred方法到PhpArrayAdapter.php文件中了,调用了saveDeferred方法触发了会有一个if语句 ,判断本类values属性是否为空,不为空,就调用本类的initialize方法,因为他本类中没有调用,而是根据trait这个关键词修饰的类中的trait PhpArrayTrait,在他的父类PhpArrayTrait中寻找 ,找到了发现他可以对本类的file属性进行一个文件包含就此到达终点,因为看wp了所以知道flag在/flag文件中,所以file的值就为/flag了

3.开始构造

那么跟着上面的思路来进行构造payload

调用链:

TagAwareAdapter :: destruct --> TagAwareAdapter :: commit --> TagAwareAdapter :: invalidateTags --> PhpArrayAdapter::saveDeferred --> PhpArrayTrait::initialize (include文件包含成功)

关键点就是$this->poo成为PhpArrayAdapter对象,然后会触发saveDeferred方法,然后转到PhpArrayTrait.php,的initialize方法的include成功执行

分析下exp的中的命名空间意思,首先第一个命名空间Symfony\Component\Cache,涉及的是CacheItem类,为了填充deferred数组,骗过类型检查, Symfony\Component\Cache\Adapter 涉及的TagAwareAdapter和PhpArrayAdapter类,他俩的命名空间要对应上

然后生成的GET传参上去,得到flag

4.知识点

这题其实链子不是特别难,跟着wp也挺好捋清楚的,主要就是命名空间的问题,好绕

PHP命名空间(namespace)是一种机制,用于将代码封装在一个逻辑单元中,从而避免不同代码段之间的命名冲突。简单来说,命名空间就像一个"容器",它可以包含类、函数和常量等元素。通过使用命名空间,我们可以为这些元素提供一个唯一的标识符,即使他们的名字相同也不会冲突

命名空间其实就像我们平时使用的绝对路径一样,只不过是在类名前面加了一个斜杠\,这就叫完全限定名称,不管你当前身处哪个命名空间,只要从\开始写,php就会从最顶层开始找

基本语法

在php中,使用namespace关键字来定义命名空间。命名空间可以嵌套,形成多级结构。

use也可以说是引用吧,就是每次如果不使用use,没使用一个类就要写他的完全限定名称,代码会变的非常 冗长,使用了之后就直接可以进行简写了

还有就是编译代码的时候起作用,告诉PHP编译器,只要看到Profile这个词就把他当成

useApp\Modules\User\Member\Profile,还可以使用as来对他进行一个改名字

implements是接口的关键词,就算是一个规范,接口定义了一组方法名,但没有具体内容。当一个类implements实现了这个接口,他就必需完成接口里所要求的所有任务

简介一下,抽空好好学习一下这个

参考链接:

https://blog.csdn.net/zhaoxilengfeng/article/details/144274431

https://www.runoob.com/php/php-namespace.html

wp:

https://blog.csdn.net/cjdgg/article/details/114873555

https://xz.aliyun.com/news/5429#toc-3

https://cn-sec.com/archives/942151.html

https://syunaht.com/p/3199619840.html

https://mixbp.github.io/2025/05/29/CISCN2019%E6%80%BB%E5%86%B3%E8%B5%9BDay1Web4-Laravel1/

http://www.cnnetsun.cn/news/191615.html

相关文章:

  • sprintf 和 printf
  • 毕业季必看!9个AI写论文神器,1天生成25000字含真实参考文献
  • 【国产 OS 顶流实战】KylinOS V10 等保 2.0 三级合规 + MES 系统国产化迁移全案
  • Java基于springboot+vue的毕业生离校管理系统的设计与实现
  • 【毕业设计】基于springboot的旧物回收商城系统的设计与实现(源码+文档+远程调试,全bao定制等)
  • OpenMV中HOG特征提取全面讲解
  • 8个AI论文生成平台测评,降重与写作功能深度解析
  • 8个AI论文改写工具评测,降重与写作功能全面分析
  • Elasticsearch基本用法项目应用:分页与高亮处理
  • 基于proteus的4位数码管动态扫描实战案例
  • 全面讲解ESP32开发核心外设:GPIO控制基础教学
  • PaperzzAI PPT:别再熬夜做PPT了,让AI给你“一键生成高光时刻”——不是模板搬运工,是你的视觉导演+内容编剧
  • 图解说明Vitis使用教程:适合初学者的界面功能解析
  • 具身智能重构体验!CES Asia 2026:消费电子从“工具”变身“主动伙伴”
  • STM32-时钟树编程
  • Packet Tracer使用教程:OSPF基础配置图解说明
  • 批量部署USB转串口驱动的企业级Windows策略应用
  • 赋能成长型企业:SAP Business One与奥维奥的数字化共赢之道
  • 一文说清同步整流buck电路图及其工作原理
  • Packet Tracer下载步骤详解:适合初学者的系统学习
  • 2025年AI论文写作平台精选,集成LaTeX支持与智能格式检查
  • Hotkey Detective终极指南:3步解决Windows热键冲突难题
  • 【Mol Plant综述精读】植物中的染色质重塑:复合物组成、机制多样性及生物学功能
  • 基于GA-HIDMSPSO算法优化BP神经网络+NSGAII多目标优化算法工艺参数优化、工程设计优化(四目标优化案例)
  • 系统学习erase前必须知道的存储基础知识
  • 通俗解释定制ROM在2025机顶盒刷机中的作用机制
  • 【数据分析】基于逆向方法的新型神经网络的实现,以估计云杉音木薄板的材料特性附Matlab代码
  • 微信小程序二维码生成实战指南:3步实现个性化营销码
  • 终极指南:如何使用Keyboard Chatter Blocker解决机械键盘连击问题
  • Performance-Fish性能优化指南:让《环世界》告别卡顿的5大秘诀