On February 20, 2019, Alert Logic research teams began tracking vulnerabilities affecting users of Jenkins which could allow an attacker to run malicious software remotely. That same day new detection content was deployed to monitor for abuse and over the following hours teams in research and security operations began managing exploit attempts in the wild and raising incidents to customers.
The content deployed included telemetry signatures to monitor for events. This first stage of detection requires additional support to manage and escalate to “manual” incidents. As a customer, if you were affected, these would have been escalated over the phone to your designated contact and you would see them in the user interface as “[M] Multiple CVE Jenkins Script/Pipeline Request compile-time RCE”.
This process expedites detection and incident response. Later permanent incident content will be built which contains more detail about the incident and logic for prioritization.
As the situation developed, configurations for other tools in the Alert Logic solution, such as vulnerability and WAF content, was developed and distributed to teams.
Many vulnerabilities never see the light of day to become exploitable by malicious actors. In this case, it took around a month for anyone to produce successful proof-of-concept (POC) code and, from there, less than a few days to be seen in the wild. As these situations develop, Alert Logic teams monitor for changes like this in the threat landscape so we can react appropriately and efficiently.
This vulnerability allows remote attackers to inject code via “Meta-Programming” compilation, a feature designed to allow evaluation of code snippets, into one of three plugins for Jenkins (Declarative, Groovy or Script Security). Using this behavior, attackers can cause a victim’s hosts to fetch remote code payloads and execute them.
- On a remote host you control
- Compile your exploit class “Attack1” and create a jar
- Create the directory structure within your web root that corresponds to the Jenkins web attack payload
- On the attacking machine: Send a web request to a Jenkins target with a pipeline script payload that tells the Jenkins target to grab a snippet; the payload tells it that the snippet is on your host
- Compromise causes a connection from Jenkins to your host and grabs the jar file – from the jar file it imports your class, “Attack1”.
- Bash commands in “Attack1” are then executed by Jenkins
In a Nutshell
A feature of the Jenkins Pipeline API allows simplistic “Meta-Programming” compilation as a development “evaluation” feature of code snippets. By utilizing known classes/methods within an available abstraction library (such as Grape (from Groovy)), malicious code objects can be remotely fetched and imported within a compile-time primitive, leveraged within the Request URI.
Each vulnerability was triggered from a single Jenkins security advisory here:
Exploit code for this has been available in GitHub since approximately February 15, 2019.
Attribution for this discovery was credited to Orange Tsai.
|Wednesday 20th Feb 2019
|Thursday 21st Feb 2019 (Less than 24 hours after initial discovery)
|Friday 22nd Feb 2019
A feature of the Jenkins Pipeline API allows simplistic “Meta-Programming” compilation as a development “evaluation” feature of code snippets. By utilizing known classes/methods within an available abstraction library in one of the linked CVEs below, malicious code objects can be remotely fetched and imported within a compile-time primitive, leveraged within the Request URI.
CVE-2019-1003000 (Script Security)
CVE-2019-1003001 (Pipeline: Groovy)
CVE-2019-1003002 (Pipeline: Declarative)
Disclosure Article 2019-02-20
Jenkins Security Advisory 2019-01-08
Where 200 OK responses containing a stack trace occur, in the Request URI class names can be matched to elements of the trace to indicate partial execution by the process, which would require investigation.
Examples of likely success are a 200 Response, containing JSON (as below), indicating successful job process exit:
Recommendations are to check for any available updates as per internal patching policy and to consider only running Jenkins environments internally with no public-facing egress.