Advertisement

山东大学软件学院项目实训-创新实训-山大软院网络攻防靶场实验平台(九)

阅读量:

目录

前言

文件上传漏洞概述

文件上传功能背后的业务逻辑是什么

文件上传的安全风险

什么是文件上传漏洞

漏洞复现演示

后端实现


前言

这篇文章记录我搭建文件上传 MIME类型漏洞的环境,以及如何利用该漏洞进行攻击的过程。

文件上传漏洞概述

大部分站点都具有 文件上传功能,例如头像更改,文章编辑,附件上传等等

文件上传功能背后的业务逻辑是什么

  • 文件上传的这个功能是如何实现的呢?
  • 文件上传功能的作用是将 本地文件上传至服务器上进行保存。
  • 当我们找到上传的入口,上传文件之后。
  • 可能会回显文件上传的路径,如果回显了文件上传路径,那么我们就可以根据回显的文件上传路径进行访问,那么我们就可以在浏览器中访问到服务器上的这个文件。

文件上传的安全风险

  • 假设文件上传功能没有对上传的文件进行限制,可能会引发哪些安全风险?
  • 如果是对方是LAMP架构,是否能上传PHP的WebShell到服务端上,然后通过访问上传后的文件地址,从而执行WebShell中的代码。达到控制对方服务器的目的。

什么是文件上传漏洞

  • 文件上传漏洞是指文件上传功能没有对上传的文件做合理严谨的过滤,导致用户可以利用此功能,上传能被服务端解析执行的文件,并通过此文件获得执行服务端命令的能力

漏洞复现演示

前端界面

选择一个图片上传

存储目录中出现该图片

试试上传其他类型的文件

上传失败 后端有对文件类型的检查

进行攻击 实现上传非法文件 抓包

修改Content-Type

发送包

成功上传非法文件

后端实现

复制代码
 @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 "上传失败,请选择文件";
    
     }
    
  
    
     String fileName = file.getOriginalFilename();
    
  
    
  
    
     String contentType = file.getContentType();
    
     System.out.println("\tcontentType=" + contentType);
    
  
    
  
    
     List<String> types = new ArrayList<String>();
    
     types.add("image/jpeg");
    
     types.add("image/png");
    
     types.add("image/gif");
    
    if (!types.contains(contentType)) {
    
  
    
        return "上传失败!不允许上传此类型的文件";
    
     }
    
  
    
  
    
  
    
     String filePath = "C:\ Users\ liu\ Desktop\ spring-boot-upload\ src\ main\ resources\ static\ temp\ ";
    
     File dest = new File(filePath + fileName);
    
     try {
    
         file.transferTo(dest);
    
         LOGGER.info("上传成功");
    
         return "上传成功";
    
     } catch (IOException e) {
    
         LOGGER.error(e.toString(), e);
    
  
    
     }
    
     return "上传失败!";
    
     }

多文件上传实现

复制代码
  @GetMapping("/multiUpload")

    
     public String multiUpload() {
    
     return "multiUpload";
    
     }
    
  
    
     @PostMapping("/multiUpload")
    
     @ResponseBody
    
     public String multiUpload(HttpServletRequest request) {
    
     List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");
    
     String filePath = "/Users/itinypocket/workspace/temp/";
    
     for (int i = 0; i < files.size(); i++) {
    
         MultipartFile file = files.get(i);
    
         if (file.isEmpty()) {
    
             return "上传第" + (i++) + "个文件失败";
    
         }
    
         String fileName = file.getOriginalFilename();
    
  
    
         File dest = new File(filePath + fileName);
    
         try {
    
             file.transferTo(dest);
    
             LOGGER.info("第" + (i + 1) + "个文件上传成功");
    
         } catch (IOException e) {
    
             LOGGER.error(e.toString(), e);
    
             return "上传第" + (i++) + "个文件失败";
    
         }
    
     }
    
  
    
     return "上传成功";
    
  
    
     }

全部评论 (0)

还没有任何评论哟~