Discussion:
[jira] [Created] (FILEUPLOAD-279) CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
Michiel Weggen (JIRA)
2016-11-14 10:33:58 UTC
Permalink
Michiel Weggen created FILEUPLOAD-279:
-----------------------------------------

Summary: CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical


http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-1000031



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
Michiel Weggen (JIRA)
2016-11-14 10:47:58 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Michiel Weggen updated FILEUPLOAD-279:
--------------------------------------
Description:
http://www.tenable.com/security/research/tra-2016-12

Summary

There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.

Background

In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.

The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.

DiskFileItem’s readObject Implementation

Here is the implementation that currently exists at the projects repository tip (as of 1/28/16):


632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
This is interesting due to the apparent creation of files. However, after analyzing the state of DiskFileItem after serialization it became clear that arbitrary file creation was not supposed to be intended:

dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification

The rules listed above do not take into account that someone might modify the serialized data before it is deserialized. Three important elements get serialized that we can modify:

The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Modifying these three elements in the serialized object gives us the ability to:

Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.

was:http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-1000031
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
Chris Seieroe (JIRA)
2016-11-15 01:38:58 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15665692#comment-15665692 ]

Chris Seieroe commented on FILEUPLOAD-279:
------------------------------------------

I noticed that in the main branch, back in May, there were some commits to remove Serializable from DiskFileItem. That would seem to fix this vulnerability. What if we backported that to the 1.3.x branch?
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
Chris Seieroe (JIRA)
2016-11-15 01:40:58 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15665692#comment-15665692 ]

Chris Seieroe edited comment on FILEUPLOAD-279 at 11/15/16 1:40 AM:
--------------------------------------------------------------------

I noticed that in the master branch, back in May, there were some commits to remove Serializable from DiskFileItem. That would seem to fix this vulnerability. What if we backported that to the 1.3.x branch?


was (Author: fifalover):
I noticed that in the main branch, back in May, there were some commits to remove Serializable from DiskFileItem. That would seem to fix this vulnerability. What if we backported that to the 1.3.x branch?
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
Gary Gregory (JIRA)
2016-11-15 01:58:58 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15665725#comment-15665725 ]

Gary Gregory commented on FILEUPLOAD-279:
-----------------------------------------

Patches welcome!
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
Chris Seieroe (JIRA)
2016-11-15 02:24:58 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Chris Seieroe updated FILEUPLOAD-279:
-------------------------------------
Attachment: 0001-Fix-CVE-2016-1000031-by-making-DiskFileItem-not-Seri.patch

First patch attempt, pulling fixes from the master branch.
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Attachments: 0001-Fix-CVE-2016-1000031-by-making-DiskFileItem-not-Seri.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
Chris Seieroe (JIRA)
2016-11-15 02:27:58 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15665795#comment-15665795 ]

Chris Seieroe commented on FILEUPLOAD-279:
------------------------------------------

Looking back at the patch, it's a lot larger than I expected. I'm wondering if my usual code formatter or something else the IDE did (end of line changes) made the change larger than expected. I'll see if I can try that again.
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Attachments: 0001-Fix-CVE-2016-1000031-by-making-DiskFileItem-not-Seri.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
Chris Seieroe (JIRA)
2016-11-15 02:50:59 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Chris Seieroe updated FILEUPLOAD-279:
-------------------------------------
Attachment: fix2.patch

I reapplied the fixes on a clean copy, and the patch looks a lot better this time. I'll delete the original one, just to remove confusion.
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
Chris Seieroe (JIRA)
2016-11-15 02:50:59 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Chris Seieroe updated FILEUPLOAD-279:
-------------------------------------
Attachment: (was: 0001-Fix-CVE-2016-1000031-by-making-DiskFileItem-not-Seri.patch)
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
Mark Thomas (JIRA)
2016-11-15 07:25:59 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15666372#comment-15666372 ]

Mark Thomas commented on FILEUPLOAD-279:
----------------------------------------

-1 to back-porting since it breaks backwards compatibility.

