High
CVE-2023-50164
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below:
Add References:
CVE-2023-50164
MITRE ATT&CK
Collection
Command and Control
Credential Access
Defense Evasion
Discovery
Execution
Exfiltration
Impact
Initial Access
Lateral Movement
Persistence
Privilege Escalation
Topic Tags
Description
An attacker can manipulate file upload params to enable paths traversal and under some circumstances this can lead to uploading a malicious file which can be used to perform Remote Code Execution.
Users are recommended to upgrade to versions Struts 2.5.33 or Struts 6.3.0.2 or greater to fix this issue.
Add Assessment
Ratings
-
Attacker ValueHigh
-
ExploitabilityLow
Technical Analysis
Based on our Rapid7 Analysis, the attacker value of this vulnerability is High, as successful exploitation can result in remote code execution via arbitrary file uploads, such as uploading a web shell or similar. However I have rated the exploitability as Low as there are a number or prerequisites that must be met for a Struts based web application to be vulnerable. Currently we don’t have any concrete examples of production applications that are vulnerable to CVE-2023-50164. This may change as the vulnerability comes under more scrutiny and more Struts based applications are examined.
Would you also like to delete your Exploited in the Wild Report?
Delete Assessment Only Delete Assessment and Exploited in the Wild ReportRatings
Technical Analysis
Despite the buzz on this one, so far we haven’t been able to identify any real-world applications that are vulnerable and exploitable out of the box, though that doesn’t mean they don’t exist.
Per @sfewer-r7’s analysis of the bug, this is not trivially exploitable, and exploits may need to be target-specific if there are any real applications discovered to be vulnerable in common configurations. At least three different security firms are reporting exploitation in the wild, but it’s not clear that any of them have seen actual exploitable code paths get hit, or that the attack vectors are production applications rather than demo applications configured to be artificially exploitable (which is what the public PoCs currently target). Happy to be wrong if we’re wrong, but until then, “don’t panic” sounds like the order of the day. If there are follow-on vendor advisories patching this out of their specific product implementations, it’d probably be good to pay attention to those as they roll in.
Edit: Shadowserver actually said explicitly that none of the attempts they’d seen as of December 13 had been successful.
Would you also like to delete your Exploited in the Wild Report?
Delete Assessment Only Delete Assessment and Exploited in the Wild ReportCVSS V3 Severity and Metrics
General Information
Vendors
- apache
Products
- struts
References
Exploit
A PoC added here by the AKB Worker must have at least 2 GitHub stars.
Miscellaneous
Additional Info
Technical Analysis
Overview
Apache Struts is a popular Java web application framework. On December 7, 2023 Apache published an advisory for CVE-2023-50164, a Struts parameter pollution vulnerability that potentially leads to arbitrary file uploads. An attacker with the ability to perform arbitrary file uploads is very likely to be able to leverage this and achieve remote code execution. According to the vendor, the following versions of Struts are affected:
- Struts 2.0.0 – Struts 2.3.37 (End of Life)
- Struts 2.5.0 – Struts 2.5.32
- Struts 6.0.0 – Struts 6.3.0
Several technical analyses on the root cause of the vulnerability have already been done (here, here, and here). Notably, all current public analysis of the vulnerability demonstrates exploitation on a custom made demo web application.
There are currently no known production web applications that are exploitable, although this is likely to change as the vulnerability comes under more scrutiny from researchers, and given the popularity of the Struts framework in enterprise web applications. Several security firms have reported exploitation (here and here), but as of December 15, 2023, it is unclear if the activity being reported actually refers to successful exploitation (i.e., code execution) against one or more known vulnerable targets, or if this is merely highlighting exploit attempts with the existing public PoCs (all of which target a demo application) being sprayed opportunistically at indiscriminate targets.
Analysis
To explore this vulnerability and better understand the prerequisites that will make a target application vulnerable, we will step through exploitation of the demo web application which accompanies the public PoC from https://github.com/jakabakos/CVE-2023-50164-Apache-Struts-RCE.
After opening the demo web application in IntelliJ, and running it on a Jetty application server, we can reach the vulnerable target endpoint via a HTTP POST request to /upload/upload.action
. First we must examine the custom logic that implements the upload action.
We can see several private member variables are defined, these are expected to be set automatically by the Struts interceptor ParametersInterceptor
via OGNL statements, when processing the HTTP request. The content of these values will be extracted from the HTTP request via the Struts interceptor FileUploadInterceptor
.
public class Upload extends ActionSupport { private File upload; private String uploadFileName; private String uploadContentType;
Next we can see the custom logic that executes when this action is performed. The file that was uploaded will be copied to another location via FileUtils.copyFile
. Of note is the destination path is constructed via uploadFileName
.
// Custom upload logic public String execute() throws Exception { if (uploadFileName != null) { try { // Specify the directory where files will be uploaded String uploadDirectory = System.getProperty("user.dir") + "/uploads/"; // Create the destination file File destFile = new File(uploadDirectory, uploadFileName); // Copy the uploaded file to the destination FileUtils.copyFile(upload, destFile); // Add message to reflect the exact upload path on the frontend addActionMessage("File uploaded successfully to " + destFile.getAbsolutePath()); return SUCCESS; } catch (Exception e) { addActionError(e.getMessage()); e.printStackTrace(); return ERROR; } } else { return INPUT; } }
Finally we can see that several getter and setter methods exist, for both the upload
and uploadFileName
member variables.
public File getUpload() { return upload; } public void setUpload(File upload) { this.upload = upload; } public String getUploadFileName() { return uploadFileName; } public void setUploadFileName(String uploadFileName) { this.uploadFileName = uploadFileName; }
By reading the documentation for the FileUploadInterceptor
, we can see that an expected naming convention exists when uploading a file and mapping that file to an action’s member variables.
Interceptor that is based off of MultiPartRequestWrapper, which is automatically applied for any request that includes a file. It adds the following parameters, where
<file name>
is the name given to the file uploaded by the HTML form:
<file name>
: File – the actual File
<file name>
ContentType: String – the content type of the file
<file name>
FileName: String – the actual name of the file uploaded (not the HTML name)
For example, uploading a file with a multi-part name of “foo”, can pass a file name through the parameter “fooFileName”. If a setter method called “setFooFileName” exists in the action, this setter method will be automatically called to set the file name. CVE-2023-50164 allows for this feature to be abused, bypassing file name sanitization, and allowing for an arbitrary file name path to be specified. If the custom application logic does something potentially dangerous, such as copy the uploaded file to a location based on the file name, this can be abused.
We can successfully exploit this demo web application with the following HTTP POST request.
POST /upload/upload.action HTTP/1.1 Host: 127.0.0.1:4444 User-Agent: Mozilla Accept: */* Connection: close Content-Type: multipart/form-data; boundary=dujjbxrtqkhczyec Content-Length: 256 --dujjbxrtqkhczyec Content-Disposition: form-data; name="Upload"; filename="good.txt" Content-Type: text/plain Hello World --dujjbxrtqkhczyec Content-Disposition: form-data; name="uploadFileName" ..\..\..\..\..\..\evil.bin --dujjbxrtqkhczyec--
Several things happen under the hood thanks to the Struts interceptors. First the FileUploadInterceptor
will extract the uploaded file’s name and ensure it does not contain any path separators via org.apache.struts2.dispatcher.multipart.AbstractMultiPartRequest#getCanonicalName
.
Then the FileUploadInterceptor
will populate the actions parameters, held in the current ActionContext
instance for this action. These parameters are later passed to the interceptor ParametersInterceptor
for processing, allowing for the automatic setting of member variables within an action. As per the documentation for FileUploadInterceptor
, parameters corresponding to the uploaded multipart form data fields <file name>
, <file name>ContentType
, and <file name>FileName
are added.
Before the call to appendAll
, we can observe that the actions parameters hold a single value, the malicious multi-part parameter named “uploadFileName” which contains a path with unsafe path traversal characters. It has not been subjected to any sanitation, as it is not intended as part of the file upload.
After the call to appendAll
, we can see a new parameter with a key name of “UploadFileName” exists containing the upload’s expected file name. The two key values can exist at the same time as the first character in each is in a different case (lower/upper).
The ParametersInterceptor
will now begin to process the action parameters, and it will call a setter method in the action, if a setter exists that matches the name of the parameter. Below we can see the action parameter named “UploadFileName” calls the actions setter setUploadFileName
and passes the parameter “good.txt”, which is the expected file name that has been sanitized to ensure it does not contain any path specifiers.
Next the action parameter named “uploadFileName” is processed, we can see that the same setter setUploadFileName
is called, even though the first character is a lowercase “u”. We can observe that the safe file name “good.txt” is replaced with the malicious file name “..\..\..\..\..\..\evil.bin”. This file name contains path specifiers that have not been sanitized, and allows for path traversal to an arbitrary location via double dot path notation.
Finally, once the underlying Struts interceptors have done their work, the action’s custom logic is executed and the uploaded file is unexpectedly copied to an arbitrary location.
We can see from stepping through the public PoC, that for a Struts based web application to be vulnerable to arbitrary file uploads via CVE-2023-50164, the following conditions must be met.
- The Struts configuration must enable the interceptor
FileUploadInterceptor
. This is required, as the HTTP parameter pollution occurs viaorg.apache.struts2.dispatcher.HttpParameters#appendAll
duringorg.apache.struts2.interceptor.FileUploadInterceptor#intercept
.
- A Struts action must implement custom logic that copies an uploaded file to a destination path, based on a file name which is provided via a setter routine. This is required as the HTTP parameter pollution allows for two OGNL statements to call the same setter routine twice, once with the expected file name that has been sanitized, and a second time with an unexpected file name that contains unsafe path traversal characters.
It is likely these conditions are going to be met in some real world production applications, due to how Struts is intended to be used, specifically how the FileUploadInterceptor
is intended to auto wire the uploaded files parameters to an actions member variables via setters.
However, exploitation of this vulnerability will be target-specific based on the differing target action’s endpoints, the naming convention of the expected uploaded file name, and any other target-specific restrictions that may need to be overcome.
Remediation
Vendors who develop applications that use Apache Struts should upgrade to Struts 2.5.33, Struts 6.3.0.2, or greater to remediate CVE-2023-50164.
Report as Emergent Threat Response
Report as Exploited in the Wild
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below: