域渗透——域内常用三大协议

Nevolar Lv1

NTLM 诞生背景

产生原因:早期 SMB 以明文口令进行传输,安全性几乎没有,后来出现了 LM(LAN Manager)协议,但安全性较弱,容易被破解,再后来微软提出 NTLM 协议,分别是 NTLM v1、NTLM v2

作用:NTLM 既可以用作域环境身份验证,又可以为 SMB、HTTP、LDAP、SMTP 等上层微软应用提供身份认证

SSPI 和 SSP

SSPI(Security Service Provider Interface 或 Security Support Provider Interface,安全服务接口),是 Windows 定义的一套接口,定义了安全有关的功能函数,主要作用于身份验证机制,以及为其他协议提供 Session Security 机制。

SSP(Security Service Provider,安全服务提供者)是 SSPI 的实现者,微软自己实现了很多 SSP,比较典型的有 NTLM SSP、Keberos SSP、Digest SSP……

LM Hash 加密算法

Lm 是微软提出的一个身份验证协议,虽然容易被破解,但为了保证兼容性,微软只是将它禁用了(从 Windows Vista 和 Windows Server 2008 开始),LM Hash 明文密码被限定在 14 位以内,超过这个位数就不会使用该加密算法,如果 LM Hash 的值为老 aad3b435b5……404ee,说明 LM Hash 为空或被禁用了

LM Hash 加密流程(略)

NTLM 加密算法

为了解决 LM Hash 容易被破解的安全弱点,微软在 Windows NT 3.1 首次引入了 NTLM Hash,基本 Windows 2000——Windows 2012 以及 Windows XP 都支持,且从 Windows Vista 和 Windows Server 2008 开始,默认禁用 LM Hash,只存储 NTLM Hash。

Windows 将用户的密码 NTLM Hash 加密后存储在 C:\Windows\System32\config\SAM 文件中。当用户注销、重启、锁屏后,操作系统会让 winlogon.exe 显示登录界面,当 winlogon.exe 接收到用户输入后,会将密码交给 lsass.exe,lsass.exe 会先自己存一份明文密码,然后将明文密码加密成 NTLM Hash 与 SAM 数据库进行比较和认证。我们用 mimikatz 就是从 lsass.exe 中提取明文密码或 Hash 密码。

NTLM 加密流程(略)

NTLM 协议认证

NTLM 是一种基于 Challenge/Response(质询/响应)的验证机制,由三种消息组成:

  1. Type 1(协商,Negotiate )
  2. Type 2(质询,Challenge)
  3. Type 3(认证,Authentication)

NTLM v1 和 NTLM v2 的显著区别是 Challenge 值和加密算法不同,共同点都是使用 NTLM Hash 进行加密。

工作组下的 NTLM 认证(C/S):

  1. 客户端输入服务器的用户名和密码之后,会自己缓存一份服务器密码的 NTLM Hash 值,然后向服务器发送一个请求,该请求利用 NTLM SSP 生成 NTLMSSP_NEGOTIATE 消息(被称为 Type 1 协商消息)。
  2. 服务端接收 Type 1 消息,读取内容并从中选择自己所能接收的服务内容、加密等级等,传入 NTLM SSP 得到 NTLMSSP_CHALLENAGE 消息(被称为 Type 2 质询消息),并将 Type 2 返回给客户端,在 Type 2 消息中包含一个服务端生成的 16 位随机值,被称为 Challenge 值,服务端会缓存该值。
  3. 客户端收到 Type 2 消息,读取内容,取出 Challenge 值,用缓存的 NTLM Hash 对其进行加密得到 Response 消息,最后将 Response 和一些其他信息封装 到 NTLMSSP_AUTH 消息中(被成为 Type 3 认证消息)发往服务端。
  4. 服务端收到 Type 3 消息,从中取出 Net-NTLM Hash,用自己的密码对 NTLM Hash 对 Challenge 进行加密运算,得到自己计算的 Net-NTLM Hash,用来比较和客户端发来的 Net-NTLM Hash 是否相等,来决定是否认证成功。

在 Type 3 中最重要的是 Response 消息,它是用服务器密码的 NTLM Hash 对 Challenge 值加密后经过一系列运算后得到的,Response 消息中可以提取出 NTLM Hash。

