Windows本地认证
NTLM Hash是支持Net NTLM认证协议及本地认证过程的,其长度为32位,由数字字母组成。
windows本身不存储用户的明文密码,它会将用户的明文密码经过加密算法后存储在SAM(C:\WINDOWS\system32\config)数据库中。
当用户登录时,会将用户输入的明文密码也加密成NTLM Hash,与SAM数据库中的NTLM Hash进行比较。
NTLM hash生成方法
该hash的生成方法:
- 将明文口令转换成十六进制的格式
- 转换成Unicode格式,即在每个字节之后添加0x00
- 对Unicode字符串作MD4加密,生成32位的十六进制数字串
本地认证流程
登录时有两个重要进程:winlogon.exe和lsass.exe。
winlogon.exe(Windows Logon Process)是用户的登录程序,用于管理用户登录和退出;lsass.exe是微软Windows系统的安全机制,用于本地安全和登录策略。
winlogon.exe接收用户输入的账号和密码,然后给lsass.exe。lsass.exe会进行缓存、加密密码获得ntlm hash,读取SAM文件与加密后的ntlm hash比较,若相同,则会将User SID和Group SID发送给winlogon.exe,准备登录界面;若不相同,则登录失败。
在渗透测试中,通常可从Windows系统中的SAM文件和域控的NTDS.dit文件中获得所有用户的hash,通过Mimikatz读取lsass.exe进程能获得已登录用户的NTLM hash。
Windows Vista和Windows Server 2008以前的系统还会使用LM hash,LM hash的生成方法本文暂不介绍,自Windows Vista和Windows Server 2008开始,Windows取消LM hash。
Windows网络认证
NTLM 协议
NTLM是除Kerberos之外的一种网络认证协议,只支持Windows。它是一种基于质询/应答 (Challenge/Response)消息交换模式的认证机制, 常用于工作组和域环境下登录场景的身份认证。
早期SMB协议(文件共享)在网络上传输的是明文口令进行身份验证,很不安全。后来出现LM验证机制,也是很简单容易被破解。于是微软提出了WindowsNT挑战/响应验证机制,称之为NTLM协议。现在已经有了NTLM v2以及Kerberos验证体系。
Challenge/Response
NTLM v2协议
第一步协商:客户端在这一步向服务器确认协议的版本,是v1还是v2……
第二步质询:
- 客户端将用户信息(包括用户名)发送到服务器
- 服务器生成一个16位的随机数,称为”Challenge”,并发送给客户端
- 客户端使用用户密码的Hash对Challenge进行加密,然后将结果response(Net-NTLM hash)返回给服务器
- 服务器使用用户名从SAM数据库中检索用户密码Hash,使用此密码Hash对Challenge进行加密
- 服务器将其加密的Challenge(在步骤4中)与客户端计算的response(在步骤3中)进行比较。如果它们相同则身份验证成功
第三步验证:上面第5步就是。
NTLM v1与NTLM v2
NTLM v1与NTLM v2最显著的区别就是Chanllege与加密算法不同。共同点就是加密的原料都是NTLM Hash。
chanllege方面:NTLM v1的chanllege有8位;NTLM v2的chanllege有16位。
加密算法方面:NTLM v1的主要加密算法是DES;NTLM v2的主要加密算法是HMAC_MD5。
Pass The Hash
Pass The Hash,哈希传递,PTH
原理:就是使用用户名对应的NTLM Hash将服务器给出的Chanllege加密,生成一个Response,来完成认证。就是说不需要明文密码就可以完成一整个NTLM协议的认证流程。
必要条件:
- 需要被认证的主机能够访问服务器
- 需要被传递认证的用户名
- 需要被传递认证用户的NTLM Hash
利用工具:smbmap、CrackMapExec、Smbexec、Metasploit、……
本地抓取Hash
在渗透测试中,通常可从Windows系统中的SAM文件和域控的NTDS.dit文件中获得用户hash,通过读取lsass.exe进程能获得已登录用户的NTLM hash(因为lsass.exe有缓存)。但需要注意的是大部分本地抓取hash工具都需要管理员权限。
Mimikatz
Mimikatz可以抓到本机的明文密码和其他用户的Hash密码,原因是因为其抓取本地lsass文件,lsass中有经过其它非Hash加密后的密码,此加密算法可逆因而得到明文密码;而得到其它用户Hash加密后的密码是因为ntds.dit中存储本来就是用户Hash加密后的密码
privilege::debug sekurlsa::logonpasswordsProcdump+Mimikatz
procdump是微软提供的一个命令行实用程序,用于监视应用程序并生成故障转储。可以用其先dump对方主机的lsass内存文件,然后用mimikatz等工具进行处理。这种方式的好处是可以避免被查杀
转储lsass内存文件 procdump.exe -accepteula -ma lsass.exe lsass.dmp Mimikatz破解lsass sekurlsa::minidump lsass.dmp sekurlsa::logonpasswords
Kerberos
Kerberos 是一种网络认证协议,其设计目标是通过密钥系统为客户机 / 服务器应用程序提供强大的认证服务。 该认证过程的实现不依赖于主机操作系统的认证,无需基于主机地址的信任,不要求网络上所有主机的物理安全,并假定网络上传送的数据包可以被任意地读取、修改和插入数据,有效防范了中间人攻击。
在Kerberos协议中主要是有三个角色的存在:
访问服务的Client
提供服务的Server
KDC(Key Distribution Center)密钥分发中心
其中KDC 中有两个服务:
- Authentication Service(AS):身份验证服务,为client生成TGT的服务。
- Ticket Granting Service(TGS):票据分发服务,为client生成某个服务的ticket。
其中KDC服务默认会安装在一个域的域控中,而Client和Server为域内的用户或服务。
域控(DC)的AD(account database):存储所有client的白名单,只有存在于白名单的client才能顺利申请到TGT。
在Kerberos中Client是否有权限访问Server端的服务由KDC发放的票据来决定。
Kerberos协议认证流程

