权限
Windows 中的“权限”不是一个单一概念。判断一个进程能做什么,通常需要同时看:
账户身份
+ 访问令牌
+ 完整性级别
+ 用户权限特权
+ 对象 ACL
+ 进程保护状态
+ 当前会话和隔离边界
例如:
- 属于 Administrators 组,不代表进程已经以管理员权限运行;
SYSTEM是高权限用户身份,但不等于内核态;TrustedInstaller是特殊服务身份,不是独立的完整性级别;- 进程处于 High Integrity,也不代表可以访问所有受保护进程;
- 拥有某个特权,也不代表所有对象都可以任意读写。
核心概念
访问令牌
进程和线程通常通过访问令牌(Access Token)表示其安全上下文。令牌中可能包含:
- 用户 SID;
- 所属组 SID;
- 完整性级别 SID;
- 已启用、禁用或仅用于 deny-only 判断的特权;
- 默认 DACL;
- 模拟级别和会话信息。
当程序访问文件、注册表、进程、线程、服务等对象时,Windows 会根据令牌与目标对象安全描述符进行访问检查。
完整性级别
完整性级别(Integrity Level,IL)用于限制不同信任程度的进程之间进行写入或发送特定操作。常见级别包括:
Untrusted
↓
Low
↓
Medium
↓
High
↓
System
完整性级别主要解决“低信任进程能否影响高信任进程”的问题,不等于完整的用户权限列表。实际访问还会受到 DACL、特权、PPL、沙箱和对象自身安全策略影响。
用户权限特权
特权(Privilege)是令牌中的特殊能力,例如:
SeDebugPrivilege:便于调试或访问其他进程;SeImpersonatePrivilege:允许在特定条件下模拟其他身份;SeAssignPrimaryTokenPrivilege:与为进程分配主令牌相关;SeCreateGlobalPrivilege:创建全局命名对象;SeLoadDriverPrivilege:加载内核驱动;SeBackupPrivilege/SeRestorePrivilege:绕过部分文件访问检查进行备份或恢复。
特权通常需要先被授予,再被进程显式启用。拥有特权也不意味着可以无条件绕过所有安全边界。
常见权限等级
下表是常见 Windows 进程上下文的概览。它是分析和排查用的简化模型,实际能力仍取决于具体令牌、ACL、策略和保护机制。
| 上下文 / 等级 | 常见主体 | 常见完整性级别 | 通常可以做什么 | 通常不能直接做什么 |
|---|---|---|---|---|
| Untrusted | 极度受限的沙箱内容 | Untrusted | 执行极少量受限操作 | 访问大多数用户和系统资源 |
| Low | 浏览器低权限组件、部分沙箱进程 | Low | 运行受限代码、访问被授予的低权限资源 | 向 Medium 或更高完整性进程写入,修改大多数用户和系统资源 |
| 标准用户 | 普通登录用户启动的程序 | Medium | 执行程序、访问自己的文件、网络通信、写入用户目录 | 写入系统目录、修改系统服务、访问高权限进程 |
| 管理员组成员的非提升进程 | UAC 过滤后的管理员进程 | Medium | 大部分普通用户操作,可能拥有管理员组的 deny-only SID | 直接执行需要 High Integrity 的系统修改 |
| 提升后的管理员 | UAC 确认后的管理员进程 | High | 写入受保护系统目录、管理服务和计划任务、执行许多系统级配置操作 | 仍可能受 PPL、ACL、Credential Guard 和内核保护限制 |
| LocalService / NetworkService | Windows 服务账户 | 通常 Medium 或更高,依服务配置 | 运行系统服务;NetworkService 可使用计算机账户访问网络 | 不等于 SYSTEM,不能自动访问所有本机资源 |
| SYSTEM | services.exe、系统服务、SYSTEM 任务 | System | 访问大量本机资源、管理服务、操作其他用户资源 | 不等于内核权限,仍可能受 PPL、对象 ACL 和安全策略限制 |
| TrustedInstaller | Windows Modules Installer 相关服务 | 通常 System | 管理部分由 TrustedInstaller 拥有的系统组件 | 不是万能身份,也不是内核态 |
| 受保护进程 / PPL | LSASS、部分安全组件等 | 视进程令牌而定 | 在保护策略允许范围内运行 | 普通管理员或 SYSTEM 也可能无法直接读写或注入 |
| Kernel | 内核驱动和内核代码 | 不适用用户态 IL | 访问内核对象、内存管理和驱动边界 | 不属于普通用户态进程权限,进入该层需要驱动加载或内核漏洞等路径 |
各等级的能力边界
Untrusted / Low
这类进程通常用于沙箱、浏览器隔离或受限组件。它们可能能够执行代码,但访问范围受到严格限制:
- 只能访问显式授予的文件、目录、对象和 IPC;
- 通常不能向普通用户的 Medium Integrity 进程写入;
- 不能直接修改系统服务、系统目录和其他用户资源;
- 进程间通信可能需要经过沙箱代理或受限接口。
Low Integrity 不是“不能联网”或“不能运行代码”,而是“运行代码时不能随意影响更高信任级别对象”。
标准用户 / Medium Integrity
普通用户点击启动的 EXE、脚本解释器和大多数桌面程序,通常处于 Medium Integrity。它们可以:
- 读取和执行用户可访问的程序;
- 读取当前用户配置、浏览器数据和用户目录;
- 访问网络;
- 创建子进程;
- 写入当前用户目录和用户级配置;
- 创建当前用户范围的启动项、任务或配置。
常见可写目录包括:
C:\Users\<用户名>\AppData\Local\Temp
C:\Users\<用户名>\AppData\Local
C:\Users\<用户名>\AppData\Roaming
C:\Users\<用户名>\Downloads
C:\Users\<用户名>\Desktop
其中,Windows 临时目录的完整路径通常是 C:\Users\<用户名>\AppData\Local\Temp,用户漫游数据目录的完整路径通常是 C:\Users\<用户名>\AppData\Roaming。
不同用户的 <用户名> 不同;服务账户、SYSTEM 账户和管理员账户的实际用户目录也可能不同。
标准用户通常不能直接:
- 向
C:\Program Files、C:\Program Files (x86)写入; - 向
C:\Windows\System32写入; - 修改系统范围服务、驱动和防火墙策略;
- 访问其他用户的受限目录;
- 任意打开并写入 SYSTEM 或 PPL 进程。
但标准用户可以执行 C:\Program Files 中已经存在且允许读取执行的程序。
可以执行 Program Files 中的已有文件
不代表可以在 Program Files 中创建或修改文件
管理员组成员的非提升进程
UAC 开启时,即使用户属于 Administrators 组,普通双击启动的程序也通常使用经过过滤的 Medium Integrity 令牌。管理员组 SID 可能以 deny-only 形式存在,程序不能直接使用完整管理员权限。
因此:
属于 Administrators 组
≠
当前进程已经是 High Integrity
普通双击、从浏览器启动或从 Office 派生的恶意进程,通常先以 Medium Integrity 运行,再尝试诱导 UAC、绕过 UAC 或寻找其他提权路径。
提升后的管理员 / High Integrity
用户确认 UAC,或程序通过其他方式获得提升令牌后,进程可能进入 High Integrity。此时通常可以:
- 写入部分系统目录和受保护安装目录;
- 创建、修改和启动服务;
- 创建系统范围计划任务;
- 修改系统级注册表、网络和防火墙配置;
- 启用某些被授予的特权;
- 访问更多高权限进程和系统对象。
High Integrity 仍不是“无条件完全控制”。例如:
- PPL 进程可能拒绝普通管理员访问;
- Credential Guard 会减少凭据可访问性;
- 对象 DACL 仍可能拒绝请求;
- 安全产品可能有自保护和内核防护;
- 某些系统组件由 TrustedInstaller 拥有。
SYSTEM
SYSTEM 是本机上的高权限服务身份,常见于:
- Windows 服务;
- 以 SYSTEM 运行的计划任务;
services.exe及其承载的部分服务;- 系统启动阶段和本机管理组件。
SYSTEM 通常可以访问大量本机文件、注册表、服务、设备和其他用户资源,也更容易打开高权限进程。
但需要明确:
SYSTEM
≠
Kernel
≠
自动绕过 PPL / Credential Guard
≠
自动拥有 TrustedInstaller 所拥有的所有对象
TrustedInstaller
TrustedInstaller 是 Windows Modules Installer 相关的特殊服务身份。部分系统文件和组件的所有者不是 Administrators 或 SYSTEM,而是 TrustedInstaller。
攻击者可能在 SYSTEM 后继续尝试获取或模拟 TrustedInstaller,以修改或替换受保护组件。但这不是所有木马都会执行的步骤,也不应把 TrustedInstaller 当成一个比 SYSTEM 更高的通用完整性级别。
Kernel
Kernel 不是普通进程的用户态权限等级,而是执行环境边界。进入内核通常需要:
- 加载合法且受信任的内核驱动;
- 滥用存在漏洞的签名驱动(BYOVD);
- 利用内核漏洞;
- 借助已有内核组件完成操作。
进入内核后,代码可能影响进程、线程、内存、驱动、回调和安全产品边界,但仍受代码完整性、HVCI、驱动签名和系统配置影响。
权限等级转换
下表描述常见的“从低到高”路径。实际攻击可能跳过某些阶段,也可能同时使用多条路径。
| 起点 | 目标 | 常见实现或操作 | 典型结果 |
|---|---|---|---|
| Untrusted / Low | Medium 用户进程 | 沙箱逃逸、受信任代理或漏洞利用 | 进入普通用户上下文 |
| 标准用户 Medium | 当前用户的持久化 | 写入用户目录、用户级启动项、用户级任务或配置 | 不一定提升权限,但获得持续执行 |
| Medium | High 管理员 | 用户确认 UAC、requireAdministrator、安装程序或 UAC 绕过 | 进入提升后的管理员上下文 |
| Medium | High / SYSTEM | 利用高权限服务、弱权限任务、COM 或安装组件 | 借高权限代理执行操作 |
| High 管理员 | SYSTEM | 创建或修改服务、创建 SYSTEM 任务、令牌复制或模拟 | 获得本机 SYSTEM 上下文 |
| High / SYSTEM | TrustedInstaller | 获取、复制或模拟 TrustedInstaller 令牌 | 修改部分受保护系统组件 |
| High / SYSTEM | 受保护进程能力 | PPL 配置错误、受信任签名组件或内核辅助 | 访问通常被保护的进程或资源 |
| High / SYSTEM | Kernel | 加载驱动、BYOVD 或利用内核漏洞 | 进入或影响内核执行边界 |
木马常见提权路径
用户点击启动:先以 Medium 运行
一个从下载目录、邮件附件或用户目录启动的木马,最初通常继承启动它的用户令牌:
用户双击
→ 木马以当前用户身份运行
→ Medium Integrity
→ 访问用户目录、收集信息、建立 C2
它可以先把载荷写入:
C:\Users\<用户名>\AppData\Local\Temp
C:\Users\<用户名>\AppData\Local\Roaming
C:\Users\<用户名>\AppData\Roaming
这解释了为什么木马即使没有管理员权限,也能完成初始收集、用户级持久化和 C2 上线。
通过 UAC 获得 High Integrity
木马可能伪装成安装器、更新器、驱动组件或系统修复程序,诱导用户确认 UAC:
Medium 用户进程
→ 请求 requireAdministrator 或触发提升
→ 用户确认 UAC
→ High Integrity 管理员进程
→ 写入系统目录、创建服务或修改系统配置
如果用户拒绝,木马通常只能保留 Medium 权限,除非它还有其他提权路径。
UAC 绕过
正常的 UAC 提升
正常情况下,Medium 进程请求完整管理员令牌时,系统会让用户确认:
Medium 木马
→ 请求完整管理员令牌
→ Application Information 服务处理
→ `consent.exe` 显示 UAC 界面
→ 用户确认
→ 创建新的 High Integrity 进程
如果当前账户是标准用户,通常还需要输入管理员凭据;如果当前账户属于 Administrators 组,通常需要确认“是”。用户拒绝后,木马不能获得完整管理员令牌。
为什么有时不弹窗
UAC 是否弹窗,不是简单由“程序是否恶意”决定,而取决于进程 manifest、启动方式、用户账户类型、自动提升策略和系统配置。Windows 中有少数受信任系统组件被设计为可以在特定条件下自动提升,它们通常位于系统目录并具有有效签名。
攻击者利用的通常不是关闭 UAC,而是让自动提升组件读取或加载攻击者可控的内容:
Medium 木马
→ 修改自动提升组件会读取的用户级注册表 / 配置 / COM 映射
→ 启动自动提升的系统组件
→ 系统组件以 High Integrity 运行
→ 系统组件加载 DLL、激活 COM 或执行攻击者控制的参数
关键点是:原来的 Medium 木马通常没有“变成”High,而是新启动的受信任组件以 High Integrity 执行了恶意内容。由于系统认为该组件本身满足自动提升条件,过程中可能不再显示常规 UAC 确认框。
常见被滥用的机制类别包括自动提升系统二进制、用户级 COM 注册、自动提升组件读取的用户级配置或路径,以及高权限代理对不可信参数缺乏校验。具体组件会随 Windows 版本、补丁和策略变化,不能把某个文件名当作永久有效的 UAC 绕过方法。
检测证据
Medium 用户进程
→ 修改用户级注册表 / 配置 / COM 映射
→ 启动自动提升系统组件
→ 新进程为 High Integrity
→ 新进程加载用户可写目录中的 DLL 或执行异常参数
重点确认:
- Medium Integrity 的异常进程启动系统自动提升组件;
- 自动提升组件随后加载用户可写目录中的 EXE、DLL 或配置;
- 提升前后出现令牌、完整性级别和父子进程关系变化;
- 提权成功后立即写入系统目录、创建服务或修改安全策略。
UAC 绕过通常是从 Medium 到 High,不等于直接获得 SYSTEM。
边界
- 标准用户不能因为启动了自动提升组件就凭空获得管理员身份;
- 启动自动提升组件不等于绕过成功,必须确认新进程的令牌和完整性级别;
- UAC 绕过成功也不代表可以访问 PPL、Credential Guard 或所有安全产品组件;
- 用户主动点击“以管理员身份运行”属于正常 UAC 提升,不应与静默绕过混为一谈。
借助已有高权限进程
木马不一定自己直接拿到完整管理员令牌,也可能利用已有的高权限服务、安装器、计划任务或代理组件执行写入。这里的“借助”通常不是进程注入,而是通过 IPC 调用一个本来就以 High 或 SYSTEM 运行的组件。
高权限代理不等于进程注入
两者解决的问题不同:
| 方式 | 核心问题 | 代码或动作在哪里发生 | 典型证据 |
|---|---|---|---|
| 高权限代理 | 让高权限组件代替低权限木马完成操作 | 高权限服务、安装器或任务进程 | IPC 请求、服务操作、代理进程写文件 |
| 进程注入 | 让代码进入并控制另一个进程 | 被注入目标进程的地址空间 | VirtualAllocEx、WriteProcessMemory、APC、远程线程 |
| 令牌操纵 | 获得或模拟另一种身份 | 当前线程或新建进程 | OpenProcessToken、DuplicateTokenEx、身份模拟 |
高权限代理本身不需要向目标进程写内存。例如,低权限木马向高权限更新服务发送请求,由更新服务创建文件,整个过程没有注入。三者也可以串联:
Medium 木马
→ 调用高权限服务完成写入或启动
→ 获得 High / SYSTEM 进程
→ 启用 SeDebugPrivilege
→ 向其他进程注入或复制令牌
看到高权限服务创建了文件,不能直接下结论说发生了注入;需要看到跨进程内存、线程或上下文操作,才能确认注入链路。
高权限代理执行的成立条件
低权限木马能否借助已有高权限进程,取决于该组件是否存在可利用的信任边界:
Medium 木马
→ 命名管道 / RPC / COM / 本地 Socket / 服务接口
→ 接口允许低权限调用,或认证 / 参数校验不足
→ 高权限组件代替木马写文件、启动进程或修改配置
关键不是木马“拿到了 SYSTEM 令牌”,而是高权限服务把危险能力暴露给了不应拥有它的调用者。需要检查:
- 低权限调用者是否能连接 IPC 接口;
- 服务是否校验调用者 SID、会话、签名或请求来源;
- 服务是否限制目标路径、参数和插件来源;
- 服务配置、二进制、依赖 DLL 或任务动作是否被低权限用户修改;
- 实际完成写入或创建进程的是哪个高权限主体。
错误服务配置
如果普通用户可以修改服务的可执行文件、启动参数、工作目录或依赖文件,就可能出现:
Medium 木马
→ 与高权限服务 / 安装器交互
→ 高权限组件执行指定动作
→ 写入 Program Files、System32 或服务目录
这不是普通用户“调用了 SYSTEM 权限”,而是高权限服务在启动时信任了低权限用户可以修改的对象。检测应关注服务配置 ACL、二进制路径、依赖 DLL、服务创建者和最近修改者。
调查时必须区分:
发起请求的木马进程权限
≠
实际写入文件或创建服务的代理进程权限
安装器、更新器、计划任务和 COM 代理
安装器和更新器经常需要以管理员权限替换 C:\Program Files 下的文件、注册服务或更新驱动。若它们的 IPC、更新包校验或路径检查不足,低权限木马可能诱导它们处理攻击者控制的安装包、配置或更新内容:
Medium 木马
→ 向高权限更新 / 安装组件提交输入
→ 组件未充分校验来源、签名或路径
→ 组件以 High / SYSTEM 写入软件目录或执行安装动作
如果已有高权限计划任务的动作、脚本或依赖文件可被普通用户修改,木马也可以等待任务触发或主动请求运行。COM 组件则可能在更高权限上下文中激活,但前提是注册信息、激活权限或调用接口存在错误配置。
这些路径的共同点是:
木马不直接获得目标令牌
而是让一个本来就拥有目标令牌的组件替它完成动作
管理员为什么还要启用 SeDebugPrivilege
管理员权限和 SeDebugPrivilege 解决的不是同一个问题:
管理员 / High Integrity
→ 更容易修改系统文件、服务、计划任务和系统配置
SeDebugPrivilege
→ 更容易获取其他进程的调试、内存、线程和句柄访问能力
木马已经是管理员,并不代表它能随意打开所有进程。目标进程对象仍有自己的安全描述符、访问掩码和保护状态;普通管理员可能只能获得有限查询权限,无法申请 PROCESS_VM_READ、PROCESS_VM_WRITE、PROCESS_VM_OPERATION 或线程控制权限。
启用 SeDebugPrivilege 的目的通常是扩大进程访问范围,为以下操作创造条件:
- 读取高权限进程内存;
- 写入目标进程内存并执行注入;
- 打开线程、暂停线程或修改线程上下文;
- 打开目标进程令牌并尝试复制或模拟;
- 访问普通 DACL 不允许当前管理员直接访问的进程对象。
它不是为了把管理员“升级成更高的账户”,而是为了改变管理员对其他进程对象的访问能力。
SeDebugPrivilege 从哪里来
SeDebugPrivilege 不是木马凭空申请的权限。它必须先由“调试程序”用户权利或相关安全策略授予账户,之后才可能被该账户的访问令牌携带。常见情况是:
- 管理员完整令牌可能携带该特权,但过滤后的 Medium 令牌不一定携带或启用;
- SYSTEM 和部分系统服务令牌通常更可能携带该特权;
- 标准用户令牌通常没有该特权;
- 企业安全策略可以收紧或重新分配该用户权利。
安全策略先授予特权
→ 令牌携带特权但可能默认禁用
→ 木马查询并尝试启用
→ 再申请高权限进程句柄
查询、启用和使用是三件事
典型流程是:
OpenProcessToken
→ LookupPrivilegeValueW(查询特权对应的 LUID)
→ AdjustTokenPrivileges(尝试启用已有特权)
→ NtOpenProcess(申请目标进程句柄)
其中:
LookupPrivilegeValueW只把特权名称转换为 LUID,不会授予权限;AdjustTokenPrivileges只能调整当前令牌中已经存在的特权,不能凭空增加新特权;- 调整后需要检查返回状态和
GetLastError,可能出现ERROR_NOT_ALL_ASSIGNED; - 即使启用成功,PPL、Credential Guard、DACL 和安全产品自保护仍可能拒绝访问。
管理员启用该特权后的典型后续链路是:
High 管理员
→ LookupPrivilegeValueW
→ AdjustTokenPrivileges
→ NtOpenProcess(高权限目标)
→ 内存读写、线程控制或令牌复制
因此,SeDebugPrivilege 不是提权终点,而是管理员进入“进程访问、注入和令牌操纵”阶段的准备条件。
进程注入需要什么权限
进程注入不是由某一个 API 单独决定的,而是取决于调用者能否同时获得:
目标进程句柄
+ 目标进程内存操作权限
+ 目标线程控制权限
+ 足够的完整性级别和令牌能力
SeDebugPrivilege 可以帮助进程更容易打开其他进程,但它不是所有注入场景的必要条件。只要目标进程的 DACL 已经允许当前用户、目标是自身创建的子进程,或者调用者已经持有可继承的高权限句柄,注入可能在没有显式启用 SeDebugPrivilege 的情况下完成。
目标进程句柄权限
常见的跨进程内存注入通常需要目标进程句柄包含以下访问权:
| 访问权限 | 用途 | 常见相关操作 |
|---|---|---|
PROCESS_VM_OPERATION | 在目标进程中分配、释放或修改内存区域 | VirtualAllocEx、VirtualFreeEx、内存保护修改 |
PROCESS_VM_WRITE | 向目标进程地址空间写入数据 | WriteProcessMemory、NtWriteVirtualMemory |
PROCESS_VM_READ | 读取目标进程内存和 PE、模块信息 | ReadProcessMemory、NtReadVirtualMemory |
PROCESS_CREATE_THREAD | 在目标进程中创建线程 | CreateRemoteThread、部分 NtCreateThreadEx 场景 |
PROCESS_QUERY_INFORMATION | 查询进程信息、令牌或映像状态 | OpenProcessToken、进程信息查询 |
PROCESS_QUERY_LIMITED_INFORMATION | 查询部分基础信息 | 进程路径、基础状态查询 |
PROCESS_DUP_HANDLE | 复制目标进程中的句柄 | DuplicateHandle、句柄窃取类操作 |
不一定每种注入都需要全部权限。例如只写入已有内存区域可能不需要 PROCESS_VM_OPERATION;只进行 APC 投递通常重点需要线程权限;而传统远程线程注入通常需要同时申请内存、写入内存和创建线程的权限。
目标线程句柄权限
如果注入依赖已有线程,还需要打开目标线程并申请相应访问权:
| 线程权限 | 用途 | 常见场景 |
|---|---|---|
THREAD_SET_CONTEXT | 修改线程上下文或投递 APC | QueueUserAPC、SetThreadContext |
THREAD_GET_CONTEXT | 读取线程寄存器和执行上下文 | 线程劫持、确定入口状态 |
THREAD_SUSPEND_RESUME | 暂停和恢复线程 | 线程劫持、进程空洞化 |
THREAD_QUERY_INFORMATION | 查询线程状态和归属 | 线程枚举、注入前确认 |
THREAD_TERMINATE | 终止目标线程 | 破坏性操作,不是普通注入的必要权限 |
线程权限与进程权限是两套访问控制。成功打开目标进程,不代表一定能打开其中的线程;反过来也一样。
不同注入方式的权限需求
| 注入方式 | 主要需要的权限 | 典型行为链 | 是否必需 SeDebugPrivilege |
|---|---|---|---|
| 普通写内存 | PROCESS_VM_WRITE,通常还需要 PROCESS_VM_OPERATION | OpenProcess → VirtualAllocEx → WriteProcessMemory | 不一定,取决于目标 DACL 和句柄来源 |
| 远程线程注入 | 进程内存权限 + PROCESS_CREATE_THREAD | 写入载荷后 CreateRemoteThread / NtCreateThreadEx | 不一定,但高权限目标通常更容易需要它 |
| APC 注入 | 进程内存权限 + 目标线程 THREAD_SET_CONTEXT | 写入载荷后 QueueUserAPC | 不一定,目标线程和句柄权限是关键 |
| 线程劫持 | 进程内存权限 + THREAD_SUSPEND_RESUME、THREAD_GET_CONTEXT、THREAD_SET_CONTEXT | 暂停线程 → 修改上下文 → 恢复线程 | 不一定,但系统进程目标通常需要更高访问能力 |
| 进程空洞化 | 创建挂起进程后的进程内存权限 + 主线程上下文和恢复权限 | CREATE_SUSPENDED → 写入 PE → SetThreadContext → ResumeThread | 自身创建的目标通常不必需;对外部高权限目标则可能需要 |
| 节区映射注入 | 节区创建 / 映射权限 + 目标进程映射权限 | NtCreateSection → NtMapViewOfSection → 执行控制流 | 不一定,取决于目标和句柄权限 |
这里的“需要”表示通常要具备相应的对象访问能力,而不是所有实现都必须申请完全相同的访问掩码。实际 API 可能根据 Windows 版本、调用方式和目标保护状态申请不同权限。
为什么同一用户的进程也可能注入成功
进程注入不一定意味着攻击者已经获得管理员权限。以下场景中,普通用户进程也可能对另一个普通用户进程进行有限注入:
- 目标进程属于同一用户,且目标进程 DACL 允许相应访问;
- 目标是当前进程创建的子进程;
- 创建目标进程时保留了可操作的进程或线程句柄;
- 目标进程没有更高完整性级别或 PPL 保护;
- 注入只针对用户自己的进程和用户可访问的内存。
因此,看到 WriteProcessMemory 或 QueueUserAPC,不能直接推出已经发生了提权。需要同时查看调用者和目标进程的用户、完整性级别、访问掩码、句柄来源以及后续执行结果。
木马如何获得注入所需权限
木马通常不是直接“申请一个注入权限”,而是先获得能够打开目标进程和线程的令牌、句柄或代理执行条件,再进行内存写入和控制流转移。常见路径如下:
| 权限来源 | 木马获得的实际条件 | 后续可能进行的注入 | 是否一定需要 SeDebugPrivilege |
|---|---|---|---|
| 同一用户进程 | 目标 DACL 允许访问,或目标是自己的子进程 | 普通写内存、远程线程、APC | 不一定 |
| 自己创建目标进程 | 创建时得到目标进程和主线程句柄 | 进程空洞化、挂起进程注入 | 通常不需要 |
| UAC 正常提升 | 用户确认后获得新的 High Integrity 进程 | 注入 High 或部分 SYSTEM 进程 | 不一定,但访问范围更大 |
| UAC 绕过 | 自动提升组件创建 High Integrity 进程 | 由新的高权限进程执行注入 | 不一定 |
| 高权限代理 | 高权限服务或安装器代替木马完成敏感操作 | 代理进程注入,或代理先创建高权限宿主 | 木马自身不一定需要 |
SeDebugPrivilege | 当前令牌携带并成功启用调试特权 | 更容易打开其他用户或高权限进程 | 该路径本身就是启用它 |
| 令牌复制 / 模拟 | 获得高权限线程令牌或创建高权限进程 | 以复制出的身份进行注入 | 通常需要先具备目标令牌访问能力 |
| 内核驱动 / BYOVD | 获得内核辅助能力,绕过部分用户态边界 | 影响 PPL 或安全产品相关进程 | 用户态特权不再是唯一条件 |
路径一:同一用户或自己创建的子进程
这是权限要求最低的一类。木马可以先创建一个普通用户子进程,并保留目标进程和主线程句柄:
Medium 木马
→ CreateProcess(CREATE_SUSPENDED)
→ 获得子进程句柄和主线程句柄
→ 写入内存或替换映像
→ 恢复线程执行
因为目标由自己创建,木马通常可以在创建时获得所需的进程和线程访问权限,所以进程空洞化不一定需要管理员权限或 SeDebugPrivilege。这种注入只能解决“控制自己的低权限子进程”,不能因此访问 lsass.exe 或其他 SYSTEM 进程。
同一用户的已运行进程也可能因为 DACL 允许而被打开,但访问权限仍然要逐项申请和检查,不能认为同用户就一定拥有完全访问权。
路径二:先通过 UAC 获得 High Integrity
如果目标是 High、SYSTEM 或其他高权限进程,木马可能先让自己或新的子进程进入 High Integrity:
Medium 木马
→ 用户确认 UAC,或利用 UAC 绕过
→ 新的 High Integrity 木马 / 宿主进程
→ OpenProcess / NtOpenProcess(高权限目标)
→ 申请 VM 和线程访问权限
→ 执行注入
UAC 只负责把进程从 Medium 提升到 High,不会自动授予 SeDebugPrivilege,也不会自动允许访问 PPL 进程。注入是否成功还要取决于目标进程的 DACL、保护级别和所申请的访问掩码。
路径三:通过高权限代理完成注入
这条路径中,低权限木马可能根本没有注入所需的进程句柄。它通过 IPC 让一个已经以 High 或 SYSTEM 运行的服务、安装器或更新器完成操作:
Medium 木马
→ 连接高权限服务的 IPC 接口
→ 提交目标 PID、载荷或加载请求
→ 高权限服务打开目标进程并执行注入
这里获得的不是“木马自己的注入权限”,而是高权限代理的代执行能力。检测时应分别记录:
请求者:低权限木马
执行者:高权限服务
目标:被注入进程
如果代理只负责写文件或创建服务,则属于高权限代理执行;只有当代理出现目标进程内存写入、线程控制或远程执行事件时,才能确认代理执行了注入。
路径四:管理员令牌启用 SeDebugPrivilege
管理员进入 High 后,可能仍然只能查询某些进程,无法申请完整的内存和线程访问权限。木马会检查当前令牌是否携带 SeDebugPrivilege,再尝试启用:
High 管理员进程
→ OpenProcessToken
→ LookupPrivilegeValueW
→ AdjustTokenPrivileges
→ NtOpenProcess(申请 VM / Thread 权限)
→ 内存写入和控制流转移
SeDebugPrivilege 的作用主要体现在“打开目标进程”这一步。它可能使进程访问检查不再完全受目标进程 DACL 限制,从而更容易获得进程句柄;但它不等于自动获得目标进程的令牌,也不能保证绕过 PPL、Credential Guard 或安全产品自保护。
因此要区分:
管理员权限
→ 有能力修改很多系统对象
SeDebugPrivilege
→ 更容易获得其他进程对象的调试和内存访问权限
路径五:通过令牌复制或身份模拟
木马也可能先访问一个高权限进程的令牌,再用复制出的令牌创建新进程或模拟线程身份:
具备目标进程访问能力
→ OpenProcessToken
→ DuplicateTokenEx
→ CreateProcessAsUserW / CreateProcessWithTokenW
→ 新进程携带高权限令牌
→ 启用 SeDebugPrivilege 或直接执行注入
这条路径的关键前提是:木马首先要能打开目标进程并读取其令牌。DuplicateTokenEx 不是凭空制造 SYSTEM 身份,也不是注入权限本身;它只是把已有令牌复制成可以模拟或用于创建进程的令牌对象。
路径六:已有句柄、继承句柄和句柄复制
木马不一定每次都调用 OpenProcess 重新申请权限,还可能使用已有句柄:
- 创建子进程时继承具有
PROCESS_VM_WRITE或线程控制权限的句柄; - 从高权限父进程或代理进程获取重复句柄;
- 利用
DuplicateHandle或NtDuplicateObject复制已有句柄; - 通过服务、任务或注入宿主间接传递目标进程句柄。
因此,检测时看到注入行为但没有对应的 NtOpenProcess,不能立即认为日志缺失或注入不存在,应继续检查句柄继承、句柄复制和父子进程关系。
路径七:内核辅助和 PPL 目标
如果目标是 PPL 或安全产品受保护进程,High、SYSTEM 和 SeDebugPrivilege 仍可能不足。攻击者可能进一步使用合法但有漏洞的驱动、错误配置的受信任驱动或内核漏洞获得内核辅助:
High / SYSTEM
→ 加载或滥用驱动
→ 内核辅助访问受保护进程
→ 破坏或绕过部分 PPL / 安全产品边界
→ 再执行进程操作或安全产品致盲
这已经不是普通用户态注入权限问题,而是代码完整性、驱动签名、HVCI、易受攻击驱动阻止策略和内核安全边界问题。
综合判断链
一个较完整的“获得注入能力”链路可能是:
用户点击木马
→ Medium Integrity
→ UAC / UAC 绕过 / 高权限代理
→ High 或 SYSTEM
→ 令牌中存在并启用 SeDebugPrivilege
→ 获得目标进程和线程句柄
→ 申请 VM 写入、线程控制等访问权限
→ 写入内存并触发执行
但也可能是更短的链路:
普通用户
→ 自己创建挂起子进程
→ 直接进行进程空洞化
或者:
低权限木马
→ 调用高权限代理
→ 高权限代理完成注入
因此,分析时要回答两个不同问题:
- 注入者为什么能获得目标进程 / 线程句柄?
- 获得句柄后是否真的完成了写入和执行?
只回答第二个问题,会把同用户注入、句柄继承、代理注入和真正的权限提升混在一起。
高完整性和 PPL 的影响
当目标进程处于更高完整性级别时,低完整性或普通用户进程通常不能向其写入或控制线程:
Medium 调用者
→ 尝试写入 High / SYSTEM 目标
→ 访问检查失败,或只能获得有限查询权限
管理员进入 High Integrity 后,能够访问的目标范围扩大;启用 SeDebugPrivilege 后,申请高权限进程句柄的成功率可能进一步提高。但 PPL、Credential Guard、安全产品自保护和内核策略仍可能拒绝访问。
尤其需要区分:
SYSTEM 进程
≠
普通 SYSTEM 进程一定可被注入
如果目标是 PPL 进程,即使调用者是管理员或 SYSTEM,也可能无法获得 PROCESS_VM_WRITE、PROCESS_CREATE_THREAD 或线程控制权限。此时应关注访问失败、保护级别、签名要求和是否存在内核辅助,而不是简单把失败归因于权限不足。
注入权限的检测思路
检测注入时建议把权限变化和对象访问关联起来:
Medium → High / SYSTEM
→ LookupPrivilegeValueW / AdjustTokenPrivileges
→ NtOpenProcess(申请 VM / Thread 权限)
→ VirtualAllocEx / NtWriteVirtualMemory
→ QueueUserAPC / NtCreateThreadEx / NtSetContextThread
同时记录:
- 目标进程和线程的用户、完整性级别及保护状态;
- 请求的访问掩码和调用返回结果;
- 是否使用了已有句柄、继承句柄或复制句柄;
- 写入区域是否属于合法模块、私有内存或可执行内存;
- 写入后是否真的发生线程执行、模块加载或后续异常行为。
最终应区分三种结论:
申请了注入所需权限
≠
成功写入目标进程
≠
成功执行了恶意代码
从管理员到 SYSTEM
获得 High Integrity 后,木马可能通过服务、计划任务或令牌操纵进入 SYSTEM:
High Integrity 管理员
→ 创建 / 修改服务
→ 启动服务
→ 服务以 SYSTEM 运行
或者:
打开高权限进程
→ OpenProcessToken
→ DuplicateTokenEx
→ ImpersonateLoggedOnUser / SetThreadToken
→ CreateProcessAsUserW / CreateProcessWithTokenW
如果链路中出现 SeDebugPrivilege、高权限进程访问、令牌复制和高权限子进程创建,应结合目标进程和后续行为判断是否真的进入 SYSTEM。
从 SYSTEM 到 TrustedInstaller
如果目标是替换由 TrustedInstaller 所有的系统组件,木马可能继续寻找 TrustedInstaller 令牌或服务上下文:
SYSTEM
→ 获取 / 模拟 TrustedInstaller 令牌
→ 修改受保护文件或组件
这一步不是所有木马都会执行,且“修改失败”并不代表此前没有获得 SYSTEM。
从用户态到内核态
部分攻击会继续加载驱动或利用 BYOVD:
High / SYSTEM
→ 注册并加载驱动
→ 与驱动设备对象通信
→ 进行内核级进程、内存或安全产品操作
重点检测驱动文件来源、签名、哈希、版本、加载者、服务注册和加载后的安全产品状态变化。
权限与目录关系
| 目录 | 普通用户通常能做什么 | 高权限进程常见用途 | 木马分析重点 |
|---|---|---|---|
C:\Users\<用户名>\AppData\Local\Temp | 读写、执行 | 暂存载荷、解压文件、临时配置 | 常见初始落地点,需看创建者和后续行为 |
C:\Users\<用户名>\AppData\Local | 读写、执行 | 用户级软件和配置 | 可能形成用户级持久化 |
C:\Users\<用户名>\AppData\Roaming | 读写、执行 | 用户配置和漫游数据 | 常用于配置、脚本和用户级启动 |
C:\Users\<用户名>\Downloads | 通常可读写 | 初始投递和解压目录 | 关注网络来源和用户点击 |
C:\Program Files | 通常读取、执行,不能直接创建或修改 | 安装软件、服务和插件 | 木马落地通常意味着提权或高权限代理 |
C:\Windows\System32 | 通常读取、执行,不能直接修改 | 系统组件、服务和驱动 | 关注签名、文件所有者和创建者进程 |
C:\ProgramData | 取决于具体子目录 ACL | 机器级配置、共享数据和服务文件 | 不能仅凭路径判断可信 |
C:\Windows\Temp | 权限取决于 ACL,通常比用户 Temp 更敏感 | 系统任务和安装过程临时文件 | 关注服务、安装器和 SYSTEM 进程写入 |
检测权限变化
进程级信息
应同时记录:
- 用户名和用户 SID;
- 进程完整性级别;
- 是否属于 Administrators 组;
- 令牌类型、模拟令牌和启用特权;
- 父进程、命令行和创建者;
- 当前 Session ID;
- 目标对象的访问权限和返回结果。
高价值时间线
用户目录 / 下载目录启动
→ Medium Integrity
→ UAC、服务、任务或令牌操作
→ High / SYSTEM 子进程
→ 写入 Program Files / System32
→ 持久化、注入、驱动加载或 C2
研判边界
- 文件位于
C:\Program Files,不代表进程是管理员; - 进程属于 Administrators 组,不代表它已经提升;
AdjustTokenPrivileges不等于特权一定启用成功;DuplicateTokenEx不等于已经获得 SYSTEM;SYSTEM不等于内核权限;NtOpenProcess不等于成功访问目标进程;- 高权限进程创建文件,不一定代表最初发起者本身就是高权限。
小结
Windows 权限可以用下面这条简化链路理解:
普通用户 / Medium
→ UAC 或其他方式
→ 管理员 / High
→ 服务、任务或令牌操纵
→ SYSTEM
→ TrustedInstaller(特定受保护组件)
→ 驱动或漏洞路径
→ Kernel
木马的初始执行权限通常来自启动它的用户。用户点击并不自动赋予管理员权限;木马能否写入系统目录、创建服务或访问高权限进程,取决于后续是否完成 UAC 提升、借助高权限代理、令牌操纵、服务任务路径或内核级操作。