域环境下的 NTLM 认证

域环境下的 NTLM 认证,前三步和工作组环境下的步骤一样,这里从第四步开始

  1. 服务端收到客户端发送的 NTLMSSP_AUTH 认证消息,通过 Net-Weblogon 协议与域控制器(Domain Controller,DC,简称域控)建立一个安全通道,将验证消息发送给域控。
  2. 域控收到验证消息,取出 Net-NTLM Hash,从自己的数据库中找到该用户的 NTLM Hash,对 Challenge 进行一系列运算得到自己生成的 Net-NTLM Hash,和服务端发送过来的 Net-NTLM Hash 进行比较,相等则密码正确,返回认证成功,否则认证失败。
  3. 服务端根据域控的指示对客户端进行回复。

NTLM v1 和 NTLM v2 的区别

它们的主要区别在于加密算法和 Challenge 值,目前使用最多的是 NTLM v2 版本。

1)Challenge 值

NTLM v1:8B

NTLM v2:16B

2)Net-NTLM Hash 使用的算法

NTLM v1:DES 加密算法

NTLM v2:HMAC-MD5 加密算法

LmCompatibilityLevel 值

这个值用来确定网络登录使用的质询 / 响应身份验证协议。

含义
0 客户端使用 LM 和 NTLM 身份验证,但从不使用 NTLM v2 会话安全性
1 客户端使用 LM 和 NTLM 身份验证,如果服务器支持 NTLM v2 会话安全性,则使用 NTLM v2 会话安全性。域控制器接受 LM、NTLM 和NTLM v2 身份验证。
2 客户端仅使用 NTLM 身份验证,如果服务器支持 NTLM v2 会话安全性,则使用 NTLM v2 会话安全性。域控制器接受 LM、NTLM 和NTLM v2 身份验证。
3 客户端仅使用 NTLM v2身份验证,如果服务器支持 NTLM v2 会话安全性,则使用 NTLM v2 会话安全性。域控制器接受 LM、NTLM 和NTLM v2 身份验证。
4 客户端仅使用 NTLM v2身份验证,如果服务器支持 NTLM v2 会话安全性,则使用 NTLM v2 会话安全性。域控制器拒绝 LM 身份验证,但接受 NTLM 和NTLM v2 身份验证。
5 客户端仅使用 NTLM v2身份验证,如果服务器支持 NTLM v2 会话安全性,则使用 NTLM v2 会话安全性。域控制器拒绝 LM 和 NTLM 身份验证,但接受 NTLM v2 身份验证。

可以通过本地策略修改”LAM 管理器身份验证级别”,或者注册表命令修改

NTLM 协议安全问题

通过学习我们知道 Type 3 消息中是使用用户密码进行计算的,当没有拿到用户密码明文而只拿到 Hash 的情况下,可以进行 Pass the Hash(哈希传递)攻击。

Type 3 消息中也存在 Net-NTLM Hash,当获得了该值后可以进行中间人攻击,也就是 NTLM Relay(NTLM 中继)攻击。

由于 NTLM v1 协议加密过程存在天然缺陷,因此可以对 Net-NTLM 进行破解,得到 NTLM Hash 之后可以进行横向移动。

  1. 哈希传递攻击是内网横向移动的一种方式,由于 NTLM 认证过程使用的是用户密码的 NTLM Hash 进行加密,因此当获取到了用户密码的 NTLM Hash 而没有解出用户的明文密码时,可以利用该 NTLM Hash 进行哈希传递攻击,对内网其他机器进行 Hash 碰撞,碰撞到使用相同密码的机器后使用 135 端口或 445 端口横向移动到使用该密码的其他机器。
  2. NTLM Relay 严格上来讲应该叫 Net-NTLM Relay,在第三步拿到 Response 消息中的 Net-NTLM Hash 之后,可以进行中间人攻击,重放 Net-NTLM Hash。
  3. 由于 NTLM v1 协议存在天然缺陷,只要拿到 Net-NTLM v1 Hash,就能破解成 NTLM Hash,这和密码强度无关。在域环境中这种危害更加强大,因为在域中使用 Hash 即可远程连接目标机器,如果域控允许发送 NTLM v1 响应,我们就可以通过与域控机器进行 NTLM 认证,然后抓取域控的 Net-NTLM v1 响应,破解为 NTLM Hash,使用域控的机器账户和 Hash 即可导出域内所有用户 Hash。

