Threat Intelligence and Security Incidents

Vulnerability Analysis | Apache Struts Remote Code Execution Vulnerability S2-066 (CVE-2023-50164)

On 8 December, Apache officially released a security advisory fixing a Struts remote code execution vulnerability, S2-066 (CVE-2023-50164).

▌About Apache Struts2

Apache Struts2 is an open-source Java Web application development framework designed to help developers build flexible, maintainable, and scalable enterprise-class Web applications.

After analysis and assessment, this vulnerability is determined to be of low exploitation difficulty. Attackers can cause directory traversal by polluting relevant upload parameters, which under specific code environments could lead to uploading a Webshell and executing arbitrary code.


▌Affected Range

  • 2.5.0 <= Apache Struts <= 2.5.32,

  • 6.0.0 <= Apache Struts <= 6.3.0


▌Vulnerability Remediation

The official recommendation is to upgrade to the following versions:

  • Apache Struts >= 2.5.33

  • Apache Struts >= 6.3.0.2

The official site has released new versions to fix this vulnerability, urging affected users to update for protection as soon as possible. Download link: https://struts.apache.org/download.cgi#struts-ga


▌Vulnerability Analysis

1. Vulnerability POC

No specific path; depends on the code of the specific environment

2. Code Analysis
Parameter Pollution
  • In the org.apache.struts2.interceptor.FileUploadInterceptor#intercept method, the upload is used to add request parameters

  • According to the comments, it can be understood that this class is an interceptor for file uploading, which adds parameters related to file uploading to the HttpParameters object.

  • It can be understood that FileUploadInterceptor will obtain three parameters, namely, the above-mentioned upload, uploadContentType, and uploadFileName. Developers can obtain the content of these parameters by defining the relevant setter methods in Action.

  • However, the parameters obtained in FileUploadInterceptor are stored in objects of the HttpParameters type. HttpParameters is case-insensitive to parameters. HttpParameters stores both uppercase and lowercase forms of parameter names, where one side will overwrite the other via the setter method.

  • A breakpoint was set on the setter method, and it was found to be called only once. According to the method name in the call stack and experience, it can be directly understood that it is called through reflection. Being called only once is definitely related to the acquisition logic of the method name. Generally, things related to Bean derive the setter/getter method name based on the member's name, for example, capitalizing the first letter of the member's name and then appending "set".

  • Therefore, the UPLOAD in the constructed request was changed to Upload, and the setter method was found to be successfully called twice. Thus, the latter call will overwrite the former. According to the output of execute, it can be known that name="upload" overwrote name="Upload". The related logic here is reflected in the com.opensymphony.xwork2.interceptor.ParametersInterceptor#setParameters code.

  • Originally, in the HttpParameters#parameters member, the order was lowercase first and uppercase starting later "HashMap". However, the acceptableParameters type here is TreeMap, and the order changed after reading the content from HashMap and inserting it into TreeMap.

  • From this, it can be known that the content of the parameter with the capitalized initial can be overwritten by using the lowercase mode.

Directory Traversal
  • The directory traversal logic is in JakartaMultiPartRequest#processUpload. The path of the uploaded content is uncontrollable. The file upload parameters are stored in temporary files created by the Commons Fileupload library, and the filenames are also uncontrollable.

  • In FileUploadInterceptor#intercept, when obtaining the uploaded filename, the filename obtained will be truncated by the JakartaMultiPartRequest#getCanonicalName method.

Therefore, requests using the following method will not succeed

  • Directory traversal cannot occur within the Struts framework itself. According to the characteristics of historical S2 vulnerabilities, it can only occur in business code during secondary development.

  • If the business logic itself does not perform checks, it may lead to directory traversal. This can be achieved simply by overwriting the member uploadFileName in Action. name="uploadFileName" will be recognized as a form parameter instead of a file parameter in JakartaMultiPartRequest#processUpload, so its content will not pass through FileUploadInterceptor. The parameters will eventually be added to Action through ParametersInterceptor#setParameters.

File Upload

Depending on the specific business logic code, if no self-check is performed, it may lead to file upload, which in turn leads to command execution.

Security Validation Rules

On 12 December, the attack simulation for this vulnerability was added to the Security Metrics Validation Platform. You can search for the keywords "Struts2" or "CVE-2023-50164" in the platform to obtain the relevant attack simulation validation actions. This allows you to verify whether your security defense system can effectively counter the vulnerability. The platform ensures your validation process is safe and harmless in an industry-unique manner.

Reference Source: https://github.com/wy876/POC/blob/61fd6427a6c4f9048ccd8eba28c63b2d88701638/Apache%20Struts2%20CVE-2023-50164.md#L5