Arbitrary File Upload Tricks In Java

0x01 Forewords

Recently I see some discussions about arbitrary file upload in Java environment on Internet. The main takling points are how to bypass file name detection when uploading arbitrary file.

Consequently I write this article to summerize the tricks.

0x02 Juicy Tricks
  • Use getSubmittedFileName method to obtain file name

When we use original Servlet to develop a multipart format file upload feature in Java, getSubmittedFileName() method is often utilized to obtain the file name, especially in early Java applications. But a potential problem involving this method.

We can debug the code to analyse it.Firstly set the breakpoint at getSubmittedFileName , then step into the next method named HttpParser.unquote(), here is the place which file name is obtained.

upload successful

During debugging the code, we can find that when file name containing \ , it will be omitted. Finally the file name becomes pyn3rd.jsp

upload successful

So we can use this peculiarity to evade file name detection,like regular expression based WAF.

upload successful

Significantly, we also can use one single " in filename parameter value with one characters appended to file extension and one \ in filename.

upload successful

  • Use getOriginalFilename method to obtain file name

As we know, the scenario of multipart format file upload in SpringBoot, we are used to utilize getOriginalFilename() method to obtain file name,
it can obtain file name directly without any file name changes.

upload successful

upload successful

However, when we use another method named StringUtils.cleanPath() to normalize the file name which getOriginalFilename() method obtains, another peculiarity existing. We can use one or more /. to append the file name.

/ is used as a delimiter and . means the current directory. If it points to current directory,just drop it. So the result of the file name is pyn3rd.jsp

upload successful

upload successful

By the way, in Java (Windows system), \ is always transformed to /, when we encounter SSRF/XXE vulnerablities, trying to replace \ with /, for example, http:\/ replaces http://

upload successful

  • Use Apache commons-fileupload/commons-io method to obtain file name

We can also use some common Java libraries like org.apache.commons.fileupload.FileItem.getName or org.apache.commons.io.FilenameUtils.getName to obtain file name. For example,commons-io is analyzed as follow

upload successful

If / or /[SPACE] is appended at the end of the file name. In the other words, / with zero character or null character, the results of the file name are both pyn3rd.jsp

upload successful

upload successful

upload successful

If / or /[SPACE] is appended at the end of the file name.In case of the non-blank characters existing behind the delimiter /,
the characters behind / will be obtained as the file name.

upload successful

0x03 Conclusion

The different normalization results depend on the implements of varied jar libraries and the personal habbits of developers. If the developers don’t know about this, potential vulnerablities seem inevitable. Thus, the in-depth research of normalization diversities will help us evade defense.