但是从 Windows Vista 开始,微软就默认使用 NTLM v2 身份认证协议,要想降级到 NTLM v1 就要修改安全策略为”仅发送 NTLM 响应”,或者通过修改注册表降级

Net-NTLM v1 Hash 破解

  1. 首先在 winserver 修改安全设置,修改 LAN 管理器身份验证级别为仅发送 NTLM 响应,或修改三处注册表也可以
  2. 在 VPS 利用 Responder 开启监听,目的是抓取目标主机的 Net-NTLM v1 Hash,记得先修改 Responder 的 Challenge 值
  3. 在目标主机使用打印机漏洞或 Petitpotam 触发域控机器强制向我们的机器进行 NTLM 认证,即可收到域控的 Net-NTLM v1 Hash 了
  4. 利用 ntlmv1.py 对 Net-NTLM v1 Hash 进行分析,得到 NTHASH,把 NTHASH 放到 https://crack.sh/get-cracking/ 进行破解,格式为:
1
2
3
NTHASH:8EE******FF

$NETNTLM$1122334455667788$8EE******FF
  1. 等待~然后就破解成功了,破解后的 key 值就是目标的 NTLM Hash
  2. 利用该 NTLM Hash 以域控机器账户身份执行 secretdump.py 就可以导出域内所有用户 Hash

Kerberos 基础

kerberos 是西方神话中的地狱三头犬的名字,对应了它需要三方共同参与才能完成一次认证

它和传统的 NTLM 基于质询/响应的方式不同,它是基于票据的方式进行身份验证的

在 Kerberos 中存在三种角色:

  1. 客户端,每个 Kerberos 客户端在访问特定资源、程序以及应用程序之前都要请求进行身份验证
  2. 服务端,每个 Kerberos 服务端都会有唯一的 SPN(服务主体名字)
  3. KDC(密钥分发中心),是一种网络服务,为活动目录域内的用户提供临时密钥和会话密钥,服务账户名为 krbtgt,该用户是自动创建,密码是自动随机生成的,无法正常登录,KDC 作为活动目录域的一部分运行在每个域控制器上

Kerberos 使用 88 端口进行认证,使用 464 端口进行密码重设

Kerberos 有两个基础认证模块,分别是 AS_REQ & AS_REP 和 TGS_REQ & TGS_REP,以及微软扩展的两个认证模块 S4U 和 PAC。

S4U 是微软为了实现委派而扩展的模块,分为 S4U2Self 和 S4U2Proxy。

在 Kerberos 最初的设计里只说明了如何证明客户端的真实身份,并没有说客户端是否有权限访问该服务,微软为了解决这个问题引入了 PAC,PAC(Privilege Attribute Certifcate,特权属性证书)中包含各种授权信息、附加凭据信息、配置文件和策略信息等,在一个正常的流程中, KDC 返回的 TGT 和 ST 都是带有 PAC 的,用 PAC 还有一个优点就是只需要根据请求包中所包含的 PAC 信息直接与本地资源的 ACL 相比较直接判断用户权限,而不需要借助 KDC 提供的完整授权信息来进行判断。

PAC 结构(略)

PAC 凭据信息

PAC 结构里有一个 Login Info 数据类型(你可以把它想象成一个接口),Login Info 类型的 PAC_LOGON_INFO 包含 Kerberos 凭据客户端的凭据信息

在此凭据信息中,部分重要的字段含义如下:

  • Acct Name:用户 sAMAccountName 的属性值,个人认为是用户名的部分
  • Full Name:用户 displayName 的属性值,个人认为是用户名的全名
  • User RID:用户的 RID,也就是 SID 的最后部分
  • Group RID:域用户的 GRID 恒为 513(也就是 Domain Users 的 RID),机器用户的 Group RID 恒为 515(也就是 Domain Comp-uters 的 RID),域控的 Group RID 恒为 516(也就是 Domain Controllers 的 RID)
  • Num RIDS:用户所属组的个数
  • GroupIDS:用户所属的所有组的 RID

