利用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),所有特权如下:特权常量
SID
SID是安全标识符,是标识用户、组和计算机帐户的唯一的号码。在第一次创建该帐户时,将给网络上的每一个帐户发布一个唯一的 SID。它用来跟踪每个账户,而且永远不会更改,即使我们更改了管理员的名字它也不会变。
SID的构成如下:
1 |
|
赋予当前进程操作令牌DEBUG权限
很多操作一般都需要赋予当前进程操作令牌权限:SE_DEBUG_NAME
,然后再进行令牌操作,比如清除令牌、伪造令牌,在加载驱动的时候如果要连接驱动是需要Debug权限的,否则无法进行createFile生成驱动句柄。
比如很常用的猕猴桃的privilege::debug
,就是为了获取SE_DEBUG_NAME
权限。
目标: 获取一个启用SE_DEBUG_NAME
的CMD。
步骤:
- 获取当前进程令牌
- 查找
SeDebugPrivilege
的 LUID - 启用
SE_PRIVILEGE_ENABLED
属性
思路:我们可以给当前的python进程赋予SE_DEBUG_NAME
权限,然后起一个CMD的子进程,这样CMD就会继承python进程的权限了。
下面的代码需要以管理员身份运行python
1 |
|
我们可以通过whoami /priv | findstr "SeDebugPrivilege"
命令来查询运行该命令的进程的令牌。
可以看到直接以管理员开启cmd,SeDebugPrivilege
是禁用的。
运行上述脚本后,成功开启了SeDebugPrivilege
这个特权。
获取一个SYSTEM权限的CMD
直接用微软官方提供的工具,PSTOOLS:https://learn.microsoft.com/zh-cn/sysinternals/downloads/pstools
以管理员身份运行一个CMD,然后输入一下命令:
1 |
|
利用Token提权到Trustedinstaller
刚刚我们获得了一个system权限的CMD窗口,这样我们就能任意操作我们的系统了吗?
例如在C:\Windows\servicing
文件夹内,哪怕是system权限,我们甚至不能写一个文件进去。
又例如在C:\Windows\System32
文件夹内,要删除这个图片文件,提示说 “你需要TrustedInstaller提供的权限才能对此文件进行更改”。
在属性里,也只有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 |
|
然后弹出一个新的cmd窗口,使用whoami /all
可以看到我们已经属于TrustedInstaller组了。
测试echo 1>1.txt
可以看到刚刚不能写的目录,现在可以写了。这个文件除了TrustedInstaller组以外的用户都无权修改。
方法二:使用MSF中的incognito
这边先用MSF拿一个本机的shell。
先生成一个木马:
1 |
|
然后在本机以管理员身份运行木马。
成功链接。
在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
ordrop_token
执行getsystem
获得system权限:
或者执行impersonate_token "NT AUTHORITY\\SYSTEM"
将权限切换至system。
在获取system权限后,根据相同的思路,窃取TrustedInstaller进程的token,然后提权。
首先使用ps命令获取TrustedInstaller进程的PID。
然后窃取token:steal_token 16312
可以看到成功提到TrustedInstaller了。
其实方法还有很多,但核心思路就是令牌窃取,利用别的进程的token创建子进程,这样子进程就有了对应进程的权限。