Junkins helps you decrypt Jenkins passwords
(Jenkins logo: https://jenkins.io/ License: CC BY-SA 3.0)
Background
Jenkins is a popular open source continuous integration (CI) project that is used by many organizations. I’ve commonly seen Jenkins used to do the following: clone a repository from GitHub, compile it, test the code, and then push the successfully compiled and tested code off to production. Junkins was created to help automate my collecting of credentials that are saved in Jenkins servers.
Attackers best friend
Jenkins by design will need credentials to access to something in order to be useful. It is famous in the security world for its /script
URL, where it provides remote code execution (RCE) by design. What more could you want? I’ve also noticed that many Jenkins admins do not like the hassle of authenticating to their servers. To make their (and our) lives easier, they will disable security and authentication entirely.
Upgrades for security updates are commonly skipped. Developers are afraid of breaking their CI process by upgrading Jenkins.
Credentials
Since Jenkins will need access to something, developers will store passwords in the Jenkins server. However, they are not stored in clear text–but they might as well be. The Jenkins encryption keysecret.key
is found in the Jenkins home directory. The key stored in this file allows Jenkins to decrypt the passwords when they are needed.
Script console
The Jenkins script console will let you run any shell command as the user that this running Jenkins. It will also let you decrypt passwords with ease.
There are two URLs that can be used to access the scripting console, /script
and /scriptText
. I first wrote this app for /script
, and used BeautifulSoup to parse the command output. I figured out later that the /scriptText
URL will print only the command output, which was exactly what I needed. Thanks Jenkins!
Example uses
$ python junkins.py http://jenkins-server/scriptText/
Credential store dump:
username: testuser
password: testpassword
Alternatively, you can paste the groovy script from plain_postdata
into the /script
page directly.
Customization
If you’d like to customize the groovy script to suit your needs, modify the plain_postdata
file. This is the raw groovy script file that is POSTed to the Jenkins server.
A few examples of commands you can run with the /script
interface:
println "uname -a".execute().text
println "cat /etc/passwd".execute().text
- (insert reverse shell of your choice here)
Credential support
Junkins can decrypt the following credential types:
- Regular username and passwords
- Private keys
- Private keys with a passphrase
- API credentials
- JSON key files