π΄οΈJenkins
We could try to spam default credentials and from there gain access via the groovy console using a reverse shell.
If we cant then we should try to create a new account and create a job.
If we dont have the build options then we can get code execution via scheduling.
Method 1: Schedule
Clicking the βConfigureβ link in the sidebar leads back to the settings for the job, where Iβll look more closely at the βBuild Triggersβ section:

βBuild periodicallyβ seems promising. Iβll check that box, which gives a empty text field. Jenkins uses a schedule system similar to cron. Iβll enter β* * * * *β, and it warns me that this will run every minute:

Iβll save and after a minute, refresh the page, and thereβs a build in the history:

Hovering over the β#1β thereβs a dropdown:

βConsole Outputβ shows the job ran:

Method 2: Trigger Remotely
Running different commands waiting one minute between each one is a bit exhausting. Iβll disable the scheduled trigger. Looking at the other options for βBuild Triggersβ, βTrigger builds remotely (e.g., from scripts)β seems interesting. Checking it expands out asking for an βAuthentication Tokenβ:

I can try just adding a string as the token (say βTestTokenβ) and requesting the endpoint they give, but it doesnβt work:
Back during enumeration I found where I could create API tokens in my profile. Iβll head there and click βAdd new Tokenβ:

Iβll name it 0xdfToken and click generate:

Iβll also update the batch script with the job so that itβs clear why it triggered:

This post shows how to actually trigger the job. Iβll need to use the url of the form:
So for me, thatβs:
Thereβs no response from the server, but the job triggers, and a moment later thereβs console output:

Jenkins Enumeration
Look for Creds
Iβll look for the creds associated with the admin account. This could get more access in Jenkins, or perhaps give WinRM access to the host. This article talks about how each userβs information is stored in a config.xml file. This article talks about the encryption used to store secrets.
Note: Iβm still running commands by editing the job, triggering it, and then checking the console output. For the sake of readability, Iβll just be showing the output from this point on unless thereβs a reason to show it.
Looking at the previous console returns, itβs clear the job is running from C:\Users\oliver\AppData\Local\Jenkins\.jenkins\workspace\0xdf's job. Looking up a couple directories:
The user information is stored in /users/:
In that admin directory, thereβs a config.xml:
Iβll dump that file and save it to my local workstation:
Thereβs both a hash and an encrypted password.
Decrypt Password
I could try to brute force the hash, but decrypting the password will be easier. Most of the references that will come up on Google (like this one) show how to do this through the script console (/script), but as I showed above, I donβt have access to that.
I found two repos on Github that had methods for decrypting user passwords stored on Jenkins. This one is written in Go, and this one has a ton of Python scripts for pentesting Jenkins.
Both require the config.xml, as well as master.key and hudson.util.Secret, but from /secrets/:
master.key looks like itβs stored in hex:
In any case that the thing is not 256 bytes we can trim the new line by using the following commands.
I can verify I got the full thing by making sure itβs the same length, 256 bytes:
hudson.util.Secret looks like a binary file:

Iβll use PowerShell to base64 encode it:
Now I can copy that string and echo it into base64 -d on my local system to save it to a file.
Downloading the Go binary from jenkins-credential-decryptor like in these instructions works great:
The pwn_jenkins Python script works as well:
Last updated