This was discussed at the time and the security hardening changes were applied only to trunk because of backwards compatibility concerns.

To re-iterate what has been said elsewhere. Java (de)serialization is inherently dangerous. It should only be performed from trusted sources or after appropriate validation that only safe classes are being used. Applications that fail to do this are open to all sorts of vulnerabilities.
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
Chris Seieroe (JIRA)
2016-11-15 18:30:59 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15667888#comment-15667888 ]

Chris Seieroe commented on FILEUPLOAD-279:
------------------------------------------

Are you saying it breaks backwards compatibility because the consuming applications may serialize DiskFileItem themselves?

I'm trying to be practical here. I have a release going out in a matter of days, and while the only deserializing from trusted sources or other mitigation techniques may be the best solution, that's too risky and we simply don't have the time. If I need to, I'll build my own version of this library with the patch. But, obviously, if you're saying there's a problem with that patch, then I need to find some other solution.
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
Jochen Wiedmann (JIRA)
2016-11-15 18:59:58 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15667947#comment-15667947 ]

Jochen Wiedmann commented on FILEUPLOAD-279:
--------------------------------------------

Chris, we are preparing an alternative solution. But pushing out a release, and all that, needs time. So, please be a bit patient.
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
Henning Schmiedehausen (JIRA)
2016-11-23 22:50:58 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15691568#comment-15691568 ]

Henning Schmiedehausen commented on FILEUPLOAD-279:
---------------------------------------------------

