February 13th, 2020
Security Researcher, SafeBreach Labs
SafeBreach Labs discovered a new vulnerability in Atlassian Jira Server and Confluence Server software.
In this post, we will demonstrate how this vulnerability can be used in order to achieve privilege escalation, persistence and in some cases defense evasion by loading an arbitrary unsigned DLL into a service that runs as SYSTEM.
Additionally, we will present some of the potential malicious actions that could be undertaken by exploiting this vulnerability in the Jira Server and Confluence Server software.
Atlassian Jira Server and Confluence Server allows the user to host the Jira and Confluence services on-premise on a Windows machine.
Part of the services is executed as “NT AUTHORITY\SYSTEM,” which provides it with very powerful permissions.
Apache Tomcat (sometimes simply "Tomcat") is an open source implementation of the Java Servlet, JavaServer Pages, Java Expression Language and WebSocket technologies.
Tomcat provides a "pure Java" HTTP web server environment in which Java code can run.
Part of the Jira Server / Confluence Server are implemented using Apache Tomcat.
In this post, we describe the vulnerability we found in the Tomcat component in the Jira / Atlassian Server software. We then demonstrate how this vulnerability can be exploited to achieve privilege escalation, gaining access with SYSTEM level privileges.
Note: The Root cause of the vulnerability is identical on both software (Jira Server and Confluence Server). We will use Confluence Server to describe the vulnerability, but it’s the same on Jira Server as well.
In our initial exploration, we targeted the “Commons Daemon Service Runner” service (tomcat9.exe) based on the assumption that a service with high-permission-level access would provide the capability to induce privilege escalation.
After the Commons Daemon Service Runner service started, it executed tomcat9.exe as NT AUTHORITY\SYSTEM.
The service tries to load a missing DLL file, which eventually were loaded from the c:\python27 directory - which is in our PATH environment variable:
As you can see, the service was trying to load a missing DLL file (MSVCR120.dll), which eventually were loaded from the c:\python27 directory - our PATH environment variable.
Demonstrating a DLL hijacking vulnerability:
In our VM, the c:\python27 has an ACL which allows any authenticated user to write files onto the ACL. This makes the privilege escalation simple and allows a regular user to write the missing DLL file and achieve code execution as NT AUTHORITY\SYSTEM.
It is important to note that an administrative user or process must (1) set the directory ACLs to allow access to non-admin user accounts, and (2) modify the system’s PATH variable to include that directory.
In order to test this privilege escalation vulnerability, we compiled a DLL (unsigned) which writes the following to the filename of a txt file:
We were able to load an arbitrary DLL and execute our code as NT AUTHORITY\SYSTEM.
Once the OpenHardwareMonitor library is loaded, it tries to load a DLL using LoadLibraryExW:
It is using 0 for the dwFlags parameter.
According to MSDN’s LoadLibraryExW documentation:
If no flags are specified, the behavior of this function is identical to that of the LoadLibrary function.
As we can see in the screenshots, there are two root causes for the vulnerability:
Below we show three possible ways that an attacker can leverage the vulnerability we discovered and documented above.
The CVE-2019-20406 and CVE-2019-20400 vulnerabilities gives attackers the ability to load and execute malicious payloads using a signed service. This ability might be abused by an attacker for different purposes such as execution and evasion, for example:
The vulnerability gives attackers the ability to load and execute malicious payloads in a persistent way, each time the service is loaded. That means that once the attacker drops a malicious DLL in a vulnerable path, the service will load the malicious code each time it is restarted.
The service provides the attacker with the ability to operate as NT AUTHORITY\SYSTEM.
Aug 28th, 2019 - Vulnerabilities reported to Atlassian using BugCrowd
Aug 29th, 2019 - BugCrowd asked for a clarification
Aug 29th, 2019 - SafeBreach sent a more detailed PoC
Sep 4th, 2019 - Atlassian confirmed the vulnerability.
Oct 22nd, 2019 - SafeBreach asked Atlassian for a disclosure timeline and a CVE-IDs.
Nov 4th, 2019 - Atlassian mentioned that they can’t provide this information yet, and asked to open a support ticket in their support system.
Nov 11th, 2019 - SafeBreach reported the issue on Atlassian’s support system.
Nov 18th, 2019 - Atlassian mentioned that they opened two internal tickets and both are awaiting resolution.
Nov 20th, 2019 - SafeBreach asked Atlassian again for a disclosure timeline and CVE-IDs.
Nov 22nd, 2019 - Atlassian’s support forwarded the request to the security team.
Dec 10th, 2019 - Atlassian mentioned that they didn’t hear back from the security team yet.
Dec 19th, 2019 - Atlassian mentioned that they are waiting for CVE-IDs.
Dec 24th, 2019 - Atlassian freezed the ticket for a few days as the new CVE range they were expected hasn’t been released yet.
Feb 5th, 2020 - Atlassian mentioned that the security team reached out and provided CVE-2019-20406 (CONFSERVER-59428 ) and CVE-2019-20400 (JRASERVER-70407 )