S2-066分析与复现

Foreword

自struts2官方纰漏S2-066漏洞已经有一段时间,期间断断续续地写,直到最近才完成,o(╥﹏╥)o。羞愧地回顾一下官方通告:

图片

 

2023.12.9发布,编号CVE-2023-50164,主要影响版本是 2.5.0-2.5.32 以及 6.0.0-6.3.0,描述中提到了文件上传漏洞和目录穿越漏洞。开始以为这是个组合漏洞,其实不是,这是一个漏洞,看了几篇大佬的文章,有的把它称为“文件上传目录穿越漏洞”,也有道理。

Prepare

准备工作就是搭建项目,用Tomcat跑,调试好断点,回顾下struts2的结构。篇幅有限,这里只贴一张struts2自身的配置文件:

图片

 

struts2有众多的Filter和Intercepter,它的配置逻辑是,除文件中定义的class、package以外,其余全部拦截。对于S2-066,处理一个请求要经过的几个关键类包括Dispatcher、Interceptor、HttpParameters以及UploadAction。使用下面的poc:

图片

 

Dispatcher

请求首先会进入著名的Dispatcher。multi参数对应的就是body数据,包含upload、fileName、contentType三个变量,无误:

图片

 

request中还有一个参数,uploadFileName=../../z127.txt,这个是污染参数,文件上传的目的地,也是利用这个漏洞的目标。

图片

 

走到这里Dispatcher只是简单处理一下请求然后交给Interceptor,无异常。

FileUploadInterceptor

拦截器先是把request包装了一下,类型是MultiPartRequestWrapper。

图片

 

这里与Dispatcher一样,请求参数还是multi和request两部分,也无异常。

图片

 

并且遍历只有一次 ,因为真正的body只有一个,就是那个multi。

图片

 

在遍历过程中struts2还出现了硬编码现象,要求文件名参数必须以FileName结尾,且拼接完成的文件名前缀就是body中的{upload}名称,这就给exp带来了一定限制:

图片

 

此外,注意这里的279行:

// get the name of the file from the input tag
String[] fileName = multiWrapper.getFileNames(inputName);

使用的是MultiPartRequest接口的方法,而这个接口在S2-066中是由JakartaMultiPartRequest实现。使用下面这个poc进行目录穿越并断点检测一下:

图片

 

发现目录穿越失败,文件没有放在指定目录下。分析源码:

图片

 

参数覆盖原本想用../../z126.txt,方法的输入参数确实也是这样接收的,但在这个方法中struts2会对文件名进行截断,最终输出的文件名会变为 z126.txt,文件也就不会出现目录穿越的现象。因此目录穿越不是发生在这里,让struts2自己背这个锅多少有点冤。body中的数据组装完毕是下面这样,size等于3,依旧无误:

图片

 

HttpParameters

来到HttpParameters查看接收的参数,还是upload、contentType、fileName三个:

图片

 

但是参数接收完后就不正常了,除了原本的UploadFileName(注意首字母是大写),还多了一个uploadFileName(注意首字母是小写),size也变成了4。这就是Struts2官方所解释的大小写敏感,即对大写的Upload和小写的upload分别做处理。从这里开始,S2-066才露出真正面目:

图片

 

HttpParameters实现了Map接口,所以本质上它还是一个map,这也是组装参数最常用的方式。但不管是HashMap还是TreeMap,自己不会出现覆盖的问题。用一个小实验证明:

图片

 

走到这里,HttpParameters对参数的处理开始出现异常,但依然没有发生覆盖。

UploadAction

终于到Action了。引用一段struts2官方的描述:

An attacker can manipulate file upload params to enable paths traversal and under some circumstances this can lead to uploading a malicious file which can be used to perform Remote Code Execution.

通过操控上传参数,黑客能够出发目录穿越漏洞,这样一来,在某些情况下可以上传恶意文件,从而进行RCE。换种说法,S2-066是框架自身、软件工程师、Java反射机制共同作用的结果。走到这里,为了简化代码,UploadAction即是Action又是Entity。而在Entity的实例化过程中,必然是通过setXX属性来赋值。所以就有了setUploadFileName(注意首字母大写)和setuploadFileName(注意首字母小写)的需求 。而在Entity的setter与getter中,这两种需求都会被当做一种,即setUploadFileName,因此覆盖也就发生了。正常情况下实例化方法只走一遍,如contentType:

图片

 

而setUploadFileName第一遍是z106.txt:

图片

 

第二遍是../../z127.txt:

图片

 

实例化完成后,uploadFileName属性已被覆盖:

图片

 

查看物理路径,上传成功:

图片

 

POCs

参数不是filename结尾,失败:

图片

 

参数不符合FileName大小写要求,失败:

图片

 

大写覆盖小写失败:

图片

 

大写覆盖大写失败:

图片

 

小写覆盖小写失败:

图片

 

小写覆盖大写成功,文章开头所用。另外覆盖也可以放在body中:

图片

 

验证:

图片

 

利用条件多少有点苛刻,但杀伤力不输struts2过去那一堆,CVSS3.0评分9.8,CRITICAL。

图片

 

参考:https://github.com/jakabakos/CVE-2023-50164-Apache-Struts-RCE

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

国产AI插件StartAI PS平替之【局部重绘】

PS beta有创成式填充,StartAI有【局部重绘】【扩图】,国内设计师的好物推荐。图像延展填充这么做?StartAI【扩图】帮你填充图像,【局部重绘】帮你调整图像细节。 【局部重绘】适用于广告、摄影等图像领域。 原图 我们对图片中的…

最近公共祖先(Tarjin)