you should also remove the serialVersionUID (https://github.com/apache/commons-fileupload/blob/7b201e44962c99cf4019e137aee9ccc0273c3ab1/src/main/java/org/apache/commons/fileupload/disk/DiskFileItem.java#L80-L83)
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
Naozumi Taromaru (JIRA)
2016-11-25 04:56:58 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15694839#comment-15694839 ]

Naozumi Taromaru commented on FILEUPLOAD-279:
---------------------------------------------

Chris, if an application deserializes data from an untrusted source, that is an application vulnerability.
Even if commons-fileupload isn't used, when using a class in JDK, it's possible to attack.

Please see following.
* https://gist.github.com/coekie/a27cc406fc9f3dc7a70d
* https://www.owasp.org/index.php/Deserialization_of_untrusted_data

The 1st link is very easy to understand.
The reply(19/Nov/15)(2015/11/19) to me at https://issues.apache.org/jira/browse/COLLECTIONS-580 includes this link.
The 2nd link also includes the 1st link.
("HashSet Billion-Laughs Style DoS example by Wouter Coekaerts")
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
Chris Seieroe (JIRA)
2016-11-30 02:31:58 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15707286#comment-15707286 ]

Chris Seieroe commented on FILEUPLOAD-279:
------------------------------------------

I understand the larger problem, and that's something that I can address as a developer in code that I write. However, what do you tell someone in the operations side of things? They use tools that scan the software that's installed to find potential security vulnerabilities and something like this issue comes up. They're not interested in this larger issue. They just need that library patched so their security dashboard shows green again.

Now that I'm aware of this style of attack, I can look out for it in code that I write and take the kind of precautions described in those links. On the other hand, I think taking a belt-and-suspenders approach here is appropriate. We can do both things.

Also means one more thing when evaluating 3rd-party code. In some cases, we may not be using FileUpload directly but it is a transitive dependency. We may not even know if object deserialization is going on, much less if it's from trusted sources.
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
Naozumi Taromaru (JIRA)
2016-11-30 07:05:59 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15707799#comment-15707799 ]

Naozumi Taromaru commented on FILEUPLOAD-279:
---------------------------------------------
Post by Chris Seieroe (JIRA)
However, what do you tell someone in the operations side of things?
They use tools that scan the software that's installed to find potential security vulnerabilities and something like this issue comes up.
They're not interested in this larger issue. They just need that library patched so their security dashboard shows green again.
A tool may not always be judged properly.
A person has to confirm the validity of the judgement of a tool.

Even if indication of a tool becomes green, it may not be proper.

If the (Disk)FileItem will be not Serializable,
a JavaBean including (Disk)FileItem will fail to serialize.
(Strictly the JavaBean will be not the "JavaBeans".)

When setAttribute such JavaBean or (Disk)FileItem to the session, the session replication will be failed.
Post by Chris Seieroe (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
Rick Oosterholt (JIRA)
2017-01-09 15:16:58 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15812015#comment-15812015 ]

Rick Oosterholt commented on FILEUPLOAD-279:
--------------------------------------------

When searching for a fix for this bug, I've found a commit related to this issue.
See [branch 1.3|https://git-wip-us.apache.org/repos/asf?p=commons-fileupload.git;a=shortlog;h=refs/heads/b1_3]:
Especially [revision 388e824518697c2c8f9f83fd964621d9c2f8fc4c|https://git-wip-us.apache.org/repos/asf?p=commons-fileupload.git;a=commit;h=388e824518697c2c8f9f83fd964621d9c2f8fc4c]. This commit disables deserialyzing by default (enable by setting system properties with a specific naming convention). This seems to 'fix' FILEUPLOAD-279 for now.

When can we expect a release of Apache Commons Fileupload 1.3.3?
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
Mark Symons (JIRA)
2017-04-11 15:54:41 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15964565#comment-15964565 ]

Mark Symons commented on FILEUPLOAD-279:
----------------------------------------

Is there any info on when a solution might be available? Be it a fix or the "alternative solution" mentioned in the last comment from 15th Nov 2016.

Currently all versions of commons-fileupload up to and including 1.3.2 are generating critical threat alerts from Sonatype Nexus IQ (and presumably from alternatives such as Whitesource or Black Duck Hub).
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.15#6346)
Pegasus (JIRA)
2017-04-27 07:27:04 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15986143#comment-15986143 ]

Pegasus commented on FILEUPLOAD-279:
------------------------------------

Is there any fix solution available ? help ...
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.15#6346)
Achim H. (JIRA)
2017-05-31 13:32:05 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16031153#comment-16031153 ]

Achim H. commented on FILEUPLOAD-279:
-------------------------------------

Please release the fix.
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.15#6346)
Gary Gregory (JIRA)
2017-05-31 21:32:04 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16032000#comment-16032000 ]

Gary Gregory commented on FILEUPLOAD-279:
-----------------------------------------

I'll ping the ML...
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.15#6346)
Rob Tompkins (JIRA)
2017-06-06 05:04:18 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Rob Tompkins updated FILEUPLOAD-279:
------------------------------------
Fix Version/s: 1.3.3
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.15#6346)
Rob Tompkins (JIRA)
2017-06-06 15:32:18 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Rob Tompkins resolved FILEUPLOAD-279.
-------------------------------------
Resolution: Fixed

Working on the release now.
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.3.15#6346)
Mark Symons (JIRA)
2017-06-24 14:11:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16062007#comment-16062007 ]

Mark Symons commented on FILEUPLOAD-279:
----------------------------------------

Thanks very much for the release. 1.3.3 is [available|http://repo1.maven.org/maven2/commons-fileupload/commons-fileupload/1.3.3/] in Maven Central.

Just one thing... 1.3.3 has not yet been released in JIRA.
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.4.14#64029)
Bruno P. Kinoshita (JIRA)
2017-06-25 05:14:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16062216#comment-16062216 ]

Bruno P. Kinoshita commented on FILEUPLOAD-279:
-----------------------------------------------

Updated the version in JIRA, with release date the same as the announce e-mail in the commons mailing list.
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v6.4.14#64029)
Matt Kempers (JIRA)
2018-11-06 20:21:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16677267#comment-16677267 ]

Matt Kempers commented on FILEUPLOAD-279:
-----------------------------------------

What is the best way to find this vulnerability across environment?

Is it safe to say any version of commons-fileupload pre 1.3.* on Struts 1 &2 is vulnerable?
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Bernd Eckenfels (JIRA)
2018-11-06 22:44:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16677377#comment-16677377 ]

Bernd Eckenfels commented on FILEUPLOAD-279:
--------------------------------------------

The „safe“ thing to do is, if you are in doubt then assume you need to upgrade to not be vulnerable. (And it reduces the amount of justification and explaining you have to do when you are regularly bombarded with scan reports and requests for asking for exceptions to keep old, known vulnerable versions around)
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
jack (JIRA)
2018-11-07 00:41:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16677464#comment-16677464 ]

jack commented on FILEUPLOAD-279:
---------------------------------

If you can't upgrade, what things should you monitor to reduce the risk of this being exploited. System is going to be EOL soon, however, it is still critical and an upgrade isn't viable. 
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Cyrus (JIRA)
2018-11-13 01:59:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16684615#comment-16684615 ]

Cyrus commented on FILEUPLOAD-279:
----------------------------------

Do I need to upgrade my commons-fileupload-1.3.2.jar even if I'm not using Apache Struts?
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Bernd Eckenfels (JIRA)
2018-11-13 02:50:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16684646#comment-16684646 ]

Bernd Eckenfels commented on FILEUPLOAD-279:
--------------------------------------------

This is not (directly) related to Struts.

The DiskFileItem class lingers around in your applications and this adds a trivial Widget to be exploited by serialisation attacks. It might not be the only vector, and deserialising untrusted data is fatal in itself, hoewever you would still be guilty of not having updated a class with known vulnerabilities. So just update.

if you cant update (for whatever reason) then the only thing to mitigate you can do is to actually review all usage of serialisation in your apps. You should probably do that anyway.

it might be possible that you notice upload_uuid_id.tmp file in random directories, but they do only show up for short times if it is used to generate files.

I would better like to understand why can’t people just upgrade, is there something we can make it easier?
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Bernd Eckenfels (JIRA)
2018-11-13 02:50:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16684646#comment-16684646 ]

Bernd Eckenfels edited comment on FILEUPLOAD-279 at 11/13/18 2:49 AM:
----------------------------------------------------------------------

This is not (directly) related to Struts.

The DiskFileItem class lingers around in your applications and this adds a trivial Widget to be exploited by serialisation attacks. It might not be the only vector, and deserialising untrusted data is fatal in itself, hoewever you would still be guilty of not having updated a class with known vulnerabilities. So just update.

if you cant update (for whatever reason) then the only thing to mitigate you can do is to actually review all usage of serialisation in your apps. You should probably do that anyway.

it might be possible that you notice upload_uuid_id.tmp file in random directories, but they do only show up for short times if it is used to generate files.

I would lIke like to better understand why can’t people just upgrade, is there something we can make it easier?


was (Author: b.eckenfels):
This is not (directly) related to Struts.

The DiskFileItem class lingers around in your applications and this adds a trivial Widget to be exploited by serialisation attacks. It might not be the only vector, and deserialising untrusted data is fatal in itself, hoewever you would still be guilty of not having updated a class with known vulnerabilities. So just update.

if you cant update (for whatever reason) then the only thing to mitigate you can do is to actually review all usage of serialisation in your apps. You should probably do that anyway.

it might be possible that you notice upload_uuid_id.tmp file in random directories, but they do only show up for short times if it is used to generate files.

I would better like to understand why can’t people just upgrade, is there something we can make it easier?
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Jochen Wiedmann (JIRA)
2018-11-13 06:12:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16684763#comment-16684763 ]

Jochen Wiedmann commented on FILEUPLOAD-279:
--------------------------------------------

It is escapes me, why there is a discussion ongoing with this issue having been resolved more than a year before. As for Struts: Of course, this is not a Struts issue. Except that Struts (AFAIK) distributes commons-fileupload. In other words: Just replace commons-fileupload 1.3.2 with 1.3.3, and you are done. They are binary compatible, so  Struts will be just as happy.

 

 
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Adam Pikulik (JIRA)
2018-12-02 10:29:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16706163#comment-16706163 ]

Adam Pikulik commented on FILEUPLOAD-279:
-----------------------------------------

Hello,

There is "Affected versions: 1.3.2" however on other websites like:
[https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-1000031]
[https://nvd.nist.gov/vuln/detail/CVE-2016-1000031
]

all versions before 1.3.3 are vulnerable. What versions are impacted by this bug?

Thanks,
Adam
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Jochen Wiedmann (JIRA)
2018-12-02 10:49:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16706178#comment-16706178 ]

Jochen Wiedmann commented on FILEUPLOAD-279:
--------------------------------------------

*Exactly,* as is written in your quote, and in my comment above: Version 1.3.3 is *not* affected. All previous versions are. Why are you asking?

 

 
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Adam Pikulik (JIRA)
2018-12-02 11:07:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16706189#comment-16706189 ]

Adam Pikulik commented on FILEUPLOAD-279:
-----------------------------------------

Jochen,

Thank you for replying so quickly. I am asking because in the affected versions I see only 1.3.2 and also under the link:
[https://www.cvedetails.com/vulnerability-list/vendor_id-45/product_id-24746/version_id-143021/Apache-Commons-Fileupload-1.2.html]

this CVE is not listed. Just got confused if before means only 1.3.2 or all versions before.

Thank you very much!

Adam
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Jochen Wiedmann (JIRA)
2018-12-02 19:41:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16706448#comment-16706448 ]

Jochen Wiedmann commented on FILEUPLOAD-279:
--------------------------------------------

Adam,

 

I do not feel responsible for external sites like cvedetails.com. To me, the authoritative information is available from

 

[https://commons.apache.org/proper/commons-fileupload/download_fileupload.cgi]

and 

 

[https://commons.apache.org/proper/commons-fileupload/security-reports.html#Apache_Commons_FileUpload_Security_Vulnerabilities]

 

which both completely match, what I am saying.

 
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Rasmita Mahapatra (JIRA)
2018-12-06 05:20:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16710987#comment-16710987 ]

Rasmita Mahapatra commented on FILEUPLOAD-279:
----------------------------------------------

Is this bug fix is ported to 1.4 SNAPSHOT build.

We are currently using _commons-fileupload-1.4-20160119.063138-53. Is this security bug is fixed in this build or we have to upgrade to some other build, please suggest._
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Rasmita Mahapatra (JIRA)
2018-12-06 09:59:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16710987#comment-16710987 ]

Rasmita Mahapatra edited comment on FILEUPLOAD-279 at 12/6/18 9:58 AM:
-----------------------------------------------------------------------

Is this bug fix is ported to 1.4 SNAPSHOT build.

We are currently using _commons-fileupload-1.4-20160119.063138-53. Is this security bug is fixed in this build or we have to upgrade to some other build, please suggest._

_If this issue is fixed in 1.4, please point me to the build location from where I can pick the jar_


was (Author: rasmita):
Is this bug fix is ported to 1.4 SNAPSHOT build.

We are currently using _commons-fileupload-1.4-20160119.063138-53. Is this security bug is fixed in this build or we have to upgrade to some other build, please suggest._
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Bernd Eckenfels (JIRA)
2018-12-06 12:32:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16711376#comment-16711376 ]

Bernd Eckenfels commented on FILEUPLOAD-279:
--------------------------------------------

[~rasmita] it looks like the fix is missing in master/b1_4.

(There are other problems with the master, like a broken changes.xml). I would think sticking with 1.3.3 is better until a official 1.4 release.)
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Bernd Eckenfels (JIRA)
2018-12-06 12:51:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16711401#comment-16711401 ]

Bernd Eckenfels commented on FILEUPLOAD-279:
--------------------------------------------
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Bernd Eckenfels (JIRA)
2018-12-06 12:53:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16711401#comment-16711401 ]

Bernd Eckenfels edited comment on FILEUPLOAD-279 at 12/6/18 12:52 PM:
----------------------------------------------------------------------
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Jochen Wiedmann (JIRA)
2018-12-06 12:48:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16711398#comment-16711398 ]

Jochen Wiedmann commented on FILEUPLOAD-279:
--------------------------------------------

Rasmita,

 

as I have no idea, who created that file, when, and how, I couldn't really tell. All I can say: The fix was committed on 12-May-2016, 13:39 UTC. (See [https://git-wip-us.apache.org/repos/asf?p=commons-fileupload.git;a=commitdiff;h=02f6b2c4ef9aebf9cf8e55de8b90e73430b69385] for details.) Or, in other words: Any version, properly created from the genuine source tree after that point, should be safe. AFAIK, we do not offer automated snapshot builds, so your only choice is to build a snapshot for yourself.

 
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Gilles (JIRA)
2018-12-06 13:08:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16711417#comment-16711417 ]

Gilles commented on FILEUPLOAD-279:
-----------------------------------

bq. AFAIK, we do not offer automated snapshot builds

Some components do, through Jenkins; see e.g.
https://repository.apache.org/content/repositories/snapshots/org/apache/commons/commons-rng-sampling/1.2-SNAPSHOT/
but the lack of synergies between components' maintenance tasks makes it difficult to have up-to-date configurations that produce artefacts in a timely manner and at expected places...
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Bernd Eckenfels (JIRA)
2018-12-06 13:14:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16711420#comment-16711420 ]

Bernd Eckenfels commented on FILEUPLOAD-279:
--------------------------------------------

ASF bylaws makes it hard to offer snapshots and I would agree that we should not do it. (if there is a good reason for users to request 1.4 snapshots it might be time for a release?). Should we discuss this on the users or dev mailing list?
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Gilles (JIRA)
2018-12-06 13:54:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16711476#comment-16711476 ]

Gilles commented on FILEUPLOAD-279:
-----------------------------------

bq. ASF bylaws makes it hard to offer snapshots

?
Jenkins produces them after a successful build.

bq. we should not do it.

Why?
They come with all the caveats: Not an official release, thus no support whatsoever.
However, they might be helpful to *us* by providing an easy way for users to test the latest artefacts (and, hopefully, report problems).

bq. Should we discuss this on the users or dev mailing list?

Probably. ;-)
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Jochen Wiedmann (JIRA)
2018-12-06 14:41:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16711520#comment-16711520 ]

Jochen Wiedmann commented on FILEUPLOAD-279:
--------------------------------------------

Bernd,

 

indeed, the fix for master / 1.4 is different: In the future version, we didn't bother with binary compatibility. So, we simply let FileItem no longer implement java.io.Serializable. In the 1.3 branch, bc matters. So we check for a system property, and throw an exception at runtime.
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Gary Gregory (JIRA)
2018-12-06 15:26:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16711584#comment-16711584 ]

Gary Gregory commented on FILEUPLOAD-279:
-----------------------------------------

FWIW: I published a new {{1.4-SNAPSHOT}} to https://repository.apache.org/content/repositories/snapshots/commons-fileupload/commons-fileupload/
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Rasmita Mahapatra (JIRA)
2018-12-07 04:40:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16712330#comment-16712330 ]

Rasmita Mahapatra commented on FILEUPLOAD-279:
----------------------------------------------

Please confirm, which build I can use, 1.4-SNAPSHOT latest or better to fall back to 1.3.3
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)
Rasmita Mahapatra (JIRA)
2018-12-07 04:59:00 UTC
Permalink
[ https://issues.apache.org/jira/browse/FILEUPLOAD-279?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16712330#comment-16712330 ]

Rasmita Mahapatra edited comment on FILEUPLOAD-279 at 12/7/18 4:58 AM:
-----------------------------------------------------------------------

Please confirm, which build I can use, 1.4-SNAPSHOT latest or better to fall back to 1.3.3

Is CVE-2016-1000031 vulnerability is not present in "commons-fileupload-1.4-20160119.063138-53.jar" SNAPSHOT build, then I we don't need to upgrade the jar.
h1.  


was (Author: rasmita):
Please confirm, which build I can use, 1.4-SNAPSHOT latest or better to fall back to 1.3.3
Post by Michiel Weggen (JIRA)
CVE-2016-1000031 - Apache Commons FileUpload DiskFileItem File Manipulation Remote Code Execution
-------------------------------------------------------------------------------------------------
Key: FILEUPLOAD-279
URL: https://issues.apache.org/jira/browse/FILEUPLOAD-279
Project: Commons FileUpload
Issue Type: Bug
Affects Versions: 1.3.2
Reporter: Michiel Weggen
Priority: Critical
Labels: security
Fix For: 1.3.3
Attachments: fix2.patch
http://www.tenable.com/security/research/tra-2016-12
Summary
There exists a Java Object in the Apache Commons FileUpload library that can be manipulated in such a way that when it is deserialized, it can write or copy files to disk in arbitrary locations. Furthermore, while the Object can be used alone, this new vector can be integrated with ysoserial to upload and execute binaries in a single deserialization call. This may or may not work depending on an application's implementation of the FileUpload library.
Background
In late 2015 FoxGlove Security released a write up on using Chris Frohoff’s yososerial tool to gain remote code execution on a variety of commercial products, based on a presentation at AppSec Cali in January, 2015. The ysoserial tool uses “gadgets” in Apache Commons Collections, Groovy, and Spring that do “unexpected” things during deserialization. Specifically, the ysoserial payloads eventually execute Runtime.getRuntime().exec() allowing for remote Java code execution.
The Apache Commons project maintains a library called “FileUpload” to make “it easy to add robust, high-performance, file upload capability to your servlets and web applications.” One of the classes in the FileUpload library is called “DiskFileItem”. A DiskFileItem is used to handle file uploads. Interestingly, DiskFileItem is serializable and implements custom writeObject() and readObject() functions.
DiskFileItem’s readObject Implementation
632 private void readObject(ObjectInputStream in)
633 throws IOException, ClassNotFoundException {
634 // read values
635 in.defaultReadObject();
636
637 /* One expected use of serialization is to migrate HTTP sessions
638 * containing a DiskFileItem between JVMs. Particularly if the JVMs are
639 * on different machines It is possible that the repository location is
640 * not valid so validate it.
641 */
642 if (repository != null) {
643 if (repository.isDirectory()) {
644 // Check path for nulls
645 if (repository.getPath().contains("\0")) {
646 throw new IOException(format(
647 "The repository [%s] contains a null character",
648 repository.getPath()));
649 }
650 } else {
651 throw new IOException(format(
652 "The repository [%s] is not a directory",
653 repository.getAbsolutePath()));
654 }
655 }
656
657 OutputStream output = getOutputStream();
658 if (cachedContent != null) {
659 output.write(cachedContent);
660 } else {
661 FileInputStream input = new FileInputStream(dfosFile);
662 IOUtils.copy(input, output);
663 IOUtils.closeQuietly(input);
664 dfosFile.delete();
665 dfosFile = null;
666 }
667 output.close();
668
669 cachedContent = null;
670 }
dfos (a type of OutputStream) is transient and therefore it is not serialized. dfos is regenerated by the getOutputStream() call above (which also generates the new File to write out to).
The “repository” (or directory that the file is written to) has to be valid at the time of serialization in order for successful deserialization to occur.
If there is no “cachedContent” then readObject() tries to read in the file from disk.
That filename is always generated via getOutputStream.
Serialized Object Modification
The repository path (aka the directory that the file is read/written from).
If there is cachedContent (i.e. data that didn’t get written to the file) then that gets serialized
If there is no cachedContent (i.e. all data was written to disk) the full path to the output file exists.
The threshold value that controls if “cachedContent” is written to disk or not.
Create files wherever we have permission on the system. The caveat here is that we only have control of the file path and not the final filename.
Copy the contents of files from one file on the system to a location we specify (again we only control the directory path and not the filename). This will also attempt to delete the file we copy from.. so be careful.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Loading...