CVE Explained
g4rg4m3l,
Sep 03
2024
CVE-2024-27198 is an authentication bypass vulnerability discovered in the JetBrains TeamCity continuous integration (CI) and continuous delivery (CD) server. It affects versions before 2023.11.4.
The vulnerability was first identified by Rapid7’s vulnerability research team in February 2024, led by Principal Security Researcher Stephen Fewer, and disclosed on March 4, 2024, alongside CVE-2024-27199 an authentication bypass vulnerability found in the same TeamCity server.
With a Critical CVSS rating of 9.8 out of 10, this vulnerability has been discovered in the web component of TeamCity, which allows an unauthenticated attacker to bypass authentication checks when accessing the server via HTTP(S), potentially leading to full compromise of the server, including unauthenticated remote code execution (RCE).
As the JetBrains TeamCity server is widely used by enterprises worldwide to assist in the automation of software creation, testing, and deployment, exploiting a vulnerable server can have catastrophic consequences.
These include injecting malicious code into public-facing applications, disclosing proprietary, personal, financial, and other sensitive data, and gaining full control of organizational systems through a supply chain attack.
This vulnerability could have an even greater impact when considering that using tools like Shodan enables the identification of public-facing infrastructure affected by this vulnerability.
// Import required libraries
const { JSDOM } = require('jsdom');
describe('Visual Text Editor Tests', () => {
let document;
let editor;
beforeEach(() => {
// Simulate the HTML environment
const dom = new JSDOM(`
<div>
<div id="editor" contenteditable="true" class="text-editor"></div>
<button id="bold">Bold</button>
<button id="italic">Italic</button>
</div>
`);
document = dom.window.document;
// Initialize the editor
editor = document.getElementById('editor');
});
test('Editor initializes correctly', () => {
expect(editor).not.toBeNull();
expect(editor.contentEditable).toBe('true');
expect(editor.textContent).toBe('');
});
test('Typing text into the editor', () => {
editor.textContent = 'Hello, world!';
expect(editor.textContent).toBe('Hello, world!');
});
test('Applying bold formatting', () => {
// Simulate selecting text and clicking the Bold button
const boldButton = document.getElementById('bold');
document.execCommand = jest.fn(); // Mock execCommand
boldButton.addEventListener('click', () => {
document.execCommand('bold', false, null);
});
boldButton.click();
expect(document.execCommand).toHaveBeenCalledWith('bold', false, null);
});
test('Applying italic formatting', () => {
// Simulate selecting text and clicking the Italic button
const italicButton = document.getElementById('italic');
document.execCommand = jest.fn(); // Mock execCommand
italicButton.addEventListener('click', () => {
document.execCommand('italic', false, null);
});
italicButton.click();
expect(document.execCommand).toHaveBeenCalledWith('italic', false, null);
});
test('Clearing the editor content', () => {
editor.textContent = 'Temporary text';
editor.textContent = ''; // Clear the content
expect(editor.textContent).toBe('');
});
});
On March 4th, JetBrains disclosed two authentication bypass vulnerabilities on TeamCity Server, identified as CVE-2024-27198 and CVE-2024-27199. The release acknowledged the team at Rapid7 as the ones responsible for the discovery.
Rapid7 published a blog post containing the full technical details of these vulnerabilities, along with their respective exploits. In the same post, Rapid7 mentioned that they’d been in discussions with JetBrains since February 2024 regarding the coordination for the publication of these vulnerabilities.
Rapid7 stated that JetBrains had suggested privately releasing patches for CVE-2024-27199 and CVE-2024-27198 before making the vulnerabilities public, which clashes with Rapid7's vulnerability disclosure policy.
Silent patching is the act of privately fixing vulnerabilities without public announcement and without assigning them a Common Vulnerabilities and Exposures (CVE).
Rapid7 stated that there was a period of time where they didn't hear back from JetBrains and the public disclosure on March 4th came to them somewhat by surprise, a fact that JetBrains admitted in a post published on March 5 by Daniel Gallo, TeamCity solutions engineer.
The reason for this lack of coordination lies in the different viewpoints JetBrains and Rapid7 have regarding vulnerability disclosure.
Rapid7 insists that their Vulnerability Research and Disclosure Principles prioritize publishing vulnerability details within 24 hours, while JetBrains argues that publishing all technical details at the same time as releasing a fix allows anyone to immediately exploit the issue before all customers have had a chance to patch their servers.
By default, TeamCity exposes an HTTP web server on port 8111, which can be optionally configured for HTTPS.
Attackers may create Uniform Resource Locators (URLs) that bypass all authentication checks, allowing access to authenticated secured endpoints.
The TeamCity server is written in Java. As Rapid7 reports, the vulnerability is found in the classjetbrains.buildServer.controllers.BaseController class that implements the web-openapi.jar library, specifically in the way this class handles requests.
When we examine the updateViewIfRequestHasJspParameter method, we can see that the variable isControllerRequestWithViewName will be set to true if the current modelAndView has a name and if the servlet path of the current request does not end in .jsp.
If a request is made for a non-existent URI on the server, it will generate an 404 HTTP response, generating a servlet path of /404.html.
Since .html is not .jsp, isControllerRequestWithViewName will be set to true calling the getJspFromRequest method that will be passed to the ModelAndView.setViewName method from the Java Spring framework.
Taking a look at the getJspFromRequest method, we can see that it retrieves the string value of the HTTP parameter "jsp" for the current request.
It then tests to ensure that the value ends with ".jsp" and does not contain the path "/admin". This check is made to ensure administrator resources are not directly accessible.
The normal behavior when accessing an authenticated endpoint without proper authentications looks like this:
As expected it returns an Authentication required message.
Given the =mentioned conditions, an attacker can request a non-existent resource and add the value parameter to an authenticated URI path such as `/app/rest/server` in the HTTP parameter "jsp", ending the query string with “.jsp”.
/idontexist?jsp=/app/rest/server;.jsp
The non-existent resource will trigger a 404 HTTP response and the getJspFromRequest method will be called to retrieve the value of the HTTP parameter.
Since the request does not contain admin/ and ends with .jsp, the server will respond with the requested resource, allowing the attacker to access the authenticated endpoint `/app/rest/server`.
There are several ways attackers can exploit this vulnerability.
A vulnerable TeamCity server can be compromised by creating a new user with administrative privileges using an API endpoint such as “/app/rest/users”. This would enable an attacker to create a user with high privileges and gain access to the server."
We will utilize the cURL command line tool to send a malicious POST HTTP request to the user creation API endpoint. This request will contain the necessary information for creating a new user with administrative privileges.
curl -s -X POST 'http://teamcity:8111/idontexist?jsp=/app/rest/users;.jsp' -H "Content-Type: application/json" --data '{"username": "g4rg4m3l", "password": "g4rg4m3l", "email": "g4rg4m3l", "roles": {"role": [{"roleId": "SYSTEM_ADMIN", "scope": "g"}]}}'
As discussed earlier, the request must satisfy three conditions to bypass authentication:
1. Requesting a resource to generate a 404 HTTP response.
2. Including a query parameter “jsp” with the URI value of the authenticated resource we are attempting to access.
3. Ending the request with “.jps”.
By successfully bypassing the user creation authentication process, we can use the newly created user to log into the system via the server's web interface.
Another approach is to generate an administrator token and use it to gain access to the system.
We will use the cURL command tool to send a malicious POST HTTP request to the API endpoint that generates new administrator access tokens.
curl -s -X POST 'http://localhost:8111/idontexist?jsp=/app/rest/users/id:666/tokens/evil-token;.jsp'
We can check on the TeamCity web interface the token creation with success.
Upgrading to TeamCity version 2023.11.4 is the suggested remediation for both CVE-2024-27198 and CVE-2024-27199.
JetBrains notes the following option for upgrading on the release blog:
Upgrade from your recent version with the automatic update.
Download the new version from the JetBrains website.
Pull the TeamCity Docker image.
HTB releases new content every month that’s based on emerging threats and vulnerabilities. This allows teams to train on real-world, threat-landscape-connected scenarios in a safe and controlled environment.
In response to this vulnerability, we released CityOfRock, a Very Easy machine that showcases an authentication bypass along with a Remote Code Execution vulnerability (CVE-2024-27198) in JetBrains TeamCity.
Organizations like Toyota, NVISO, and RS2 are already using the platform to stay ahead of threats with hands-on skills and a platform for acquiring, retaining, and developing top cyber talent. Talk to our team to learn more.