【模板】最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。 输入格式 第一行包含三个正整数 N , M , S N,M,S N,M,S,分别表示树的结点个数、询问的个数和树根结点的序号…

十、MySQL主从架构配置

目录 一、资源配置 二、主从同步基本原理: 1、具体步骤: 2、数据库是靠什么同步的? 3、pos与GTID的区别? 三、配置一主两从 (1)为主库和从库创建复制账户, 分别在主从库上执行如下命令&a…

Chrome 114 带着侧边栏扩展来了

效果展示 manifest.json {"manifest_version": 3,"name": "ChatGPT学习","version": "0.0.2","description": "ChatGPT,GPT-4,Claude3,Midjourney,Stable Diffusion,AI,人工智能,AI","icons"…

健康星球乃幸福源泉:AI如何助力拯救环境

地球、环境和自然是有机融入的,自形成以来就一直维持着自我。看似如此有机的东西无需技术,但随着地球上发生的各种变化,我们却可以寄希望于人工智能(AI)帮助地球重回正轨,迎接幸福健康的千年。全球目标业已…

Stable Diffusion之核心网络结构解析

Stable Diffusion核心网络结构解析 1. SD模型整体架构初识 1. SD模型整体架构初识 Stable Diffusion模型整体上是一个End-to-End模型,主要由以下三个核心组件构成。 VAE(变分自编码器,Variational Auto-Encoder),U-N…

带你玩透浮动float布局,详解(一)

文章目录 一 认识浮动二 浮动的规则浮动的规则一代码展示 浮动规则二代码展示 浮动规则四代码展示代码展示 浮动规则五 空隙的解决方案代码展示:第一种方式 放在一行第二种解决方式(不推荐使用这种方式)第三种方式采用浮动(推荐,统…

ESP-IDF 外设SPI驱动

本文只是对ESP32S3的SPI使用进行简单的介绍,主要讲解基于ESP-IDF的四线标准SPI的简单使用。并不涉及非固定长度结构体、dummy位的使用、高速SPI以及其它类型的SPI工作模式。 更加专业的内容可以参考:SPI 主机驱动程序 SPI简介 SPI(serial …

【JS】替换文本为emjio表情

最终效果展示 T1 T2 T3 T4 需求 把评论你好帅啊啊啊[开心][开心],[开心] 替换为图片 思路 正则match提取[开心]到一个数组数组去重创建img标签img标签转文本. 。例:(el.outerHTML),将el元素转文本字符串replaceAll…

TikTok运营要用什么样的IP?怎么选择?

对于运营TikTok的从业者来说,IP的重要性自然不言而喻。 在其他条件都正常的情况下,拥有一个稳定,纯净的IP,你的视频起始播放量很可能比别人高出不少,而劣质的IP轻则会限流,重则会封号。那么,如何…

jQuery 选择器--获取元素

文章目录 1 jQuery 基础选择器2 层级选择器3 隐式迭代(重要)4 jQuery 筛选选择器5 jQuery 筛选方法(重点)案例--下拉菜单 6 jQuery 排他思想*案例--左右Tab栏切换 7 jQuery 链式编程 1 jQuery 基础选择器 2 层级选择器 3 隐式迭代(重要) 示例: 4 jQuery 筛选选择器…

万亿参数大模型网络怎么建?GTC 2024立了个标杆

​多年来,NVIDIA一直在面向AI的数据中心方面布局,随着大模型与生成式AI的到来,NVIDIA也为大模型AI智算中心立了个Flag,这就是黄仁勋近两年来经常挂在嘴边上的“AI工厂”。 早在2022年9月的GTC大会上,黄仁勋就预测数据…

MavenGit

Maven Maven的功能 1.管理jar包 2.Maven也支持编译、测试、打包发布和安装等功能 Maven的下载安装 1.Maven官方地址:Maven – Download Apache Maven 2.Maven的配置 1)配置环境变量 2)配置本地仓库 3)配置镜像 关于pom.…

每日一题 --- 27. 移除元素 - 力扣 [Go]

移除元素 题目: 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不…

视频素材库app哪里找?收藏以下短视频素材网站

嗨,视频创作达人们!你们是不是在寻找那些高质量的视频素材库app?别担心,今天我就给你们推荐几个超棒的app,让你的视频创作更加出彩! 蛙学网:视频素材库app推荐当然少不了蛙学网啦!这…

图论基础|695. 岛屿的最大面积、1020. 飞地的数量、130. 被围绕的区域

695. 岛屿的最大面积 力扣题目链接(opens new window) 给你一个大小为 m x n 的二进制矩阵 grid 。 岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0&#xff0…

一、Java中SpringCloud组件集成接入【Nacos服务管理】

一、Java中SpringCloud组件集成接入【Nacos服务】 1.Nacos介绍2.搭建Nacos服务2.1Windows部署2.2Linux和Docker部署 3.Nacos可视化操作4.Java集成Nacos5.常见问题5.1将nacos变量读取到程序中作为全局变量 6.参考文章 1.Nacos介绍 Nacos是一个开源的动态服务发现、配置管理和服…

pyvista可视化加强版

增加了一个随机按钮,可以即时切换case可视化 import os import glob import randomimport pyvista as pvdef display_multi_meshes(meshes: list, titlesNone, point_size3, opacity0.9):num len(meshes)for i in range(num):pl.subplot(0, i)if i 2:pl.add_che…

动态规划--子序列问题(一)

一.什么是子序列问题 我们之前已经学习过子数组问题,子数组问题最大的特点就是求一段连续区间的xxxx,子数组问题的经典的状态表示就是以i位置为结束,xxxx,推导状态转移方程的一个经验是根据数组的结构来区分不同的结构 子序列问题本质上是对子数组问题的一个拓展,或者说子序列…