参考文章
彻底理解Windows认证
LM-Hash && NTLM-Hash
前提知识
这是一个 Windows 密码
Administrator:500:C8825DB10F2590EAAAD3B435B51404EE:683020925C5D8569C23AA724774CE6CC:::
# 其格式为:
用户名:RID:LM-HASH值:NT-HASH值
用户名称为:Administrator
RID 为:500
LM-HASH 值为:C8825DB10F2590EAAAD3B435B51404EE
NT-HASH 值为:683020925C5D8569C23AA724774CE6CC
# 其中:
Windows XP、Windows 2000、Windows 2003 系统默认使用 LM-HASH 加密,其值就是加密后的密码
Windows 2008、Windows 7、Windows Vista、Windows 8、Windows 10 、Windows 2016 禁用了 LM,默认使用 NTLM-HASH,其值就是加密后的密码
其中 LM-HASH 生成规则为:
1.用户的密码被限制为最多 14 个字符。
2.用户的密码转换为大写。
3.系统中用户的密码编码使用了 OEM 内码页
4.密码不足 14 字节将会用 0 来补全。
5.固定长度的密码被分成两个 7 byte 部分。每部分转换成比特流,在分 7bit 为一组末尾加 0,组成新的编码
6.上步骤得到的 8 byte 二组,分别作为 DES key 为 "KGS!@#$%" 进行加密。
7.将二组 DES 加密后的编码拼接,得到最终 LM HASH 值。
NT-HASH 生成规则为:
1.将密码字符串转化为 ASCII 字符串
2.ASCII 字符串再转换为十六进制字符串
3.十六进制字符串再转化为 Unicode 字符串
4.然后对 Unicode 字符串使用 MD4 消息摘要算法
当抓取到 Windows 中的 HASH 值时可以去一些在线网站尝试查询密码。
认证方式
本地认证
LM/NTLM 本质上是两种协议,LM-HASH 与 NT-HASH 根据这两个协议生成,用于认证的时候使用。
在本地登录 Windows 的情况下,操作系统会使用用户输入的密码经过同样的加密方式得到的密文作为凭证去与系统 SAM 文件中存储的密文(也就是前文的 LM/NT-HASH)进行对比验证,也就是本地认证
NTLM(网络认证)
LM(LAN Manager) 认证与 NTLM(NT LAN Manager) 认证分别以前文所说的 LM-HASH 和 NT-HASH 作为根本凭证进行认证,且 LM 与 NTLM 协议的认证机制相同,因此下面以 NTLM 为例
Windows 中常使用 NTLM 网络认证的地方有 SMB、Telnet 等
在实现网络认证的时,采用的方式为挑战/应答(Chalenge/Response)模式。可分为三步:
- 协商:主要用于确认双方协议版本
- 质询
- 验证:验证主要是在质询完成后,验证结果,是认证的最后一步。
其完整过程为:
# 协商
确定双方使用协议的版本
# 质询
1.客户端向服务器端发送用户信息(用户名)请求
2.服务器接受到请求,生成一个 16 位的随机数,被称之为 "Challenge", 使用登录用户名对应的 NTLM Hash 加密 Challenge 和用户名等, 生成 Challenge1。同时,生成 Challenge1 后,将Challenge(16 位随机字符)发送给客户端。Challenge 是以明文的形式发送的。
3.客户端接受到 Challenge 后,使用将要登录到账户对应的 NTLM Hash 加密 Challenge 生成 Response,然后将 Response 发送至服务器端。
其中,经过 NTLM Hash 加密 Challenge 和用户名等的结果在网络协议中称之为 Net-NTLM Hash。
# 验证
服务器端收到客户端的 Response 后,比对 Chanllenge1 与 Response 是否相等,若相等,则认证通过。
其中,NTLM 又有两个版本 v1 和 v2:两者区别并不大:
Challage: NTLM v1的 Challenge 有 8 位,NTLM v2 的 Challenge 为 16 位。
Net-NTLM Hash: NTLM v1 的主要加密算法是 DES,NTLM v2 的主要加密算法是 HMAC-MD5。
可以看到,整个认证过程都没有使用明文密码,这就在我们抓取到 hash 却无法破解时提供了另一种利用方式:Hash 传递攻击(Pass The Hash)
具体可以看这些文章 深入研究 Pass-the-Hash 攻击与防御、浅析内网横向移动-Pass The Hash
Kerberos(域认证)
Kerberos 是一种网络认证协议,其设计目标是通过密钥系统为客户机/服务器应用程序提供强大的认证服务。该认证过程的实现不依赖于主机操作系统的认证,无需基于主机地址的信任,不要求网络上所有主机的物理安全,并假定网络上传送的数据包可以被任意地读取、修改和插入数据。在以上情况下, Kerberos 作为一 种可信任的第三方认证服务,是通过传统的密码技术(如:共享 密钥)执行认证服务的。
为什么要进行 Kerberos(域认证):摘自 kerberos 协议概述
kerberos 目的是认证,既然认证就是辨别身份,那我输入用户名密码不就好了,为何要有 Kerberos 这样一个复杂的东西;举例来说,有 A,B,C 三个服务器,分别提供不同的服务,user 要访问 ABC 都需要输入用户名密码,但是 ABC 没必要都存一份 user 的密码,所以就衍生出一个中央服务器 D 来专门存储用户名密码;如果 user 通过了 D 的认证,那就是合法的身份,就可以使用 ABC 任何一个服务,所以 user 需要告诉 ABC 它通过了 D 的认证。如何证明这个事情,以及信息在网络传输过程如何防止被截获篡改而假冒等等,解决这些问题就靠 Kerberos。
先了解几个词汇:
完成一次 Kerberos 认证主要涉及到三个对象:
- Client 客户端
- Server 服务端
- KDC(Key Distribution Center 密钥分发中心),在域环境中,KDC 一般架设在 DC(Domain Controller 域控)上,负责管理票据、认证票据、分发票据,其中 KDC 又分为一下两个部分
- AS(Authentication Service): 为 client 生成 TGT 的服务,身份验证服务
- TGS(Ticket Granting Service): 为 client 生成某个服务的 Ticket,票据授与服务
其他:
- Ticket 票据,是网络对象互相访问的凭证
- TGT(Ticket Granting Ticket)入场券,通过入场券能够获得票据,是一种临时凭证的存在
- AD(Account Database)存储所有 client 的白名单,只有存 在于白名单的 client 才能顺利申请到 TGT
完成一次域认证基本流程:
1.
首先,客户端需要发送自己的身份信息到 KDC,身份信息中起码包含用户名,KDC 根据用户名在 AD 中寻找是否在白名单中,然后根据用户名提取到对应的 NTLM Hash。
KDC 此时生成一个随机字符串,叫 Session Key,使用用户名对应的 NTLM Hash 加密 Session Key,作为 AS 数据
AS 使用 KDC 中 krbtgt(域中的默认账户)的 NTLM Hash 加密 Session Key 和客户端的信息,生成 TGT。
Session Key 用于客户端向 TGS 服务通信。
域内所有网络对象的凭证都在 AD 中保存
其中,客户端发送的信息包括:自身的身份信息
、一个加密的时间戳
、目标 server 的信息
KDC 返回的消息包括:用 Client 对应的 NTLM Hash 加密的 Session Key
、TGT,即用 KDC Hash 加密的(Session Key、客户端信息、到期时间)
其中,TGT 的到期时间为 8 小时,如果超过了 8 小时,还需要重新申请 TGT,不能之间进入下一步获取 Ticket。
第二步客户端需要提供
TGT
、使用自己 NTLM Hash 解密出来的 Session Key 然后用 Session Key 加密的客户端信息跟时间戳
KDC 接到 TGT 与其他内容后,会首先解密 TGT,只有 KDC 可以解密 TGT,从 TGT 中提取到 Session Key,再使用 Session Key 解密其他内容,解密出来的内容同 TGT 中的信息进行校验来确认客户端是否受信。
验证通过后,就会生成一个新的 Session Key,我们称之为 Server Session Key,这个 Server Session Key 主要用于和服务器进行通信。同时还会生成一个 Ticket,也就是最后的票据了
其中 Ticket 由这些东西组成:使用 Server Hash 加密的(Server Sssion Key、Client Info、到期时间)
Server Hash:这个 Hash 是在 AD 中服务器计算机的 NTLM Hash。
客户端向服务器请求,提供 Ticket,Server Session Key 加密的客户端信息与时间戳。
Ticket 客户端无法解密
服务器端通过解密 Ticket 解密 Server Session Key(Client info + Timestamp)
比较时间长度
校验通过后,认证成功,该票据会一直存在客户端内存中
懂了吗?还是迷迷糊糊就对了。多看几遍吧,把每个词都记一下!
举一个稍显复杂的栗子:
我 --> Client
大型娱乐场所里的水上乐园 --> Server
总服务站 --> KDC(DC)
购票处 --> AS
检票口 --> TGS
- 今天约了一个小姐姐,决定一起出去玩,来到这个大型娱乐场所(整个域),项目有很多,我直呼一句去水上乐园玩(一看就是 LSB 了)。下面进入正题,首先得先去总服务站(KDC)买对应的票,我先提供了我的身份信息,并表示我想去水上乐园,而且告知了我什么时间点想去。服务站瞟了我一眼,发现我在 LSB 白名单(AD)上,于是便给购票处发了我的身份密码(我的 NTLM Hash,我也知道的)。并指示我去购票处(AS)。
- 于是我来到购票处(AS),购票处生成一串随机字符(Session Key),并用刚刚总服务站发送的关于我的身份密码(我的 NTLM Hash)加密了这个随机字符(Session Key),得到结果(暂时叫做 NS),然后再用服务站老板的身份密码(krbtgt Hash,我们不知道)加密了那串随机字符以及我之前提供信息,得到结果(TGT),然后将这两个加密后的数据印在一张临时票据(临时 Ticket,包含 TGT、加密后的随机字符 NS)上,这张票只有在我提供的时间点之后的 8 小时内有效。
- 什么鬼,买个票这么复杂。买好泳衣泳裤,也差不多到时间了,我跟小姐姐打算进去玩了。来到检票口(TGS),员工告诉我要提供一些数据认证。首先我用我的身份密码解密了票上数据(NS),得到那个随机字符串(Session Key),为了避免我的身份信息泄露,我便用那个随机字符串加密了我的身份信息以及真正的入园时间,得到结果(暂时叫做 SI),然后将加密后的结果(SI)跟之前票据上的另一个加密字符串(TGT)一并提供给了那个偷瞄我身旁小姐姐的员工
- 那个员工立马就向上级总服务站请示,总服务站立马使用服务站老板的身份密码(krbtgt Hash)解密了我提供的第二个加密字符串(TGT),得到了之前在购票处生成的随机字符串(Session Key)以及我一开始提供的提供的身份信息与入园时间(INFO1),然后再用那个随机字符串(Session Key)解密我提供的第一个加密字符串(SI),将得到的数据(INFO2)与之前得到的信息做对比。
- 身份信息是对的,也在票的有效时间之内。总服务站便再生成一个随机字符串(Server Session Key),使用游乐园服务密码(Server Hash)加密了这个随机字符(Server Session Key)以及我的身份信息还有到期时间(INFO1/2都可)。然后通知员工,给我戴一个电子手环(最终 Ticket),该手环含有刚加密的信息,当我要去玩某个项目时,用手环触碰一下门禁,门禁立马将得到的信息解密后对比有效时间与我的个人信息,发现无异常,于是立马发送指令将门打开。我便可以开心的玩耍了。
OK,看到这里,发现我写的东西都是些什么狗屎。卒。总之 Kerberos 认证相较于 NTLM 认证要复杂得多,需要多看几遍。
那么这其中又有什么问题呢?
- 白银票据
前提:拥有 Server Hash
原因:在 KDC 未发送 Server Session Key 加密的 Ticket 之前,服务器 Server 是不知道 Server Session Key 是什么的。 所以,一切凭据都来源于经 Server Hash 加密后的结果
方法:伪造使用 Server Hash 加密 Server Sssion Key、Client Info、到期时间
局限:由于白银票据需要目标服务器的 Hash,所以没办法生成对应域内所有服务器的票据,也不能通过 TGT 申请。因此只能针对服务器上的某些服务去伪造,伪造的服务类型列表如下:
服务注释 | 服务名 |
---|---|
WMI | HOST、RPCSS |
Powershell Remoteing | HOST、HTTP |
WinRM | HOST、HTTP |
Scheduled Tasks | HOST |
LDAP 、DCSync | LDAP |
Windows File Share (CIFS) | CIFS |
Windows Remote ServerAdministration Tools | RPCSS、LDAP、CIFS |
利用工具:mimikatz
- 黄金票据
前提:拥有 krbtgt Hash,拿到这个后,想干嘛干嘛
利用工具:mimikatz
Access Token
简介:
Windows Token 其实叫 Access Token(访问令牌),它是一个描 述进程或者线程安全上下文的一个对象。不同的用户登录计算机后, 都会生成一个 Access Token,这个 Token 在用户创建进程或者线程 时会被使用,不断的拷贝,这也就解释了A用户创建一个进程而该 进程没有 B 用户的权限。
Access Token 种类:主令牌、模拟令牌
一般情况下,用户双击运行一个程序,都会拷贝"explorer.exe"的 Access Token。
当用户注销后,系统将会使主令牌切换为模拟令牌,不会将令牌清除,只有在重启机器后才会清除。
组成:
用户帐户的安全标识符(SID)
用户所属的组的SID
用于标识当前登录会话的登录SID
用户或用户组所拥有的权限列表
所有者SID
主要组的SID
访问控制列表
访问令牌的来源
令牌是主要令牌还是模拟令牌
限制SID的可选列表
目前的模拟等级
其他统计数据
其中 SID(安全标识符):
安全标识符是一个唯一的字符串,它可以代表一个账户、一个用户 组、或者是一次登录。通常它还有一个SID固定列表,例如 Everyone 这种已经内置的账户,默认拥有固定的 SID。
SID 的表现形式:域SID-用户ID、计算机SID-用户ID
SID 列表都会存储在域控的 AD 或者计算机本地账户数据库中
产生过程:
每个进程创建时都会根据登录会话权限由 LSA(Local Security Authority)分配一个 Token(如果CreaetProcess 时自己指定了 Token, LSA 会用该 Token, 否则就用父进程 Token 的一份拷贝。
利用工具:
Incognito
Powershell - Invoke-TokenManipulation.ps1
Cobalt Strike - steal_token
危害:
假冒域管理员的令牌,从控制 DC