Junkins helps you decrypt Jenkins passwords

Junkins

(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

https://github.com/chris408/junkins/