PAC 签名

PAC 包含两个数字签名:PAC_SERVER_CHECKSUM 和 PAC_PRIVSVR_CHECKSUM,前者使用服务密钥进行签名,主要是验证此 PAC 已由服务签名;后者使用 KDC 密钥进行签名,主要是防止不受信任的服务使用无效的 PAC 为自己伪造票据——说白了就是验证 PAC 是否由 KDC 签发,此签名默认关闭。

PAC_PRIVSVR_CHECKSUM 选项的关闭也是白银票据成功的前提,如果该选项开启,目标主机会将这个 PAC 签名以 KRB_VERIFY_PAC 的消息通过 RPC 协议发送给 KDC,KDC 再验证这个 PAC 数字签名以 RPC 返回码的形式返回给服务端,服务端就可以根据返回结果判断 PAC 的真实性和有效性了,这样就算我们伪造了 ST,也不能伪造 PAC_PRIVSVR_CHECKSUM 签名,自然也就无法通过 KDC 签名校验。

PAC 的优缺点

优点:

  • 有了 PAC 之后,服务端不再需要从 KDC 查询该客户端的授权信息,省了网络资源和成本

缺点:

  • PAC 会导致认证耗时过长
  • Kerberos 客户端会通过 RPC 调用 KDC 上的函数来认证 PAC 信息,导致服务端和 KDC 之间 RPC 流量包的增加
  • PAC 是微软有的一个特性,启用了 PAC 的域不支持装有其他操作系统的服务器,制约了域配置的灵活性
  • PAC 安全性导致了一个域内极其严重的提权漏洞——MS14-068

Kerberos 数据包分析

说一些比较重要的细节,其他的就略过了,在”初探 Kerberos”文章即可看认证流程

在 AS 认证阶段有两个数据包,分别是 AS_REQ 和 AS_REO

AS_REQ 中有一个 PA_DATA pA_ENC_TIMESTAMP 预认证字段,它用用户 Hash 加密的时间戳作为 value 发送给 KDC 的 AS,然后 AS 从活动目录中查询出用户的 Hash,使用用户的 Hash 进行解密,获得时间戳,如果能解密,且时间戳在一定的范围内,则证明认证通过,因为用的是用户的 Hash,因此也就造成了哈希传递攻击;还有一个比较重要的字段名叫 cname,表示请求的用户名,用户存在或否返回的包是有差异的,所以也就造成了用户名枚举攻击,当用户名存在时,密码正确与否也会影响返回包,因此也可以进行密码喷洒。

在收到客户端的 AS_REQ 后,KDC 会对 AS_REQ 的预认证部分进行解密,若解密成功且时间戳在一定范围内,则会返回一个 AS_REP 包表明认证成功,AS_REP 中比较重要的字段有 ticket、enc-part(ticket 中的)、enc-part(最外层的),其含义如下:

  • ticket:票据
  • enc-part(ticket 中的):TGT 中的加密部分,这部分是用 krbtgt 的密码 Hash 加密的,因此如果我们有 krbtgt 的密码 Hash,就可以自己制作一个 ticket,这也就造成了黄金票据攻击
  • enc-part(最外层的):Logon Session key,这部分是用请求的用户密码 Hash 加密的,作为下一阶段的认证密钥
  • authorization-data:这个字段包含用户的身份权限信息,这些信息包含在 PAC 中

那么 PAC 信息是如何生成的呢?KDC 在收到客户端发来的 AS_REQ 的时候,会取出里面的 cname 字段,并在域活动目录数据库中查询,找到 sAMAccountName 属性为 cname 的值的用户,用该用户的身份生成一个对应的 PAC。

AS 认证成功之后,客户端拿着 AS_REP,用用户密钥解密 enc_Logon Session key 获得 TGT,随后客户端要拿着 TGT 去向 KDC 的另一个服务 TGS 购买 ST,此时会产生两种类型的数据包,分别是 TGS_REQ 和 TGS_REP

