1. 前言
无意中看到的,稍微研究了下,简单理解就是一种另类的权限维持方式。
shadow credential是一个ace属性msDS-KeyCredentialLink
。Windows中有一种无密码身份验证的方式叫做PKINIT
,它是通过证书进行身份验证的。
2. 利用逻辑
假设我们给Tom账号添加shadow credential后,我们可以通过工具获得一个.pfx后缀文件与pfx文件密码,这是个私钥证书文件,密码就是证书的密码。
通过证书进行身份验证
的逻辑是:
- 用私钥加密一段时间戳发送给KDC并声明自己的身份例如Tom。
- 服务端用Tom的公钥解密这段密文,如果成功则发送Tom的TGT给认证者。
因此我们可以利用这个pfx文件和pfx文件密码申请Tom账号的TGT,并且可以进行解密得到Tom的ntlm hash。只要shadow credential属性没有被删除,无论Tom账号的hash是否改变,我们都可以获得当前最新的hash。
至于能获得ntlm hash的原因大概是,工具可以替我们实现例如Tom申请访问Tom自己的服务。这样就会获得一张Ticket。这个TIcket里面包含一个PAC这个PAC里面有Tom的ntlm hash。我们解密这个ticket即可获得hash。
在PKINIT的认证反思下,如果我们进行TGS-REQ的时候,将我们要访问的目标服务的TGT放在addition ticket下的话,KDC就会用addition ticket中TGT中存的session key 加密即将发给我们的ticket。
这时候我们可以尝试进行自己访问自己服务的操作。这里以Tom为例,我们用Tom的TGT请求Tom自己的服务,即将Tom的TGT放在addition ticket中。这时候生成的ticket就是用Tom的TGT中的session key加密的了,而我们又是知道这个session key的(因为在AS-REP阶段就会跟TGT一起发送过来,跟普通的kerberos不太一样),因此可以解密最终得到ntlm hash。
3. 利用条件
- 至少一台 Windows Server 2016 域控制器。
- 域功能级别为win server 2016或者更高。
- 开启AD CS或者CA。
综上,只要能改变某个账号的msDS-KeyCredentialLink属性,且满足上面三个条件,我们就能获得这个账号的TGT和ntlm hash。
4. 谁能增添msDS-KeyCredentialLink属性
- 域管
- key credential admin
- 机器账号自己给自己新增
- 具有高权限ACL的账户
5. 利用过程
1.利用一个域控账号给其他账户添加msDS-KeyCredentialLink属性
工具下载地址:
pywhisker
python3 pywhisker.py -d "bsec.corp" -u "win7" -p "your_password" --target "win10" --action "add" -o test1 --dc-ip dc3.bsec.corp
它会输出一个test1.pfx,还有一串密码。
2.获得tgt
工具下载地址:
PKINITtools
python3 gettgtpkinit.py sec.corp/win10 -cert-pfx test1.pfx -pfx-pass xwnFLH0kconJ2cfts9Gp win10.ccache -dc-ip dc3.sec.corp
3.获得hash
python3 getnthash.py -key 182....... sec.corp/win10 -dc-ip dc03.sec.corp
6. 参考文章
Shadow Credentials: Abusing Key Trust Account Mapping for Account Takeover