申请TGT之前有一个过程叫做pre-auth,可以使用 DES、RC4、AES128 或 AES256 加密,或使用非对称(使用 证书)预认证。预认证的不对称方式称为 PKINIT(这是2016引入的)。 比如说普通的可以看到加密方式为AES256: 什么是PKINIT? PKINIT 是不太常见的非对称密钥方法。客户端有一个公私钥对,并用他们的私钥对预认证数据进行加密,KDC 用客户端的公钥对其进行解密。 此外,KDC 还有一个公私密钥对,允许交换会话密钥。 PKINIT 协议文档: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-pkca/d0cf1763-3541-4008-a75f-a5 77fa5e8c5b Windows Server2016域功能级别中,LDAP有一个名为 msDS-KeyCredentialLink 的属性,可以在其中设置公 钥。当使用 PKINIT 进行预认证时,KDC 将检查认证用户是否知道匹配的私钥,如果匹配,将发送 TGT。 所以说如果我们可以控制能够编辑其他对象的 msDS-KeyCredentialLink 属性的帐户的话,那么这允许我们创 建密钥对,附加到该属性中的公钥,并获得对目标对象(可以是用户或计算机)的持久和隐秘访问。 利用条件 1. 位于域功能级别为 Windows Server 2016 或更高版本的域中(或至少一个运行 Windows Server 2016 或更 高版本的域控制器) 2. DC拥有自己的密钥对(用于会话密钥交换)(例如,在启用 AD CS 或存在证书颁发机构 (CA) ) 3. 可以控制编辑目标对象的 msDs-KeyCredentialLink 属性的帐户 当时群里纠结的问题是,明明自签名证书的情况下把公钥写入 msDs-KeyCredentialLink 属性,我们使用私钥 去请求TGT即可。好像并不需要ADCS或者一个CA开放,因为感觉KDC就把这个事情做了,还需要他们干什么。 其实DC还需要一个会话密钥交换的过程,DC还有一个公私钥,如果环境有 ADCS 和 CA 可用,DC会自动获取 证书。用来进行会话密钥交换。 Key Trust Mode 并且微软还引入了一个Key Trust模式,以支持在不支持证书信任的环境中进行无密码身份验证。在 Key Trust 模 式下,PKINIT 身份验证是基于原始密钥数据,而不是证书建立的。 客户端的公钥存储在名为 所以说条件2还是必须的。 msDS-KeyCredentialLink 的多值属性中,但是DC还是需要用于密钥交换的证书, 所以说基于这个Key Trust模式,我们上述的攻击才可以成立。 有权限修改 msDs-KeyCredentialLink 属性的帐户有: 1. 域管 2. KeyCredential Admins 3. Acl高权限用户 4. 机器账号给自己新增 利用思路 1.直接修改目标 msDs-KeyCredentialLink 属性 使用工具: https://github.com/eladshamir/Whisker https://github.com/ShutdownRepo/pywhisker Whisker.exe add /target:"TARGET_SAMNAME" /domain:"FQDN_DOMAIN" /dc:"DOMAIN_CONTROLLER" /path:"cert.pfx" /password:"pfx-password" pywhisker.py -d "FQDN_DOMAIN" -u "user1" -p "CERTIFICATE_PASSWORD" --target "TARGET_SAMNAME" --action "list" 2.Relay的方式修改目标 msDs-KeyCredentialLink 属性 可以使用常规relay方法,比如我们知道机器账户可以自己给自己新增,那么: 1. webdav配合efs这类工具无需签名利用 2. -remove-mic,利用1040绕过签名 python3 ntlmrelayx.py --shadow-credent --shadow-target 'dc2$' -t ldap://dc1 --remove-mic 还可以relay特殊用户、DA的NTLM请求,因为高权限用户也可以修改这个属性 所以说又可以配合添加域内DNS记录发链接给高权限用户的利用方法了。 与RBCD的区别 1. 攻击的目标对象可以是用户账户也可以是机器账户 2. 不需要利用默认MAQ特性去添加机器账户 3. 不需要目标机器当前存活