Jenkins has a built-inย command line interface (CLI)ย to access Jenkins from a script or shell environment. We can download this cli from http://builder.htb:8080/jnlpJars/jenkins-cli.jar:
It seems to be vulnerable!
Now we can enumerate the Jenkins installation environment:
So we now know that the HOME folder is /var/jenkins_home, so we can get user flag like:
Jenkins stores the initial admin password inside /var/jenkins_home/secrets/initialAdminPassword. But in this case it didnโt work :(
Instead of using the Script Console to decrypt the encoded private key, we can use Pipeline SSH
First, we create a job:
On the next page, Iโll give it a name and select Pipeline:
On the next screen, Iโll define the pipeline. I can leave most of it as is, and just fill in the โPipeline scriptโ. The โtry sample pipelineโ button will offer a starting format.
If I save this and go back to the job page and click โBuild Nowโ, the job runs. In the โConsole Outputโ of the result, it shows the print:
These docsย show how to use the SSH Agent plugin. Iโll paste in their POC as the pipeline:
I clearly need to change the IP. Iโll also need to change the โcredentialโ. The docs show that it takes a list of strings. Trying with โrootโ fails:
Looking at the credential, it seems the ID is actually just โ1โ:
Iโll update to that:
And it works:
Iโve successfully run commands on the host.
Iโll update the command fromย uname -aย toย find /root. In this build, it returns a full read of all the files inย /root:
I could readย root.txt, but Iโll grab that SSH private key instead, changing the command toย cat /root/.ssh/id_rsa:
Itโs the same key as the previous method.
Alternative solving version 2 (Via Pipeline Dump Credentials)
If the pipeline can use the SSH key to get on to the host system as root, then it has access to the SSH key itself (Iโve already shown it can decrypt it).ย This postย talks about dumping credentials. Thereโs a good bit in the post about how to get it to print the credential unmasked. With a bunch of attempts and troubleshooting, I end up with: