长亭百川云 - 文章详情

Tomcat Servlet 3.0 upload 小case

bluE0x00

43

2024-07-14

前段时间听园长和su18师傅在群里谈起,Tomcat Servlet 3.0的文件名解析规则有稍许奇特,上周跟了一下,以下为笔记:

Servlet3.0 新增了对文件上传请求解析的支持,

javax.servlet.http.HttpServletRequest#getParts,使用

request.getParts();即可获取文件上传包解析后的结果,从此不再需要使用第三方jar来处理文件上传请求了。

参考园长:https://javasec.org/java-vuls/FileUpload.html

demo:

`package com.example.tomcat_bypass;``   ``import org.apache.commons.io.FileUtils;``import org.apache.commons.io.IOUtils;``   ``import javax.servlet.ServletException;``import javax.servlet.annotation.MultipartConfig;``import javax.servlet.annotation.WebServlet;``import javax.servlet.http.HttpServlet;``import javax.servlet.http.HttpServletRequest;``import javax.servlet.http.HttpServletResponse;``import javax.servlet.http.Part;``import java.io.*;``import java.util.Collection;``   ``@MultipartConfig``@WebServlet(name = "upload",value = "/upload")``public class upload extends HttpServlet {``   `    `@Override`    `protected void doGet(HttpServletRequest req , HttpServletResponse resp) throws IOException {`        `resp.getWriter().println("doPost!");``   `    `}``   ``   `    `@Override`    `protected void doPost( HttpServletRequest request , HttpServletResponse response) throws IOException, ServletException {`        `PrintWriter out         = response.getWriter();`        `String      contentType = request.getContentType();``   `        `// 检测是否是multipart请求`        `if (contentType != null && contentType.startsWith("multipart/")) {`            `String dir       = request.getSession().getServletContext().getRealPath("/uploads/");`            `File   uploadDir = new File(dir);``   `            `if (!uploadDir.exists()) {`                `uploadDir.mkdir();`            `}``   `            `Collection<Part> parts = request.getParts();``   `            `for (Part part : parts) {`                `String fileName = part.getSubmittedFileName();``   `                `if (fileName != null) {`                    `File uploadFile = new File(uploadDir, fileName);`                    `out.println(part.getName() + ": " + uploadFile.getAbsolutePath());``   `                    `FileUtils.writeStringToFile(uploadFile, IOUtils.toString(part.getInputStream(), "UTF-8"));`                `} else {`                    `out.println(part.getName() + ": " + IOUtils.toString(part.getInputStream()));`                `}`            `}`        `}``   `        `out.flush();`        `out.close();`    `}``   ``}``   `

其中使用ApplicationPart来存储从multipart请求中接收的DiskFileItem对象信息:

而获取文件名所使用的方法为getSubmittedFileName(),如上图断点处所示。

跟进ApplicationPart类,查看其getSubmittedFileName方法:

使用unquote方法处理fileName,跟进查看:

一共两个特性:

case1:

当input String中含有双引号时‘ ” ’,整体字符长度将会减1。

case2:

当字符串中含有' \ '时,则会跳过该字符,将后一位字符直接放入result中。

针对文件名我们可以尝试构造如下类型的payload:

  • 123\.\j\s\p

  • 123.\j\s\p\

  • "123.js\p\xg

  • .....

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2