Sliver 中的 AES-CBC 密文窃取(Ciphertext Stealing)加密实现指南
发布时间:2026/9/25 5:55:20来源:尧图网络
网络安全【免费下载链接】sliverAdversary Emulation Framework项目地址https://gitcode.com/gh_mirrors/sl/sliver点击查看免费下载导读本文围绕 sliver 仓库中 vendor 目录下gopkg.in/jcmturner/aescts.v1包展开深入讲解 AES-CBC 密文窃取Ciphertext Stealing简称 CTS模式的原理、Encrypt/Decrypt源码实现与调用链路。该包在本仓库中并非孤立存在——它是 Kerberos 5gokrb5AES 加密类型RFC 3962 与 RFC 8009的底层加密原语最终服务于 sliver 植入体implant的 SSH GSSAPI/Kerberos 认证场景。读完本文你将掌握该包的安装方式、API 语义、三种边界情况下的加解密行为以及它如何被上层 Kerberos 加密套件实际调用。一、包定位AES CBC 密文窃取模式vendor/gopkg.in/jcmturner/aescts.v1是一个提供AES CBC Ciphertext Stealing密文窃取加解密方法的 Go 包。包的文档定义非常简洁Encrypt and decrypt data using AES CBC Ciphertext stealing mode.使用 AES CBC 密文窃取模式加密和解密数据。与标准 CBC 模式不同CTS 模式的核心价值在于在保持 CBC 链式反馈结构的同时无需任何填充即可加密任意长度的数据。其算法参照 Ciphertext stealing - CBC ciphertext stealing 中的描述实现即交换最后两个密文块并将密文截断为原始明文长度。包内共两个文件README.md安装与导入说明即本文所依据的主文档aescts.go全部加解密实现包含Encrypt、Decrypt两个公开 API 与三个内部辅助函数。获取与导入方式摘自原文档go get gopkg.in/jcmturner/aescts.v1import gopkg.in/jcmturner/aescts.v1二、公开 API 与返回值语义aescts.go暴露两个函数aescts.go// Encrypt the message with the key and the initial vector. // Returns: next iv, ciphertext bytes, error func Encrypt(key, iv, plaintext []byte) ([]byte, []byte, error) // Decrypt the ciphertext with the key and the initial vector. func Decrypt(key, iv, ciphertext []byte) ([]byte, error)需要注意Encrypt的返回值有三个其中第一个返回值是next iv下一次加密使用的初始向量。根据源码注释其取值为加密输出的倒数第二块next-to-last block密文也就是最后一个明文块加密后的结果。这一设计使得该包天然支持流式多段加密上一段加密返回的 next iv 可以直接作为下一段加密的 IV 传入从而在任意长度边界上保持 CBC 链的连续性。三、Encrypt三种边界情况的处理策略Encrypt(key, iv, plaintext)的实现依据明文长度l与 AES 块大小aes.BlockSize固定 16 字节的关系分为三种路径aescts.go1. 明文 ≤ 一个块l 16此时直接对明文做**零填充zero padding**到 16 字节执行一次 CBC 加密然后原样返回。密文与返回的 next iv 均为完整的 16 字节块if l aes.BlockSize { m, _ zeroPad(m, aes.BlockSize) mode.CryptBlocks(m, m) return m, m, nil }注意仅在此分支使用零填充因为此时不存在“窃取”所需的第二个块而返回的 next iv 恰好是唯一的密文块本身链式状态得以保留。2. 明文是块大小的整数倍l % 16 0这是最体现 CTS 思想的路径先按普通 CBC 加密全部块然后交换最后两个密文块并将倒数第二块作为 next iv 返回if l%aes.BlockSize 0 { mode.CryptBlocks(m, m) iv m[len(m)-aes.BlockSize:] rb, _ : swapLastTwoBlocks(m, aes.BlockSize) return iv, rb, nil }源码注释对此做了权威说明For consistency, ciphertext stealing is always used for the last two blocks of the data to be encrypted... If the data length is a multiple of the block size, this is equivalent to plain CBC mode with the last two ciphertext blocks swapped.—— 即当数据长度是块大小的整数倍时CTS 等价于“普通 CBC 交换最后两个密文块”。3. 明文既超过一个块又不是块大小的整数倍一般情况这是最典型的 CTS 路径。实现步骤如下aescts.go先对明文零填充到块大小整数倍方便后续按块切分调用tailBlocks将数据切分为三部分其余块rb、倒数第二块pb、最后一块lb若存在rb用当前 IV 做 CBC 加密并把rb的最后一块作为新的“滚动 IV”之后pb、lb各自以前一块的输出作为 IV 链式加密交换最后两个密文块先输出lb再输出pbct append(ct, lb...); ct append(ct, pb...)将密文截断到原始明文长度ct[:l]返回lb作为 next iv再次印证next iv 是加密后的最后一个明文块。mode.CryptBlocks(rb, rb) iv rb[len(rb)-aes.BlockSize:] mode cipher.NewCBCEncrypter(block, iv) ct append(ct, rb...) mode.CryptBlocks(pb, pb) mode cipher.NewCBCEncrypter(block, pb) mode.CryptBlocks(lb, lb) // Cipher Text Stealing (CTS) // Swap the last two cipher blocks // Truncate the ciphertext to the length of the original plaintext ct append(ct, lb...) ct append(ct, pb...) return lb, ct[:l], nil正是“交换最后两块 截断”这两步让 CTS 在零填充开销的前提下处理了非整块明文——这是它与传统 PKCS#7/CBC 填充模式的本质区别。四、Decrypt逆向还原与密文长度校验Decrypt(key, iv, ciphertext)是上述过程的逆操作aescts.go实现要点如下防御性拷贝函数开头先把密文复制到新切片避免 Go 切片按值传递时共享底层数组导致调用方数据被改写源码注释明确说明了这一意图。长度校验若密文不足一个块大小直接返回错误Ciphertext is not large enough. It is less that one block size.整块倍数路径先交换回最后两个密文块再做普通 CBC 解密若密文恰好只有一个块则无法交换直接 CBC 解密。一般 CTS 路径先解密除最后两块外的其余块并滚动 IV用原始 IV 解密倒数第二块取其尾部npb字节npb 16 - len(ct)%16拼接回最后一个密文块补齐到整块随后逆序解密最后按message[:len(ct)]截断到原始密文长度。从代码结构可以推断解密算法严格遵循 CTS 的“窃取”语义最后一块密文先补齐再解密、倒数第二块在最后位置解密时以其补齐后的密文作为 IV从而完整恢复任意长度的明文。五、内部辅助函数三个辅助函数服务于上述主流程aescts.go函数作用tailBlocks(b, c)将字节切片切分为“其余块 倒数第二块 最后一块”三元组若不足两个块返回错误若仅有两个块则rb为 nilswapLastTwoBlocks(b, c)基于tailBlocks交换最后两个块并重组输出zeroPad(b, m)用零字节将数据补齐到m的整数倍对m0或空数据返回错误六、在本仓库中的真实调用链从 gokrb5 到 implant SSH该包并非仅作为独立工具存在而是 sliver 依赖的 Kerberos 加密栈的底层原语。梳理仓库中的引用关系如下1. 被 gokrb5 的 RFC 3962 / RFC 8009 加密类型调用gopkg.in/jcmturner/gokrb5.v7的 AES 加密类型直接 import 本包RFC 3962对应 Kerberos 加密类型 AES128-CTS-HMAC-SHA1-96 / AES256-CTS-HMAC-SHA1-96在 rfc3962/encryption.go 中EncryptData构造全零 IVivz : make([]byte, e.GetCypherBlockBitLength()/8)后调用aescts.Encrypt(key, ivz, data)DecryptData对称调用aescts.Decrypt(key, ivz, data)。RFC 8009对应 AES128-CTS-HMAC-SHA256-128 / AES256-CTS-HMAC-SHA384-192在 rfc8009/encryption.go 中同样以 16 字节全零 IV 调用aescts.Encrypt/aescts.Decrypt并针对 SHA384 变体将密钥长度特判为 32 字节。可见CTS 正是 Kerberos 规范中“AES-CTS”字面的实现来源上层负责密钥派生与 HMAC 完整性校验本包专注完成 CTS 模式的加解密。2. sliver implant 的 SSH GSSAPI/Kerberos 认证链路在 sliver 植入体侧gokrb5 经由github.com/yiya1989/sshkrb5/krb5forssh依赖版本见 implant/go-mod接入 SSH GSSAPI 认证implant/vendor/github.com/yiya1989/sshkrb5/krb5forssh/client.go 中 import 了gopkg.in/jcmturner/gokrb5.v7/client、config、crypto、keytab等模块implant/sliver/shell/ssh/ssh.go 通过krb5forssh.NewKrb5InitiatorClient(krb5ConfData, username, realm, keytab)创建 Kerberos 发起方客户端为植入体的 SSH 连接提供 Kerberos 认证能力。由此形成完整证据链sliver implant SSH → sshkrb5 → gokrb5 → rfc3962/rfc8009 → aescts本包。也就是说当植入体使用支持 Kerberos 的 SSH 会话时会话数据的加密保护最终由 AES-CBC-CTS 完成。七、安装与集成注意事项获取依赖与任何 Go 模块一致在模块内执行go get gopkg.in/jcmturner/aescts.v1即可本仓库中该包以 vendor 形式存在见 vendor/gopkg.in/jcmturner/aescts.v1/并同时被 server 端与 implant 端的 vendor 目录收录implant 侧见 implant/vendor/gopkg.in/jcmturner/aescts.v1/aescts.go。API 约定务必按“返回 next iv、密文、错误”的三元组接收Encrypt的结果多段连续加密时将上一段返回的 next iv 作为下一段的 IV可保持 CBC 链的连续性。适用前提本包提供的是无认证的机密性原语不包含消息完整性校验。在需要防篡改的场景如 Kerberos 消息中上层必须自行附加 HMAC——这正是 gokrb5 在EncryptMessage/DecryptMessage中先加 confounder、再追加完整性哈希的做法见 rfc3962/encryption.go 与 rfc8009/encryption.go。错误处理Encrypt在密钥非法或tailBlocks失败时返回错误如创建 cipher 失败、数据不足两块Decrypt对不足一个块的密文直接报错。调用方应始终检查错误返回值。八、小结jcmturner/aescts.v1以约 190 行代码完整实现了 AES-CBC 密文窃取模式通过“交换最后两个密文块 截断到明文长度”的核心手法在无需填充的情况下支持任意长度明文并通过 next iv 返回值支持链式连续加密。在 sliver 项目中它是 Kerberos AES 加密类型RFC 3962 / RFC 8009的加解密内核经由 gokrb5 与 sshkrb5 间接支撑植入体 SSH 的 Kerberos 认证会话。理解这一底层原语的三种边界路径与返回值语义将有助于排查上层 Kerberos/SSH 加密问题或在其他需要“CBC 无填充”的场景中正确复用该实现。赞分享网络安全【免费下载链接】sliverAdversary Emulation Framework项目地址https://gitcode.com/gh_mirrors/sl/sliver点击查看免费下载相关推荐Go 中的 AES-CBC-Ciphertext Stealing密文窃取加解密aescts 包原理与在 Kerberos 加密链中的实战应用Go 中的 AES CBC Ciphertext Stealing密文窃取加解密aescts 包原理与在 Kerberos 加密链中的实战应用 本篇文章以网络安全MicroPython cryptolib 模块实战AES 加密解密ECB / CBC / CTR完整指南MicroPython cryptolib 模块实战AES 加密解密ECB / CBC / CTR完整指南 本指南以 MicroPython 仓库中 do嵌入式语言运行时编程语言解释器编译器物联网系统编程SeaTunnel FieldEncrypt 加密 Transform 插件实战指南AES-GCM/AES-CBC 字段加解密原理与配置SeaTunnel FieldEncrypt 加密 Transform 插件实战指南AES GCM/AES CBC 字段加解密原理与配置 SeaTunnel数据集成ETL大数据批处理流处理变更数据捕获上一篇深入解析PowerShellEditorServicesLSP与DAP协议的完美结合下一篇Go Continuous IntegrationConfiguring with 100 Go Mistakes and How to Avoid Them创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网