KDC 在接收到 TGS_REQ 会做以下几件事:

  1. 用 krbtgt 密钥解密 TGT 中的加密部分,得到 Logon Session key 和 PAC 信息,解密成功则证明该 TGT 是 KDC 颁发的
  2. 验证 PAC 的签名,签名正确则证明 PAC 未经过篡改
  3. 使用 Logon Session Key 解密 authorization 得到时间戳等信息,如果能解密成功,且票据时间在有效范围内,则验证了会话的安全性

完成上述步骤后 KDC 会发送回复包 TGS_REP 给客户端,回复包中有访问服务所需的 ST

客户端收到 KDC 发来的 TGS_REP 后,从中取出 ST,准备开始申请访问服务,至此流程结束

S4u2Self & S4uProxy 协议

为了在 Kerberos 协议层面对约束性委派进行支持,微软对 Kerberos 协议扩展了两个自协议:S4u2Self(Service for User to Self)& S4uProxy(Service for User to Proxy)

S4u2Self:代表任意用户针对自身的服务票据

S4uProxy:可以用上一步获得的 ST,以用户的名义请求针对其他指定服务的 ST,在 S4uProxy 协议的 TGS_REQ 包会增加一个 additional-tickets 字段,该字段的内容就是上一步利用 S4u2Self 请求的 ST

Kerberos 协议的安全问题

AS_REQ 阶段因为使用的是用户密码 Hash 或 AES Key 加密的时间戳,当只获得了用户密码 Hash 时,可以发起 AS_REQ 请求造成 PTH(pass the hash)攻击,当只获得了用户密码的 AES Key 时,发起 AS_REQ 请求造成 PTK(pass the key)攻击。

AS_REQ 中 cname 字段的值代表用户名,当这个值存在或不存在时返回的包不一样,所以可以枚举用户名;当用户名存在,密码正确或错误时,返回的值也不一样,所以可以对用户名的密码进行爆破;而且 Logon Session Key 是用用户密码加密的,对于域用户,如果设置了“Do not require Kerberos preauthentication”(不需要域认证)选项,攻击者会向域控的 88 端口发送 AS_REQ,此时域控不会做任何验证就会将 TGT 和该用户 Hash 加密的 Logon Session Key 返回,这样攻击者就能对用户 Hash 加密的 Logon Session Key 进行离线破解,如果破解成功则会获得用户密码明文,这被称为 AS_REP Roasting 攻击,关于这点,deepseek 比喻的比较好

在 TGS_ REP 阶段,由于 ST 是用服务 Hash 加密的,因此我们如果能获取到 ST,就能对该 ST 进行破解,得到服务的 Hash,造成 Kerberosraosting。

密码喷洒攻击:属于自动化密码猜测的一种,当我们对同一个用户名进行多次密码验证失败时会锁定用户,这时我们可以用同一个密码对多个用户名进行身份验证,从而避免账户被锁定,这种方式就叫做密码喷洒攻击。

Kerberos 是怎么工作的?

在我们计算机里通常有三种认证,分别是本地认证、网络认证以及 kerberos 认证

本地认证是我们最常用的,我们启动自己的电脑,输入密码就是本地认证;我们通过 Windows smb 传输文件之前显示要先登录,这个可以被称为网络认证

这两个认证是最基础,也是最常用的认证,但他们有个缺陷,在这里我们可以想象一个场景:公司老板想用自己的电脑访问财务部门的电脑的时候,需要输入账号密码进行认证,但问题来了——这个老板是真正的老板吗?这个财务部门是真正的财务部门吗?他们会不会是黑客伪造的主机用来窃取账号密码的呢?

为了解决这些问题, kerberos 登场了,kerberos 是一种网络认证协议,主要应用与 C/S 架构,通过使用票据(ticket)来验证用户身份

要注意,kerberos != k8s,学之前我以为它们是等价关系

部分内容引自:https://www.bilibili.com/video/BV1ySEyzaEfP

为了弄清楚它是怎么工作的,我们引入几个概念:

  • KDS(key distributed center):整个安全认证过程的票据生成管理服务,其中包含两个服务:TS 和 TGS
  • AS(authentication service):为客户端生成 TGT 的服务
  • TGS(ticket granting service):为客户端生成某个服务的 ticket
  • TGT(ticket-granting ticket):用于获取 ticket 的票据
  • KRBGTG:密钥分发中心(KDS)的账户名

