网络安全【免费下载链接】sliverAdversary Emulation Framework项目地址https://gitcode.com/gh_mirrors/sl/sliver点击查看免费下载导读本文以 gokrb5 库本仓库 vendor 目录下分发的 Kerberos 认证实现自带的 GSS-API Negotiation Mechanism 笔记为骨架结合其源码逐层拆解基于 RFC 4178 的 SPNEGOSimple and Protected GSSAPI Negotiation Mechanism协商流程从客户端构造NegTokenInit初始协商消息到服务端应答accept-completed、accept-incomplete、reject、request-mic四种状态再到底层 Kerberos 5 机制的 AP_REQ 令牌与 MIC/Wrap 每消息保护。读完本文你将能够理解 gokrb5 中spnego与gssapi两个核心包的设计脉络掌握协商令牌的 ASN.1 结构、四种协商状态的语义以及如何在 Go 代码中调用NewNegTokenInitKRB5与SPNEGOClient/SPNEGOService完成一次完整的 Kerberos 认证。一、背景GSS-API 与 SPNEGO 机制GSS-APIGeneric Security Services Application Program Interface为应用程序提供了一套统一的认证、完整性校验与加密接口底层可以挂接多种安全机制mechanism如 Kerberos 5、NTLM 等。为了让通信双方在不预先约定机制的前提下完成协商IETF 在 [RFC 4178] 中定义了SPNEGOSimple and Protected GSSAPI Negotiation Mechanism其 OID 为1.3.6.1.5.5.2。在 gokrb5 中GSS-API 相关的 OID 定义位于 gssapi/gssapi.goconst ( // GSS-API OID names OIDKRB5 OIDName KRB5 // MechType OID for Kerberos 5 OIDMSLegacyKRB5 OIDName MSLegacyKRB5 // MechType OID for Kerberos 5 OIDSPNEGO OIDName SPNEGO )对应的实际 OID 值由OID()函数返回同文件 L120-L130机制OIDSPNEGO1.3.6.1.5.5.2Kerberos 5KRB51.2.840.113554.1.2.2MS Legacy Kerberos 51.2.840.48018.1.2.2SPNEGO 的完整实现位于 spnego/spnego.go它实现了 GSS-API 的Mechanism接口定义见 gssapi/gssapi.go#L105-L114包括AcquireCred、InitSecContext、AcceptSecContext、MIC、VerifyMIC、Wrap、Unwrap等操作。客户端侧通过SPNEGOClient(cl, spn)构造服务端侧通过SPNEGOService(kt, options...)构造分别对应 RFC 2744 中GSS_Init_sec_context与GSS_Accept_sec_context的语义。二、客户端初始协商消息NegTokenInit 与 NewNegTokenInitKRB5RFC 4178 规定客户端向服务端发送一条初始协商消息消息中按偏好降序in order of decreasing preference列出客户端支持的所有机制列表。gokrb5 通过NewNegTokenInitKRB5方法生成该消息并且该消息只声明一种受支持的机制——Kerberos 5。// NewNegTokenInitKRB5 creates new Init negotiation token for Kerberos 5 func NewNegTokenInitKRB5(cl *client.Client, tkt messages.Ticket, sessionKey types.EncryptionKey) (NegTokenInit, error) { mt, err : NewKRB5TokenAPREQ(cl, tkt, sessionKey, []int{gssapi.ContextFlagInteg, gssapi.ContextFlagConf}, []int{}) if err ! nil { return NegTokenInit{}, fmt.Errorf(error getting KRB5 token; %v, err) } mtb, err : mt.Marshal() if err ! nil { return NegTokenInit{}, fmt.Errorf(error marshalling KRB5 token; %v, err) } return NegTokenInit{ MechTypes: []asn1.ObjectIdentifier{gssapi.OID(gssapi.OIDKRB5)}, MechTokenBytes: mtb, }, nil }源码位于 spnego/negotiationToken.go#L320-L334从中可以读出三个关键实现事实机制列表MechTypes仅包含gssapi.OID(gssapi.OIDKRB5)一个元素即客户端只声明支持 Kerberos 5初始机制令牌RFC 4178 允许该消息可选地携带客户端首选机制此处即 KRB5的初始机制令牌NewNegTokenInitKRB5总是包含它——具体是通过NewKRB5TokenAPREQ构造携带Integ完整性与Conf机密性两个上下文标志的 AP_REQ 令牌再Marshal后填入MechTokenBytes字段ReqFlags 与 MechListMIC 未设置从返回值看ReqFlags保持零值、MechListMIC为空。注释negotiationToken.go#L75说明mechListMIC字段在协商 Kerberos 令牌时不会使用。NegTokenInit的 ASN.1 结构定义negotiationToken.go#L24-L32NegTokenInit :: SEQUENCE { mechTypes [0] MechTypeList, reqFlags [1] ContextFlags OPTIONAL, -- 继承自 RFC 2478为向后兼容保留建议省略 mechToken [2] OCTET STRING OPTIONAL, mechListMIC [3] OCTET STRING OPTIONAL, ... }三、服务端应答的四种协商状态RFC 4178 规定服务端对客户端初始协商消息的应答分为四种状态这也是关联文档给出的核心表格。下表为原文内容的完整保留并补充了在 negotiationToken.go#L50-L56 中对应的源码常量Message Type/State描述源码常量NegStateaccept-completed表示发起方选定的机制对目标方是可接受的且第一条协商消息中内嵌的安全机制令牌足以完成认证NegStateAcceptCompleted 0accept-incomplete至少还需要客户端再发送一条消息来建立安全上下文NegStateAcceptIncomplete 1reject协商正在终止NegStateReject 2request-mic该状态只能出现在目标方的第一条应答消息中表示如果每消息完整性服务per-message integrity services可用则必须进行 MIC 令牌交换NegStateRequestMIC 3服务端的应答以NegTokenResp承载其 ASN.1 结构定义于 negotiationToken.go#L34-L47NegTokenResp :: SEQUENCE { negState [0] ENUMERATED { accept-completed (0), accept-incomplete (1), reject (2), request-mic (3) } OPTIONAL, -- 在目标方的第一条应答中为必需字段 supportedMech [1] MechType OPTIONAL, -- 仅出现在目标方的第一条应答中 responseToken [2] OCTET STRING OPTIONAL, mechListMIC [3] OCTET STRING OPTIONAL, ... }NegTokenResp在 Go 中的实现字段negotiationToken.go#L79-L86为NegState、SupportedMech、ResponseToken、MechListMIC其中NegState以asn1.Enumerated表示可用State()方法取回NegState类型SupportedMech则承载服务端最终选定的机制 OID。在服务端校验逻辑SPNEGO.AcceptSecContext见 spnego/spnego.go#L69-L90中服务端会检查协商令牌携带的 OID 是否为 KRB5 或 MSLegacyKRB5若非则返回gssapi.StatusDefectiveToken随后调用t.Verify()校验内嵌的机制令牌并取出上下文context供后续使用。四、协商令牌的整体封装NegotiationToken CHOICESPNEGO 的协商令牌在 ASN.1 层面是一个 CHOICE 类型由[0] NegTokenInit客户端发往服务端与[1] NegTokenResp两种选择构成。gokrb5 用SPNEGOToken统一表示这两种形态见 spnego/spnego.go#L99-L107type SPNEGOToken struct { Init bool Resp bool NegTokenInit NegTokenInit NegTokenResp NegTokenResp settings *service.Settings context context.Context }Marshal时spnego.go#L110-L129若是Init形态先 ASN.1 编码 SPNEGO 的 OIDgssapi.OID(gssapi.OIDSPNEGO)再编码NegTokenInit随后通过asn1tools.AddASNAppTag(b, 0)打上应用标签 0形成[APPLICATION 0]外层结构若是Resp形态直接编码NegTokenResp其外层由Marshal内部以上下文标签[1]封装。Unmarshal时spnego.go#L132-L173则先检查首字节若为0xA1即[1]上下文标签的构造编码则按NegTokenResp解析否则按[APPLICATION 0]解出 OID 并校验是否为 SPNEGO OID。这一分支逻辑最终落到UnmarshalNegTokennegotiationToken.go#L281-L318依据 ASN.1 标签 0 或 1 分别解出NegTokenInit或NegTokenResp。五、底层机制Kerberos 5 与 AP_REQ 认证SPNEGO 只是协商外壳真正的认证由选定的机制KRB5完成。在 gokrb5 的客户端流程中spnego.go#L51-L65client.GetServiceTicket(spn)完成 TGS 交换取得服务票据Ticket与会话密钥NewNegTokenInitKRB5用它们构造携带 AP_REQ 的NegTokenInit返回SPNEGOToken{Init: true, NegTokenInit: ...}作为ContextToken发出。服务端通过VerifyAPREQservice/APExchange.go校验 AP_REQ验证票据签名、检查时钟偏差MaxClockSkew、可选地强制校验客户端主机地址RequireHostAddr、通过重放缓存GetReplayCache检测重放攻击并解析票据中的 PACPrivilege Attribute Certificate以获得用户的组 SID、登录时间、UPN 等域身份信息。PAC 解码失败时isPAC err ! nil直接拒绝认证这体现了域环境认证中的权限校验语义。六、每消息保护MIC Token 与 Wrap Token当协商结果要求每消息完整性保护尤其服务端应答request-mic状态时GSS-API 提供GSS_GetMIC/GSS_VerifyMIC与GSS_Wrap/GSS_Unwrap两类操作分别对应 gokrb5 的 MICToken.go 与 wrapToken.go。MIC TokenRFC 4121 4.2.6.1用于对数据做完整性校验生成独立于用户数据的令牌。其 16 字节头部格式为字节字段说明0..1TOK_ID固定值0x04 0x04big-endian2Flags属性字段bit0 表示发送方为 context acceptorbit1 表示机密性MIC 令牌中不得设置bit2 表示使用 acceptor 子密钥3..7Filler五个字节0xFF8..15SND_SEQ明文序列号big-endian16..endSGN_CKSUM对待签名数据 0..15 头部的校验和NewInitiatorMICTokenMICToken.go#L190-L202以keyusage.GSSAPI_INITIATOR_SIGN25计算校验和接受方通常使用GSSAPI_ACCEPTOR_SIGN23。校验和通过 HMAC 计算Verify使用hmac.Equal做常量时间比较以防时序攻击。Wrap TokenRFC 4121 4.2.6.2用于签名并可选的加密封装数据。头部同样 16 字节TOK_ID 0x05 0x04、Flags、1 字节 Filler0xFF、ECExtra Count校验和长度、RRCRight Rotation Count、SND_SEQ随后是数据区与校验和。计算校验和时 EC 与 RRC 必须置 0NewInitiatorWrapTokenwrapToken.go#L215-L235使用GSSAPI_INITIATOR_SEAL24作为 key usage接受方对应GSSAPI_ACCEPTOR_SEAL22。注意Wrap Token 不做 ASN.1 编码直接以二进制字节序列传输。七、GSS-API 状态码与上下文标志gokrb5 的 gssapi/gssapi.go 定义了完整的 GSS-API 状态码集合StatusBadBindings、StatusBadMech、StatusBadName、StatusBadSig、StatusContextExpired、StatusNoCred、StatusContinueNeeded等Status结构实现error接口Error()方法把数字代码转换为可读文本如StatusBadMech→ unsupported mechanism requested。协商校验中常见的StatusContinueNeeded对应需要继续调用以建立上下文StatusDefectiveToken对应检测到缺陷令牌这些在NegTokenInit.Verify/NegTokenResp.VerifynegotiationToken.go#L141-L174、L231-L258中被用作协商推进与失败判定的信号。上下文标志gssapi/contextFlags.go以位掩码定义对应 RFC 2744 的标准含义标志值含义ContextFlagDeleg1委托ContextFlagMutual2相互认证ContextFlagReplay4重放检测ContextFlagSequence8序列检测ContextFlagConf16机密性ContextFlagInteg32完整性ContextFlagAnon64匿名如NewNegTokenInitKRB5中所见客户端默认请求Integ与Conf两个标志negotiationToken.go#L322。八、在仓库中的定位与使用提示gokrb5 以第三方依赖形式随本仓库分发分别位于根目录 vendor/gopkg.in/jcmturner/gokrb5.v7 与 implant/vendor/gopkg.in/jcmturner/gokrb5.v7两者内容一致。其中gssapi包实现 GSS-API 通用接口OID、状态码、MIC/Wrap 令牌spnego包实现 RFC 4178 的协商机制client/service包分别承担客户端 AS/TGS 交换与服务端 AP_REQ 校验。在 Go 程序中使用 SPNEGO 完成 Kerberos 认证的典型路径为客户端cl, _ : client.NewClientWithPassword(user, REALM, password, config)后调用SPNEGOClient(cl, service/hostREALM)经AcquireCredInitSecContext得到携带NegTokenInit的ContextToken服务端SPNEGOService(keytab)经AcceptSecContext校验令牌并建立上下文后续每消息保护可通过MIC()/Wrap()完成。需要说明的是本仓库主项目源码并未直接引用 gokrb5 的 GSS-API/SPNEGO 接口它主要作为认证协议栈的组成部分随依赖树分发implant/vendor/github.com/yiya1989/sshkrb5中的 SSH Kerberos 客户端实现krb5forssh/client.go引用了gssapi与spnego包可作为库内实际消费方参考。本文基于关联文档 vendor/gopkg.in/jcmturner/gokrb5.v7/gssapi/README.md 展开源码细节均以当前仓库实际内容为准。赞分享网络安全【免费下载链接】sliverAdversary Emulation Framework项目地址https://gitcode.com/gh_mirrors/sl/sliver点击查看免费下载相关推荐Sliver 依赖剖析gokrb5.v7 中 SPNEGO/GSS-API 协商机制RFC 4178原理与实现Sliver 依赖剖析gokrb5.v7 中 SPNEGO/GSS API 协商机制RFC 4178原理与实现 导读 本文以 SliverAdversa网络安全Tempo 依赖中的 GSS-API/SPNEGO 协商机制解读从 NegTokenInit 到 Kerberos MIC 与 Wrap 令牌Tempo 依赖中的 GSS API/SPNEGO 协商机制解读从 NegTokenInit 到 Kerberos MIC 与 Wrap 令牌 导读 Graf后端可观测性链路追踪curl --negotiate 选项详解使用 SPNEGO/GSS-API 实现 HTTP Negotiate 认证curl negotiate 选项详解使用 SPNEGO/GSS API 实现 HTTP Negotiate 认证 导读 negotiate 是 curl 命CLI网络通信上一篇Blender曲线工具终极指南5大实用技巧释放你的创造力✨下一篇Pangolin-NPU 零基础入门为什么剪接位点预测对遗传病研究至关重要创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考