March 2017 witnessed two security advisories from Apache Struts2 – both involving a similar problem with the Jakarta-based file upload Multipart parsers (CVE-2017-5638). S2-045 addresses an issue with parsing the Content-type header on an erroneous multipart request, while S2-046 discusses the possibility of exploiting a multi-part file upload request’s content-disposition section. In both cases, it is possible to inject malicious OGNL expressions using the described attack vectors.
Our previous post explored the techniques involved in static analysis to detect these issues. In this post, we will dive into the dynamic analysis techniques to achieve the same goal.
The issue discussed by S2-045 can be detected using a GET request with a content-type of ‘multipart/form-data’ and an empty request body. This qualifies as a malformed multipart request and will trigger the error code path within the parser.
In the case of S2-046, we construct a POST multipart request with a large content-length header and embed the payloads in the filename attribute of the content-disposition header. The actual size of the request body need not match the value of the content-length header. The goal is to force an error using a value that’s larger than the acceptable request size as configured on the application server.
Numerous payloads may be used, depending on the goal of the attack and the filters used on the application server. In order to detect this vulnerability in WebInspect, we use two different payloads, each using a different set of classes. This increases the chance of bypassing the most common filters on the target server. The first payload attempts to inject a custom header in the HTTP response by accessing the com.opensymphony.xwork2.dispatcher.HttpServletResponse class and using the setHeader function.
The second payload is very similar to the Proof-of-Concept attack that was released with the original vulnerability disclosure. But, instead of executing an OS command on the server, WebInspect attempts to inject a random string into the HTTP response.
Below is an example request that uses both of the payloads.Note: We’ve observed that some servers may block requests with large content lengths. Hence, while the vulnerability may still be present, it is possible that the server temporarily disables the ability to exploit S2-046. However, the setting may be temporarily disabled to allow for identification of the vulnerable deployments.
Most filters are off by default. So, in a default setup, both payloads are expected to succeed. In order to attack a target server with a custom payload, the above templates may be used to create a custom check using the WebInspect SDK.