这里假定我们是张三,要去动物园(Web 系统),我们首先要将我们的身份信息发送给安检窗口,然后它给了我们一个票据(TGT)用于告诉我们应该去哪个卖票窗口买票——由于这个动物园有点特殊,一种票只能看一种动物(服务,比如 ssh服务、web服务),所以在这个流程我们要指定我们要看的动物,随后我们拿着票据去到售票窗口(TGS)买票,售票窗口给了我们一张可以看长颈鹿(web 服务)的票据(ST),最后我们拿着这个票据就可以进到动物园长颈鹿专区看到长颈鹿啦!

原理剖析

  1. 在我们第一步拿着自己的身份证安检窗口的时候,实际是我们将我们的用户名、地址以及当前时间等信息发送到 KDC 里的 AS 做认证,得到一个 TGT 票据,这个票据的上半部分是用我们用户的密码 hash 加密的,下半部分是用 krbtgt 的密码 hash 加密的,里面的 CT_SK 是一个随机的十六位字符串

  1. 在我们收到 TGT 票据的时候,我们会将其解密,再加上我们要访问的服务(每一个凭证只能访问一种服务),然后通过里面的 CT_SK 重新封装

  1. 重新封装之后发给卖票窗口 TGS,买票窗口返回一个 ST,这个就是我们进“动物园”所需的“门票”啦

  1. 随后我们就可以拿着 ST 凭证访问对应的服务了

黄金票据和白银票据

这里我们就提一下它们的概念

首先就是黄金票据,如果我们是伪造 TGT 票据的话,这个票据就叫做黄金票据,这个时候我们一般是拿下域控制器了,然后通过域控制器就可以伪造一张“任意通行”的身份证,从而控制整个内网的机器

白银票据的话就是伪造 ST 的过程,伪造好了之后我们就可以拿下整个内网的单一服务

LDAP 基础

LDAP(Lightweight Directory Access Protocol,轻量目录访问协议) 的前身是 X.500(目录服务的计算机服务),X.500 是通过 OSI 网络进行数据传输的,不过在 TCP/IP(网络控制协议 / 网际协议)出来后,其逐渐被 LDAP 所取代。LDAP通常将信息以树状的方式进行存储,这种结构称为 DIT(Directory Information Tree)。

大多数 Web 应用在使用统一身份认证的时候用的就是 LDAP 协议作为支撑,保证了统一用户身份认证存储,LDAP 支持跨平台,可以在单独服务器上部署 LDAP,实现域控相同功能,从而让任何应用都可以使用 LDAP 进行认证、信息获取、信息存储,并不是完全依赖域控。

基础模型:

  • 信息模型:LDAP 的信息表示方式,因为是面向对象的数据库,所以用户对象、计算机对象等通过对象类描述。
  • 命名模型:LDAP 的条目定位方式,每一个 LDAP 对象都有一个独一无二的 RDN 和 DN,RDN 表示的是 DN 中每一个用逗号分隔的表达式,DN 是整个树中唯一的标识,例如“CN=Admin,DC=S3root,DC=com”就有三个 RDN,分别是 CN=Admin,DC=S3root,DC=com。
  • 功能模型:条目的增删改查操作;认证类操作,绑定或解绑;其他操作,放弃或扩展。
  • 安全模型:匿名认证、基本认证、SASL 认证(Simple Authorization and Secure Layer 认证),其中 SASL 认证是指在 SSL 和 TLS 安全通道基础上的认证。

LDAP 的应用特性包括有:名唯一、可继承、可复制、跨平台、树结构。

全局目录编排(Global Catelog,GC),简单的来说这一个特殊的 windows 的分布式索引服务,能够让用户

快速地从整个域森林中查找对象,而不是查找整个域。默认情况下会在域中的 DC 上监听 TCP 端口 3268 或 3269(用于 SSL 上的 LDAP)。直接使用 LDAP 客户端连接 GC 的相应端口即可访问全局目录,但使用该端口时只允许只读方式。

  • 标题: 域渗透——域内常用三大协议
  • 作者: Nevolar
  • 创建于 : 2026-03-31 15:16:45
  • 更新于 : 2026-03-31 15:16:47
  • 链接: https://blog.eval.moe/2026/03/111e2b742ea6.html
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论