ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Sliver 植入体 Pivot 链传输客户端源码解析:pivotclients 包架构、密钥交换与隧道协商机制

Sliver 植入体 Pivot 链传输客户端源码解析:pivotclients 包架构、密钥交换与隧道协商机制 网络安全【免费下载链接】sliverAdversary Emulation Framework项目地址https://gitcode.com/gh_mirrors/sl/sliver点击查看免费下载导读本文以 Sliver 对抗仿真框架中implant/sliver/transports/pivotclients包为核心深入剖析植入体Implant在通过 Pivot 链pivot chain拨号上行时使用的传输客户端实现。该包是 Sliver 多层跳板通信的最后一公里它实现了嵌套客户端行为nested client behaviors与隧道协商tunnel negotiation并为 TCP 与 Windows 命名管道Named Pipe两种 pivot 监听器类型提供对等连接能力。读完本文你将掌握NetConnPivotClient的核心抽象、两级密钥交换流程、长度前缀帧协议与防滥用保护、C2 URL 选项解析规则以及上层传输路由tcppivot:///namedpipe://如何与之衔接。一、包定位Pivot 链上的客户端侧传输组件在 Sliver 的架构中Pivot 是指植入体之间相互中继流量的机制一台已经受控的机器中间节点运行 pivot 监听器其他植入体后续节点通过它间接连接 C2 服务器从而形成多级跳板链。整个链路涉及两个方向的能力监听器侧listener side由implant/sliver/pivots包维护PivotListener的创建、注册与生命周期管理客户端侧client side即本包pivotclients负责作为后续植入体主动拨号到上游 peer协商会话并复用其链路向服务器注册。根据 implant/sliver/transports/pivotclients/README.md 的说明本包实现了嵌套客户端行为与隧道协商运行时组件覆盖 namedpipe、namedpipe generic、namedpipe windows 以及 pivotclient 四类植入体侧特性。包内共有 5 个 Go 源文件与 1 个测试文件文件职责pivotclient.go核心 Pivot 客户端抽象协调嵌套传输长度前缀帧、读写、两级加密、会话关闭tcp.go基于 TCP 的 Pivot 客户端实现与 C2 URL 选项解析namedpipe.go命名管道 Pivot 的公共选项定义与解析平台无关namedpipe_windows.goWindows 命名管道传输实现构建条件IncludeNamePipenamedpipe_generic.go非 Windows 平台的命名管道客户端桩返回unsupported platformpivotclient_test.go会话 ID 解析与帧长度保护的单元测试所有源文件均位于 implant/sliver/transports/pivotclients/其中namedpipe_generic.go顶部带有//go:build !windows构建约束而namedpipe_windows.go同时受 Sliver 模板系统{{if .Config.IncludeNamePipe}}条件编译控制。二、核心抽象NetConnPivotClientNetConnPivotClient定义于 pivotclient.go是本包一切功能的载体。它把任何net.ConnTCP socket 或 Windows named pipe包装成已协商好的 pivot 会话连接对外只暴露四个方法type NetConnPivotClient struct { pivotSessionID []byte // 与上游服务器协商出的 pivot 会话 UUID conn net.Conn // 底层传输TCP / named pipe readMutex *sync.Mutex // 串行化读取 writeMutex *sync.Mutex // 串行化写入 peerCipherCtx *cryptography.CipherContext // 与直接 peer 之间的加密上下文 serverCipherCtx *cryptography.CipherContext // 与上游 C2 服务器之间的加密上下文 readDeadline time.Duration // 读写超时 writeDeadline time.Duration }关键设计点双层加密上下文peerCipherCtx加密本节点到直接上游 peer这一段链路serverCipherCtx加密本节点到 C2 服务器端到端这一段。数据在 peer 上被解密后再重加密转发因此中间节点无法读取会话内容这实现了嵌套客户端行为每一跳只对相邻一跳可见。读写互斥readMutex/writeMutex保证在多 goroutine 场景如并发发送信封与后台 ping下帧边界不被破坏。通用性TCP 与 named pipe 两种StartSession都返回同一个*NetConnPivotClient上层传输见第五节完全不需要关心底层是 socket 还是管道。此外包内定义了哨兵错误errInvalidPivotSessionIDpivotclient.go并在 pivotclient_test.go 中用TestParsePivotSessionID验证只有恰好 16 字节的数据才能被解析为 UUIDnil、15 字节与 17 字节输入都必须返回该错误。三、两级密钥交换从 Peer 到 Server 的会话建立KeyExchange()pivotclient.go是建立会话的入口分为peerKeyExchange与serverKeyExchange两个阶段全程对底层连接设置 deadline默认见第四节防止死锁。3.1 第一阶段与直接 Peer 交换密钥流程如下对应peerKeyExchangepivotclient.go本节点构造pb.PivotHello携带cryptography.PeerAgePublicKey本节点的 Age 公钥、PublicKeySignature以及本节点 Peer IDpivots.MyPeerID序列化后写入连接读取对端返回的PivotHello用cryptography.AgeDecryptFromPeer解密出会话密钥并校验签名要求会话密钥恰好 32 字节用该 32 字节密钥构造peerCipherCtx完成 peer 段加密上下文的初始化。这里的pivots.MyPeerID定义于 implant/sliver/pivots/pivots.go是每次进程执行都会重新生成的实例级 ID它通过crypto/rand读取 8 字节生成 64 位整数随机数不可用时回退到time.Now().UnixNano()generatePeerID。Peer ID 是链路中每条消息路由的依据。3.2 第二阶段经由 Peer 与上游服务器交换密钥serverKeyExchangepivotclient.go实现嵌套的精髓本节点用cryptography.RandomSymmetricKey()生成随机会话密钥cryptography.AgeKeyExToServer加密后放入pb.PivotServerKeyExchange并附上OriginID: pivots.MyPeerID将该消息封装为pb.PivotPeerEnvelope记录经过的 peer 列表[{MyPeerID, SliverName}]再套一层pb.Envelope{Type: MsgPivotPeerEnvelope}最后用peerCipherCtx加密写入连接——即借道 peer 把密钥交换请求递交给上游服务器读取响应信封校验类型必须为MsgPivotServerKeyExchange解密得到服务器的SessionKey解析为 16 字节 UUID 作为pivotSessionID保存此后所有上行数据都携带该会话 ID。值得注意的工程细节响应阶段的读 deadline 被放宽到5 分钟pivotclient.go源码注释明确解释了原因——该请求需要往返服务器如果上游植入体使用慢速协议来回可能需要较长时间。这说明 Sliver 在实现上对多层慢速中继场景做了显式容错。四、帧协议长度前缀 双层信封 防滥用保护4.1 写入路径writepivotclient.go采用经典的 4 字节小端长度前缀 负载的帧格式先用lengthOf把消息长度写成 4 字节 little-endianlengthOf定义见 pivotclient.go若长度前缀未能一次写完 4 字节直接返回ErrFailedWrite定义于 tcp.go负载部分使用循环Write直至写满容忍部分写入。4.2 读取路径与安全上限readpivotclient.go用io.ReadFull依次读取 4 字节长度与负载并做两层防护长度 ≤ 0 时返回zero data length错误长度超过pivots.MaxFrameLength时返回pivots.ErrFrameTooLarge。MaxFrameLength定义为512 MiBimplant/sliver/pivots/pivots.go源码注释给出了明确的防护动机损坏或失步的长度前缀可能被解析为接近 4 GiB 的值从而触发足以压垮植入体的大内存分配参见 BishopFox/sliver#1452。512 MiB 远高于任何真实中继消息的体积又远低于致命分配阈值。对应的测试TestNetConnPivotClientReadRejectsOversizedFramepivotclient_test.go用net.Pipe模拟对端写入MaxFrameLength1的长度前缀断言读取在 3 秒内以pivots.ErrFrameTooLarge失败TestNetConnPivotClientReadAcceptsValidFrame则验证合法负载可被完整、原样读出。这两条用例共同构成了帧解析的拒绝越界、接受合法边界。4.3 信封封装规则WriteEnvelopepivotclient.go和ReadEnvelopepivotclient.go是上层与传输之间的消息接口封装规则非常精细上行普通消息先用serverCipherCtx加密包进PivotPeerEnvelope携带PivotSessionID与自己的 PeerID再整体套MsgPivotPeerEnvelope最后用peerCipherCtx加密而MsgPivotPeerPing与已存在的 peer envelope 属于不属于本节点起源的控制消息不用服务器密钥加密pivotclient.go下行先解 peer 层密文若收到的不是MsgPivotPeerEnvelope则报invalid message type随后检查 peer 列表首位是否为pivots.MyPeerID——如果不是我们这个 peer envelope 就不是发给我们的直接原样返回由上层转发实现链式中继只有确认自己是收件人时才用serverCipherCtx解密出真正的业务信封。这条路径完整实现了每一跳只解密 peer 段、端到端加密仍保持的嵌套传输语义正是 README 所述nested client behaviors and tunnel negotiation的代码落地。五、两种底层传输实现与 C2 URL 选项5.1 TCP Pivot 客户端tcp.goTCPPivotStartSessiontcp.go是本包最直接的会话入口func TCPPivotStartSession(peer string, opts *TCPPivotOptions) (*NetConnPivotClient, error) { conn, err : net.Dial(tcp, peer) if err ! nil { return nil, err } pivot : NetConnPivotClient{ conn: conn, readMutex: sync.Mutex{}, writeMutex: sync.Mutex{}, readDeadline: opts.ReadDeadline, writeDeadline: opts.WriteDeadline, } err pivot.KeyExchange() if err ! nil { conn.Close() return nil, err } return pivot, nil }拨号成功即执行第二节所述的两级密钥交换任何一步失败都会关闭连接并返回错误。5.2 NamedPipe Pivot 客户端Windows 实现NamedPipePivotStartSessionnamedpipe_windows.go先把 C2 URL 转换成本机管道路径再拨号address : \\\\ uri.Hostname() strings.Replace(uri.Path, /, \\, -1) conn, err : winio.DialPipe(address, nil)即\\主机名\路径的形式然后以与 TCP 完全相同的NetConnPivotClient构造流程完成密钥交换。它依赖github.com/lesnuages/go-winio库并被{{if .Config.IncludeNamePipe}}模板包裹——只有在生成植入体时启用了 named pipe 支持才会编译进二进制。非 Windows 平台的NamedPipePivotStartSessionnamedpipe_generic.go直接返回errors.New(unsupported platform)通过//go:build !windows保证两个同名函数永远不会同时编译。5.3 C2 URL 选项解析默认值与来源两个Parse*Options函数从拨号 URL 的查询参数中解析超时配置解析失败或参数缺失时回退到默认值参数TCP 默认值tcp.goNamedPipe 默认值namedpipe.go含义read-deadline10sdefaultDeadline10sdefaultNamedPipeDeadline单次读取操作的超时write-deadline10sdefaultDeadline10sdefaultNamedPipeDeadline单次写入操作的超时timeout—10sdefaultNamedPipeDeadlineNamedPipe 专属的连接建立超时ParseTCPPivotOptions与ParseNamedPipePivotOptions均使用time.ParseDuration解析因此支持10s、500ms、1m等 Go duration 字符串NamedPipe 版本在参数存在但解析失败时还会输出调试日志仅 Debug 构建启用便于定位配置错误。六、上层接入传输路由与心跳维持pivotclients 包并不自行决策协议而是被植入体的传输层按 URL scheme 分发调用tcppivot://在 implant/sliver/transports/session.go 中被路由到tcpPivotConnect(uri)该函数session.go调用ParseTCPPivotOptions(uri)与TCPPivotStartSession(uri.Host, opts)完成拨号namedpipe://在 implant/sliver/transports/transports_windows.go 的namedPipeConnect中被路由到ParseNamedPipePivotOptions(uri)与NamedPipePivotStartSession(uri, opts)。拨号成功后连接层会为 pivot 会话启动一个双路心跳 goroutine每分钟一次见 session.go 与 transports_windows.go向直接 peer 发送MsgPivotPeerPing携带纳秒级 Nonce同时向服务器发送MsgPivotServerPing分别验证上一跳存活与整条链路可达。这两类 ping 在WriteEnvelope中走不加密 server 段的特殊分支与控制消息通道解耦避免 ping 在高延迟链路上排队超时。pivotclient.go中与协议相关的消息类型全部来自protobuf/sliverpbMsgPivotPeerEnvelope、MsgPivotServerKeyExchange、MsgPivotPeerPing、MsgPivotSessionEnvelope等proto 定义可参考 protobuf/sliverpb/sliver.proto。七、会话生命周期与关闭会话结束后调用CloseSession()pivotclient.go它直接关闭底层net.Conn从而触发对端read返回错误并层层退出。上层Connection的cleanup回调发送ctrl/pingCtrl信号会终止心跳 goroutine 并清理隧道状态详见 session.go。此外会话的Stop()与cleanup()语义在nextSendEnvelopesession.go的注释中有明确说明生产者通道在清理后保持打开传输发送方必须依赖连接生命周期而非range发送通道来判断连接是否终结——这避免了 pivot 会话断开时发送方永久阻塞。从调用链可以推断CloseSession通常由上层 transport 连接在检测到io.EOF、密钥交换失败或连续错误超限opts.MaxErrors时触发与 pivots.go 中RemoveListener对监听器侧的生命周期管理形成对偶关系。八、小结pivotclients包虽小却是 Sliver 多级跳板通信中承上启下的关键一环抽象层NetConnPivotClient统一了 TCP 与 Windows NamedPipe 两种底层传输让上层只面对已协商好的加密连接安全层peer/server 两级密钥交换与双层信封封装保证中间节点只可转发、不可窃读健壮层4 字节长度前缀帧 512 MiB 上限 双向 deadline配合 pivotclient_test.go 的回归测试防止失步帧导致的内存崩溃接入层tcppivot://与namedpipe://两种 scheme 在 session.go 与 transports_windows.go 中完成路由心跳机制维持链路健康。对于希望深入 Sliver 内部或自行实现 pivot 协议的读者建议按以下顺序阅读源码先通读本包全部 6 个文件再对照 implant/sliver/pivots/pivots.go 理解监听器侧与MyPeerID、MaxFrameLength等共享常量最后回到 implant/sliver/transports/session.go 查看传输层如何组合这些能力——三者合在一起才能看到一条完整 pivot 链路从拨号、协商、加密中继到心跳保活的全貌。赞分享网络安全【免费下载链接】sliverAdversary Emulation Framework项目地址https://gitcode.com/gh_mirrors/sl/sliver点击查看免费下载相关推荐Sliver 植入体隧道处理器tunnel_handlers源码级解析Shell / SOCKS / 端口转发 / WASM 的隧道流协调机制Sliver 植入体隧道处理器tunnel_handlers源码级解析Shell / SOCKS / 端口转发 / WASM 的隧道流协调机制 导读 im网络安全Sliver 客户端核心包 client/core 深度解析会话状态、隧道编排与 RPC 协调机制Sliver 客户端核心包 client/core 深度解析会话状态、隧道编排与 RPC 协调机制 导读 client/core 是 SliverAdver网络安全Sliver 植入物 Pivot 通道管理深入解析横向移动、命名管道与 Pivot 图构建Sliver 植入物 Pivot 通道管理深入解析横向移动、命名管道与 Pivot 图构建 本文聚焦 Sliver Adversary Emulation F网络安全创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表