Junkins helps you decrypt Jenkins passwords
(Jenkins logo: https://jenkins.io/ License: CC BY-SA 3.0)
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.
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 key
secret.key is found in the Jenkins home directory. The key stored in this file allows Jenkins to decrypt the passwords when they are needed.
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,
/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!
$ 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.
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
println "uname -a".execute().text
println "cat /etc/passwd".execute().text
- (insert reverse shell of your choice here)
Junkins can decrypt the following credential types:
- Regular username and passwords
- Private keys
- Private keys with a passphrase
- API credentials
- JSON key files