Windows认证及其票据传递
网上大佬的文章很多,这里仅此记录学习到的笔记。如有兴趣可以看最后发的参考文章来学习[都是大佬]
初始Windows认证
windwos认证方式主要分为NTLM 和 Kerberos。而Access Token记录用户的SID、组SID、Session及其权限等信息,当然也起到权限认证。
- NTLM可以分为本地验证和网络验证,本地验证密码是存储在SAM文件,而网络验证是基于一种Challenge/Response认证机制。
- Kerberos认证存在域环境中,是基于一种票据(Ticket)认证的方式。他整个认证过程设计三方:客户端、服务端、KDC。KDC一般由DC来操控。
- Access Token[访问令牌]是用来描述线程安全的上下文对象,令牌包含的信息是与该账户线程相关的身份和权限信息。当用户登录的时候系统会生成一个Access Token,然后以该用户身份运行的所有进程都拥有该身份令牌的拷贝。
NTLM
Windwos密码的组成
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和NTLM区别
两者的区别就是加密的规则不一样。因为LM相对容易破解所以后来就有了NTLM
LM生成规则
1.用户的密码被限制为最多 14 个字符。
2.用户的密码转换为大写。
3.系统中用户的密码编码使用了 OEM 内码页
4.密码不足 14 字节将会用 0 来补全。
5.固定长度的密码被分成两个 7 byte 部分。每部分转换成比特流,在分 7bit 为一组末尾加 0,组成新的编码
6.上步骤得到的 8 byte 二组,分别作为 DES key 为 "KGS!@#$%" 进行加密。
7.将二组 DES 加密后的编码拼接,得到最终 LM HASH 值。
NTLM生成规则
1.将密码字符串转化为 ASCII 字符串
2.ASCII 字符串再转换为十六进制字符串
3.十六进制字符串再转化为 Unicode 字符串
4.然后对 Unicode 字符串使用 MD4 消息摘要算法
NTLM本地认证
在本地登录的情况下,操作系统会使用用户输入的密码作为凭据去与系统的密码进行校验,一样的话就通过。
操作系统的密码是存储在%SystemRoot%\system32\config\sam
但是他是以Hash是方式存储的。
他的生成规则上面也提到了,认证流程就是
winlogon.exe -> 接收用户输入 -> lsass.exe -> (认证)
NTLM网络认证
网络认证是必须要依托于第三方服务的类似于中介。而Windwos常使用NTLM网络认证的地方有SMB、Telnet。
在网络认证时候基于挑战(Chalenge)/响应(Response)认证机制的一种认证模式。当然也是需要分三个步骤来完成的。
- 协商:主要用于确认双方协议版本、加密等级等。
- 挑战:也就是挑战(Chalenge)/响应(Response)认证机制起作用的时候。
- 认证:验证主要是在挑战完成后,验证结果,是认证的最后一步。
详细流程
- 第一步:输入密码,然后LSASS会把密码的NTLM Hash后的值先存储到本地。
- 第二步:客户端把用户名的明文发送给服务端
- 第三步:服务端接收到用户名之后会判断用户名是否存在,不存在则代表认证失败。存在的话服务端会生成一个16位的随机数,并且从本地查找share_user对 应的NTLM Hash,使用NTLM Hash加密Chanllenge,生成一 个Net-NTLM Hash存在内存中,并将Chanllenge发送给客户端。
- 第四步:当客户端收到challenge后,用在第一步中存储的NTLM Hash对其加密,然后再将加密后的challenge发送给服务器,也就是response,表现形式是Net-NTLM Hash。
- 第五步:服务端在收到response后,会向DC发送针对客户端的验证请求。该请求主要包含以下三方面的内容:客户端用户名、客户端NTLM Hash加密的Challenge、原始的Challenge。
- 第六步:当DC接到过来的这三个值的以后,会根据用户名到DC的账号数据库(ntds.dit)里面找到该用户名对应的NTLM Hash,然后把这个hash拿出来和传过来的challenge值进行比较,相同则认证成功,反之,则失败。
这个具体实现细节可以阅读最后一个参考。
NTLM V1和V2的区别
他们两个最显著的区别就是Chllenage与加密算法的不同,当然共同点就是都是以NTLM Hash来的
- Challage:NTLM v1的Challenge有8位,NTLM v2的Challenge为16位。
- Net-NTLM Hash:NTLM v1的主要加密算法是DES,NTLM v2的主要加密算法是HMAC-MD5。
Kerberos
名词基本概念
- KDC: Key Distribution Center,密钥分发中心,负责管理票据、认证票据、分发票据,但是KDC不是一个独立的服务,它由AS和TGS组成。
- AS: Authentication Service,验证服务,为client生成TGT的服务
- TGS: Ticket Granting Service,票据授予服务,为client生成某个服务的ticket
- TGT: Ticket Granting Ticket,入场券,通过入场券能够获得票据,是一种临时凭证的存在。
- Ticket:票据,是网络中各对象之间互相访问的凭证
- AD: Account Database,存储所有client的白名单,只有存在于白名单的client才能顺利申请到TGT。
- DC: Domain Controller,域控
- KRBTGT: 每个域控制器都有一个krbtgt账户,是KDC的服务账户,用来创建TGS加密的密钥。
详细流程
AS-REQ—AS-REP阶段:
首先Client用自己的哈希值NTLM-hash对timestamp、client-info、server-info等数据进行加密,发送给AS,向AS请求TGT票据。(AS-REQ)
当AS收到Client发来的信息后,AS会先向域控AD请求,询问是否有此Client用户,如果有的话,就会取出该Client的NTLM hash,然后生成一个随机秘钥称为Session-Key as(临时秘钥Session-Key)。并使用Client NTLM-hash 加密 Session-key as 作为一部分内容。
还有一部分内容就是TGT:使用KDC一个特定账户krbtgt的NTLM-hash对Session-key as、timestamp、Client-info进行的加密。然后将这两部分回复给Client。(AS-REP)
该阶段是Client和AS的认证。
TGT中用户唯一不知道的是krbtgt这个hash,有了的话就可以自己伪造TGT,也就是所谓的金票据。
TGS-REQ—TGS-REP阶段:
Client 收到AS发来的AS-REP后,先使用自身的 NTLM Hash 解密得到 Session-key as,然后使用 Session-key as 对 Client-Info、timestamp、Server-Info 加密作为一部分,加上TGT ,一并发送给 KDC中的 TGS。(TGS-REQ)
TGS 收到请求后,使用 krbtgt 的 NTLM Hash 解密 TGT,得到 Session-key as、timestamp、Client-info,同时,使用 TGT 解密出的 Session-key as 解密第一部分内容,得到Client-info、timestamp。 比对这两部分解密得到的内容以验证是否通过。通过后,生成一个新的随机秘钥(Session-Key tgs),其实就是Server session key并向Client回复TGS-REP的两部分内容:
- 一部分是Session-key as 加密的Session-key tgs
- 另一部分是ST(ticket),即Server NTLM-hash加密的数据(Session-key tgs、timestamp、Client-info)
该阶段是Client和KDC的通信。
ST中用户唯一不知道的是server的密码hash,所以有了这个hash,就可以自己伪造ST,也就是所谓的银票据。
AP-REQ—AP-REP阶段:
Client收到TGS-REP后,先用自己保存的Session-key as解密出了Session-key tgs。再使用Session-key tgs加密Client-info、timestamp作为一部分内容,另一部分是ST,一并发送给Server。(AP-REQ)
Server 收到Client发来的AP-REQ后,用自身的NTLM Hash解密了ST,得到Session-key tgs,再用Session-key tgs解密第一部分得到Client-info、timestamp。然后与ST的Client-info、timestamp进行对比。timestamp 一般时间为8小时。验证通过后,回复AP-REP,最终建立通信。
上面拷贝为@WHAOMI大佬
黄金票据
在Windows的kerberos认证过程中,Client将自己的信息发送给KDC,然后KDC使用krbtgt用户的Hash作为密钥进行加密,生成TGT。那么如果获取到了krbtgt的Hash值,不就可以伪造任意的tgt了吗。因为krbtgt只有域控制器上面才有,所以使用黄金凭据意味着你之前拿到过域控制器的权限,黄金凭据可以理解为一个后门。
攻击者攻击前提需要掌握:
- 需要伪造的域管理员用户名
- 完整的域名
- 域SID
- krbtgt的NTLM Hash
首先登陆域控抓取krbtgt用户的Hash值并获取域sid
privilege::debug
lsadump::lsa /patch // 专用于在域控制器上导出用户密码或hash
我们切换域控普通,用mimikatz生成名为ticket.kirbi的TGT凭证
kerberos::golden /user:需要伪造的域管理员用户名 /domain:demo.com /sid:域sid /krbtgt: krbtgt用户的Hash /ticket:ticket.kirbi
生成TGT凭证ticket.kirbi成功,名为ticket.kirbi,然后使用mimikatz将凭证ticket.kirbi注入进去:
kerberos::ptt ticket.kirbi
kerberos::ptt <票据文件>
然后就可以使用psexec,wmi等方法进行远程执行命令了
白银票据
白银票据不同于黄金票据,白银票据的利用过程是伪造TGS,通过已知的授权服务密码生成一张可以访问该服务的TGT。因为在票据生成过程中不需要使用KDC,所以可以绕过域控制器,很少留下日志。而黄金票据在利用过程中由KDC颁发TGT,并且在生成伪造的TGT得20分钟内,TGS不会对该TGT的真伪进行效验。
白银票据依赖于服务账号的密码散列值,这不同于黄金票据利用需要使用krbtgt账号的密码哈希值,因此更加隐蔽。
攻击者要利用白银票据进行票据传递攻击,需要掌握下面几个信息:
- 域名
- 域SID
- 目标服务器的FQDN
- 可利用的服务
- 服务账号的NTLM Hash
- 要伪造的用户名
kerberos::golden /domain:<域名> /sid:<域 SID> /target:<目标服务器主机名> /service:<服务类型> /rc4:<NTLM Hash> /user:<用户名> /ptt
- /sid:域的SID值
- /rc4:server机器的hash
- /service:可利用的服务,这里是cifs
- /user:要伪造的用户名,任意填写
- /target:域控制器名,即FQDN(全称)
由于白银票据需要目标服务器的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 |
kerberos::list #列出票据
kerberos::purge # 清除票据
MS14-068
在讲解MS14-068之前,我们要先了解PAC这个东西,PAC是用来验证Client的访问权限的,它会被放在TGT里发送给Client,然后由Client发送给TGS。
服务器收到客户端的TGS后,需要将客户端在TGS中声明的域组与服务器上的ACL进行配对,然后决定授予客户端什么样的资源访问权限。 Microsoft 使用 PAC 来表示客户端在 TGS 中声明的域组, PAC即特权属性证书。PAC 包含客户端用户的 SID 和组的 SID。 PAC决定了客户端的组属性,即客户端PAC的权限
MS14-068是密钥分发中心(KDC)服务中的Windows漏洞。它允许经过身份验证的用户在其Kerberos票证(TGT)中插入任意的PAC(表示所有用户权限的结构)。该漏洞位于kdcsvc.dll域控制器的密钥分发中心(KDC)中。普通用户可以通过呈现具有改变了PAC的Kerberos TGT来获得票证,进而伪造票据获得管理员权限。
利用条件:
- 域控没有打KB3011780补丁
- 拥有一个可以访问域内资源的账号权限。(domain users组里的任意一个账号就行)
当我们满足上面条件的时候,在Windows 7上传工具ms14-068.exe,并执行如下命令生成TGT票据:
ms14-068.exe -u 域成员名@域名 -s 域成员sid -d 域控制器ip地址 -p 域成员密码
成功生成了票据,然后现在就注入内存吧。
mimikatz # kerberos::ptc 票据文件 //将票据注入到内存中
查看注入是否成功klist:
然后我们就可以使用net use或者其他工具进行远程命令执行等等操作了
Windows Access Token
Windows Token其实叫Access Token(访问令牌),它是一个描述进程或者线程安全上下文的一个对象。不同的用户登录计算机后, 都会生成一个Access Token,这个Token在用户创建进程或者线程 时会被使用,不断的拷贝,这也就解释了A用户创建一个进程而该 进程没有B用户的权限。令牌就是系统的临时密钥,相当于用户名和密码,用来决定是否允许这次请求和判读这次请求属于那个用户,它允许你不提供凭证的前提下访问网络和系统资源。
Access Token的种类:
- 主令牌:交互会话登陆[直接登陆账户]
- 模拟令牌:用于非交互登陆[如net use共享文件]
Access Token的组成
- 用户帐户的安全标识符(SID)
- 用户所属的组的SID
- 用于标识当前登录会话的登录SID
- 用户或用户组所拥有的权限列表
- 所有者SID
- 主要组的SID
- 访问控制列表
- 访问令牌的来源
- 令牌是主要令牌还是模拟令牌
- 限制SID的可选列表
- 目前的模拟等级
- 其他统计数据
Windows Access Token SID安全标识符
安全标识符是一个唯一的字符串,它可以代表一个账户、一个用户 组、或者是一次登录。通常它还有一个SID固定列表,例如 Everyone这种已经内置的账户,默认拥有固定的SID。
SID的表现形式:
- 域SID-用户ID
- 计算机SID-用户ID
- SID列表都会存储在域控的AD或者计算机本地账户数据库中。
Windows Access Token产生过程
每个进程创建时都会根据登录会话权限由LSA(Local Security Authority)分配一个Token(如果CreaetProcess时自己指定了 Token, LSA会用该Token, 否则就用父进程Token的一份拷贝。
Windows Access Token令牌假冒
getsystem
load incognito
list_tokens –u
impersonate_token "WIN7\gokteh"
参考文章
1-2是倾旋大佬的
https://www.bilibili.com/video/av51717543/
https://payloads.online/archivers/2018-11-30/1/
//kerberos详细
https://www.jianshu.com/p/13758c310242
https://www.cnblogs.com/wjrblogs/p/13549585.html
https://mp.weixin.qq.com/s/UPzt80QBBlCUZvs2wKCwzw
https://www.freebuf.com/articles/system/270495.html
https://www.freebuf.com/articles/245872.html
//建议原文学习一遍
http://davenport.sourceforge.net/ntlm.html#theNtlmResponse