-

3 min read

Atlassian Confluence Server (CVE-2023-22518) - Improper Authorization

Atlassian Confluence Server (CVE-2023-22518) - Improper Authorization

CVE-2023-22518 is a critical vulnerability in Atlassian Confluence Data Center and Server. The vulnerability could potentially allow unauthenticated attackers with network access to the Confluence Instance to restore the database of the Confluence instance and eventually execute arbitrary system commands.

Technical Details

After performing a patch diff between the patched and unpatched versions, we identified the addition of two new annotations, namely, @WebSudoRequired and @SystemAdminOnly, in various Action classes.

Initially, we attempted to brute-force the routes leading to these specific actions, but this approach yielded no success. We then turned our attention to the struts.xml file, which contains information about action and namespace-based routing, as well as interceptors, hoping to uncover insights. However, nothing immediately stood out.

Additionally, we noticed a regex change in the SafeParametersInterceptor, which was related to a previous critical CVE-2023-22515 that had led to authentication bypass. We dedicated a significant amount of time trying to exploit this change, but were unable to make any breakthroughs. Our investigation led us to the understanding that in the case of ActionObject.getXYZ.getABC[N]=ANYTHING, where N must be a digit, the SafeParametersInterceptor would not consider the parameter key as a complex parameter and would permit OgnlValueStack.setValue(...).

The discovery revealed a complex hurdle: locating a method capable of facilitating authentication bypass through property modifications. This process necessitated the existence of a getter returning a collection or array. Furthermore, an index with a manipulable setter was essential. We then redirected our focus to the struts.xml file, scrutinizing its contents for any potential leads. Upon closer inspection, it was evident that the /json namespace enhances the /admin namespace's functions. Consequently, routes crafted for the /admin namespace can also be accessed via the /json namespace.

In the context of the /json namespace, the request routing process involves passing through a series of interceptors. One of these interceptors, known as the WebSudoInterceptor, performs checks based on the request URI.

WebSudo, a security feature commonly associated with Atlassian Confluence, plays a crucial role here. It requires users to re-authenticate themselves with elevated privileges, typically their password, before they can perform critical operations.

Specifically, the WebSudoInterceptor performs the following checks:

  1. If the request path is /authenticate.action, it is skipped.
  2. If the request path is /admin, it checks whether the WebSudoNotRequired attribute is not null.
  3. For any other request path, such as those in the /json namespace, it ensures that the WebSudoRequired attribute is null. This condition suggests that the WebSudoRequired annotation is not present at either the class, package, or method level. If this condition is met, the WebSudo check, which is responsible for initiating a secure admin session, is skipped.

The objective now is to identify an action (class) that lacks any authorization or authentication checks at the HTTP handler method level.

The subsequent phase involved conducting a brute-force of all the endpoints/actions within the /admin/ namespace to /json/. The objective was to monitor the responses and identify any noteworthy findings. During this, an observation was made when attempting a GET request on /json/setup-restore.action, which resulted in a 405 Method Not Allowed response. Further examination of the code confirmed that it lacked the WebSudoRequired annotation and did not implement any secondary authentication checks within the method handler. In essence, this meant that by supplying the correct parameters, the request could potentially succeed without requiring any form of authentication.

HTTP

1POST /json/setup-restore.action?synchronous=true HTTP/1.1
2Host: localhost:8090
3Accept-Encoding: gzip, deflate, br
4Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryT3yekvo0rGaL9QR7
5X-Atlassian-Token: no-check
6Content-Length: 277538
7
8------WebKitFormBoundaryT3yekvo0rGaL9QR7
9Content-Disposition: form-data; name="buildIndex"
10
11false
12------WebKitFormBoundaryT3yekvo0rGaL9QR7
13Content-Disposition: form-data; name="file";filename="exploit-restore.zip"
14
15ZIP_DATA
16------WebKitFormBoundaryT3yekvo0rGaL9QR7
17Content-Disposition: form-data; name="edit"
18
19Upload and import
20------WebKitFormBoundaryT3yekvo0rGaL9QR7--

Interestingly, passing synchronous=true what actually worked for us. This was a simple change from false to true when the earlier request was not resulting in a successful restore, even when a task was created to restore.

Nuclei Template

Due to the nature of this vulnerability, to restore the state of Confluence instance to attacker-controlled data/users. We're releasing a detection-based template rather than a full exploit-based template for this CVE.

Related stories

View all