粗略流程:
client向 kerberos 服务请求,希望获取访问 server 的权限。kerberos 得到了这个消息,首先得判断 client 是否是可信赖的,也就是白名单黑名单。这就是 AS 服务完成的工作,通过在 AD 中存储黑名单和白名单来区分 client 。成功后,返回 AS 返包 TGT 给 client。
client 得到了 TGT 后,继续向 kerberos 请求,希望获取访问server 的权限。 kerberoS 又得到了这个消息,这时候通过 client 消息中的 TGT ,判断出了 client 拥有了这个权限,给了 client 访问 server 的权限 ticket。
client 得到 ticket 后,终于可以成功访问 server 。这个 ticket 只是针对这个 server ,其他 server 需要向 TGS 申请。
详细流程:
为了更容易理解,有的名称可能和主流的不一样。
客户端发送自己的信息以及要连接的服务器信息给AS,AS去AD查看是否是白名单。客户端发送的
KRB_AS_REQ包含的详细信息如图:
AS随机生成session key,AS返回两个 TGT票据:
- TGT1 (session key,tgs 服务信息,结束时间) (客户的 NTLM hash 加密)、
- TGT2 (session key,客户信息,结束时间) (KDC NTLM hash 加密)
客户端拿到两个 TGT票据然后解密TGT1得到session key,再生成认证因子。
先用自己的 NTLM hash 解密 TGT1
得到 session key,tgs 服务信息,结束时间
然后生成认证因子(客户信息,时间戳,….….)(用解密出来的 session key 加密)
发送给 TGS :认证因子+TGT2+客户端信息+服务端信息TGS拿到 认证因子+TGT2+客户端信息+服务端信息
先用 KDC NTLM hash 解密TGT2得到 session key,客户信息,结束时间。
再用 session key 解密 认证因子 得到客户信息,时间戳……
经过校验: 时间戳和当前时间
解密的TGT2里面的客户信息与 session key 解密的认证因子的客户信息
客户端权限访问服务端
然后自己随机生成 server session key
TGT3( server session key ,服务器信息,票据到期时间)( session key 加密)
TGT4( server session key ,客户信息,票据到期时间)(服务端 NTLM hash 加密)客户端收到TGT3,TGT4
首先用session key(客户端已得到) 解密 TGT3,得到 server session key,服务器信息,票据到期时间
再生成认证因子2(服务器信息,票据到期时间) 用 server session key 加密
发送给服务端:认证因子2+TGT4服务端收到客户端
用 服务端 NTLM hash 解密TGT4 得到:server session key ,客户信息,票据到期时间
用 server session key 解密认证因子2得到:服务器信息,票据到期时间
然后拿着信息去KDC那边问客户有没有访问权限。
注意两个重要名称:TGT里包含的是session key,Ticket里包含的是server session key。
白银票据
特点:
- 不需要与KDC进行交互
- 需要目标服务的NTLM Hash
在第四步之前TGS认证的Ticket的组成:
Ticket=Server Hash(server session key ,客户信息,票据到期时间)
当拥有Server Hash(服务端 NTLM hash)时,我们就可以伪造一个不经过KDC认证的Ticket。
Tips:Server session key在未发送Ticket之前,服务器是不知道server session key是什么的,所以我们可以伪造server session key。
一切凭据都来源于Server hash。
黄金票据
特点:
- 需要与DC通信
- 需要krbtgt用户的hash(KDC NTLM Hash)
白银票据伪造的是Ticket,黄金票据伪造的是TGT。
当我们有KDC的NTLM hash后,可以给自己签署GT票据,跳过1、2步。TGT仅用于向域控制器上的KDC服务证明用户已被其他域控制器认证。TGT被KRBTGT密码散列加密并且可以被域中的任何KDC服务解密的。
通常在拿下域控后用来作权限维持的一种方式。因为krbtgt 域账户的密码基本不会更改,即使域管密码被修改,它也不会改变。
参考链接:
Kerberos 篇 - windows protocol (gitbook.io)
Windows下的密码hash——NTLM hash和Net-NTLM hash介绍