- CVE-2024-23897, announced on January 24, 2024, is a vulnerability in Jenkins CI/CD, which can result in arbitrary files being read.
- As of January 30, 2024, Censys has observed 83,509 Jenkins servers on the internet, 79,952 (~96%) of which are potentially vulnerable.
- Users are urged to upgrade to Jenkins 2.442 for the standard release of Jenkins and 2.426.3 for Long-Term Support (LTS) editions.
- When possible, Jenkins servers should not be directly connected to the internet.
Jenkins servers on the internet.
On January 24th, 2024, a critical-level vulnerability was announced for the Continuous Integration and Continuous Deployment (CI/CD) system Jenkins, which is currently being tracked as CVE-2024-23897 (vendor advisory 3314). When successful, an unauthenticated attacker could utilize a Remote Code Execution (RCE) to facilitate the job of reading arbitrary files (with some caveats).
With the default configuration, an unauthenticated attacker has no default permissions and can only read the first two or three lines from an arbitrary plaintext file. When authenticated, an attacker can view the entirety of any plaintext file.
On the other hand, if the Jenkins server has been configured with one of the two “dangerous” options listed below:
- “Allow users to sign up”
- “Allow anonymous read access”
Users with the above permissions enabled can read the entirety of both plaintext and binary files (although the binary files are converted to plaintext).
The issue stems from one of the programming libraries that Jenkins uses to parse arguments that are sent to a command-line utility. The API in question, args4j, has a feature that replaces “@” characters, followed by a file path with the file’s actual contents. Versions of Jenkins LTS prior to and including 2.426.2 and Jenkins release 2.441 and earlier do not disable this specific feature, the result of which allows an attacker to read arbitrary files on the Jenkins file system.
The few Proof of Concept exploits that have been released thus far have only been able to read arbitrary files; they are not executing arbitrary commands. This means that an attacker can potentially read sensitive files such as /etc/passwd (which, in reality, isn’t all that sensitive given that the real hashed passwords are in /etc/shadow). Using this exploit alone will not give the attacker a remote shell. However, an attacker could get lucky and find a password stored in some specific file, which could, in turn, be used to gain further access.
In short, while this exploit executes a command, it’s limited to just the utilities the Jenkins server has access to (like the Jenkins-CLI over a WebSocket), the results of which can be potentially used to gain elevated access.
This is not to say this isn’t a problem; it is technically an “RCE” in that a (specific) command is executed, and we are in no way downplaying this. We are also not saying that an attacker could not find a file that could be used to gain additional access (like a private SSH key); it’s just that so far, the severity is greatly limited based on the Jenkins server configuration.
For the details of the different configuration severities and a great writeup of exactly the types of data that can be exfiltrated, we highly recommend Horizon3.ai’s writeup of CVE-2024-23897 and Sonar’s post on the same topic.
To understand why this could be a problem under the right conditions, we first need to understand what Jenkins is, what it does, why people use it, and the potential security ramifications of one of these services getting owned.
What is Jenkins?
Jenkins is, at its core, a software build and delivery system. Anyone who has worked in an organization or field that requires programmers and developers has probably had to use a software build system at one point or another. Jenkins is one of the most well-known (sometimes infamous) continuous integration platforms. It is open-source and readily available to anyone wishing to use it. Along with “simple” tasks such as compiling one or more projects and creating packages, Jenkins can also automatically deploy these applications into customer networks.
This service is often a catalyst for an entire organization’s code deployment cycle, and it is because of this we can better understand why it is considered a highly valuable target for attackers.
Jenkins is the Supply Chain…
…or, at least, a very critical part of it.
In general terms, if any single product were considered the one true soft underbelly of a software company’s (or any development team’s) supply chain, it would be its build servers. Not only does this server hold (multiple) copies of an organization’s source code, but it often contains all of the bits and bobs that make up a single build, which can include keys, configurations, and passwords needed for an application to be assembled and deployed (although this will be build project specific). Often, Jenkins is used as a final determinant as to whether a piece of software is ready for production.
In a worst-case scenario, an attacker who can modify a build on a Jenkins server could theoretically poison both the build and deployment pipeline by injecting malicious code or commands as part of the job. And it’s happened before with the 2020 SolarWinds incident, where bad actors could install backdoors in the company’s Orion network monitoring software using their CI/CD pipeline. It was then automatically deployed to thousands of customers, masked as a normal update.
“To establish a foothold into the organization, the threat actor compromised the “heart” of the CI/CD pipeline, where code is tested, wrapped, containerized and signed, then successfully changed SolarWinds’ source code.” – CyberArk
Incidents like SolarWinds2k make access to a Continuous Integration (CI) or Continuous Deployment (CD) system a figurative goldmine for a would-be attacker. Or at the least, a highly sought-after point of entry.
This is not to say this Jenkins vulnerability is the same as the vulnerability used in the SolarWinds attack, just as an example of what could possibly be achieved with administrative access to a company’s build and deployment systems.
The Censys Perspective
A note to readers.
In the following sections, we treat any Jenkins LTS release less than or equal to version 2.426.2 and Jenkins release versions less than or equal to 2.441 as vulnerable to this CVE, as per the vendor advisory. This does not take into account whether the proper conditions are in place to read the entirety of both text and binary files (anonymous read access or authenticated users), as our scanner doesn’t directly report this level of detail, and it is not meant to say the world is on fire; we are just reporting the raw number of Jenkins servers on the internet to give an idea of the potential scope of this issue.
Jenkins on the Internet
In total, Censys observes 83,509 Jenkins servers on the Internet. Of those, 79,952 hosts are running a vulnerable version, while only 3,557 hosts have been patched with one of the fixed versions. This means that only 4.2% of the hosts running Jenkins on the internet are safe from this CVE, and 95.7% are potentially vulnerable.
The above screenshot shows the last eight days of vulnerable versus non-vulnerable Jenkins servers we could find on the public internet. We see that on January 25th, 2024, a day after the vulnerability was announced, a little over 300 servers were running the latest non-vulnerable versions. Over the next few days, we will see a consistent number of Jenkins servers being taken offline and/or upgraded to the latest version.
* 2024-01-24 is the advisory release date. Note our statistics here were pulled at 11 AM ET.
We’ve seen this same pattern before with products like Confluence, where a vulnerability is announced, and instead of seeing a consistent number of online servers in total, we see decreases in the number of online servers overall. This indicates that when a vulnerability is announced, administrators will remove them from the internet instead of upgrading their servers, either by putting them behind a firewall or taking them offline completely. This could also indicate that many of these servers were not being used in the first place (as in, they were test instances or something similar).
The graphs and tables below represent the number of vulnerable versus non-vulnerable versions of Jenkins across all autonomous systems and countries where they reside as of January 30th, 2024.
Autonomous Systems (January 30, 2024)
|HWCSNET Huawei Cloud Service
Countries (January 30, 2024)
Vulnerable Jenkins Servers in Quantum Space
Censys suggests that administrators take careful note of all Jenkins services running on their hosts, as we have found just under 600 hosts on the internet that are running multiple versions of the Jenkins software over several ports and a little over 60 hosts that have both a vulnerable and non-vulnerable version of Jenkins.
For example, in the screenshot below, we see a single host running a patched version of Jenkins LTS on TCP port 80 but a vulnerable version running on TCP port 9001.
Identifying Jenkins Services
With Censys, you are one search query away from uncovering all of the running Jenkins servers on the internet:
One of the easiest ways to identify not only whether a host is running a Jenkins server but also obtain the exact version of the running service is to analyze the HTTP response headers and look for the existence of the X-Jenkins key, the value of which will often be the actual version of the server.
A host running Jenkins.
More often than not, making an HTTP request to the Jenkins server will result in a 403 status code, which informs us as the client that the server requires authentication; in other words, if you go to that URL in your browser, you will see a login form.
The same host but in a browser.
But the above screenshot is not the only view you can see with Censys and Jenkins; a Jenkins server can be configured so that anonymous/guest access can be given to the general internet, which gives any user the ability (at the very least) to view the various jobs and builds that are currently configured.
If you modify the Censys search query to include an HTML title search, one can find many examples of Jenkins servers with global read access to the system:
It should be noted that many of the Jenkins servers found with read access to the dashboard are not necessarily misconfigured, as many open-source projects utilize Jenkins as a means to build and test their software. But it is something to note.
Differentiating Jenkins LTS from Jenkins Release
In the advisory, we see that versions of Jenkins that are less than or equal to version 2.441 are vulnerable to this CVE. On the other hand, versions of Jenkins LTS less than or equal to 2.426.2 are also vulnerable. Since there is a little overlap between these two code trees, we need a way to differentiate a Jenkins LTS (Long Term Support) server and a normal Jenkins server.
Thankfully, the value of the version in the X-Jenkins HTTP response header will either include three digits (major, minor, patch, separated by a dot) for LTS releases and only two digits (major, minor, separated by a dot) for standard releases. For once, we have a vendor that does semantic versioning correctly.
What can be done?
- Refer to the vendor advisory, which states users should upgrade to Jenkins 2.442 or LTS version 2.426.3.
- Use this Censys search query to find Jenkins servers exposed to the internet.
- Censys ASM customers will have access to a new risk that will identify potentially vulnerable Jenkins servers (search for “CVE-2024-23897”).