电脑疯子技术论坛|电脑极客社区

微信扫一扫 分享朋友圈

已有 2437 人浏览分享

研究|Windows访问令牌原理与实践

[复制链接]
2437 0
0x01 基础

0x0101 登录流程:

先来了解一下在本地计算机上进行交互式登录的流程

从按下Ctrl+Alt+Del时开始启动登录一系列的流程 之后winlogon程序接收到SAS并调用GINA弹出一个对话框要求用户
输入账号和密码。GINA获取到账号和密码后 将其传输给LSA,LSA再调用特定的身份验证程序包去验证账号密码是否有
效若有效,则创建一个登录会话 并分配一个与之相关联的访问令牌。

640.png

QQ截图20210609103953.png


0x0102 访问令牌:

Windows Access Token(访问令牌是一个描述进程或线程安全上下文的一个对象令牌所包含的信息是与该user账户相关
的进程或线程的身份和权限信息。每一个用户登录计算机后 系统通过将用户输入的账号密码与系统存储的账号密码进行
比对若比对通过 就会生成一个Access Token 访问令牌。之后这个用户执行的每个进程都会拥有该访问令牌的一个拷贝
因此 A用户创建一个进程而该进程没有B用户的权限。

访问令牌的产生过程:

使用凭据 用户密码)进行认证->登录session创建->Windows返回用户sid和用户组sid->LSA(Local Security
Authority创建一个token 主令牌primary token ->根据该token创建进程 线程(如果CreateProcess时指定了
token LSA会用该token,否则就继承父进程的token。

注:explorer.exe是用户的默认shell.因而一般情况下 用户双击运行一个程序 explorer.exe会是这个运行进程
的父进程 类似于Linux中的shell 因此一般都会拷贝explorer.exe的Access Token。
如下图:

640 (1).png

0x0103 访问令牌的用途:

当前系统的某个进程或线程能访问到什么样的系统资源 完全取决于当前进程是拿着谁的令牌。
如:有些需要用管理员令牌的资源 拿着普通用户的令牌就访问不到了。

当进程或线程需要访问某个具有安全属性的对象时:
1.   系统会在对象的ACE中查找是否有进程或线程中token代表的账户。
2.   当有该账户时 再根据对象中的ACL决定该账户具有操作该对象的哪些权限(如:读、写、执行等等)。
右键文件属性 点击安全 可查看ACE和ACL,如下图:

QQ截图20210609104633.png

0x0104 访问令牌的种类:

主令牌:
每个进程都有一个主令牌来描述与该进程相关的用户账号的安全上下文
服务进程在自己的账号下运行,使用自己的主令牌。但当服务接受一个用户的访问请求时它创建一个线程来完成这
项工作并将用户的访问令牌与工作线程相关联。用户的访问令牌是一个模拟令牌 用来标识用户 用户组和特权
当线程代表用户请求访问资源 如文件 打印机 数据库等时 在访问检查过程中使用该信息。
在模拟结束后 线程重新使用主令牌并返回到服务自己的安全上下文中操作。
服务器只能在发起模拟请求的线程内模拟用户。

模拟令牌(Impersonation Token):
模拟令牌时服务进程中的一个线程用来临时接受一个不同
的安全上下文如服务的一个客户的安全上下文的令牌。
一个正在进行客户端模拟的线程具有两个访问令牌:
主访问令牌: 描述服务器的安全上下文。
模拟访问令牌:描述被模拟的客户的安全上下文。

主访问令牌vs模拟访问令牌:
主访问令牌:为进程令牌 只能附加到进程
模拟访问令牌:线程令牌 只能附加到线程

注:
主令牌和模拟令牌会在系统重启或者关机后全部清除 不然将会一直存留在系统内存中。
默认情况下 当前用户只能看到当前用户自己和比自己权限低的所有访问令牌。若想看到系统中所有用户的访问
令牌就需要将自己当前用户的权限提到一个特权用户的身份上,如:Windows的system或者administrator.

普通用户查看访问令牌:

640 (2).png

管理员查看访问令牌:

69.png

0x0105 客户端模拟 Client Impersonation :

模拟是线程使用与拥有该线程的进程不同的安全信息去执行的能力。通常来说 服务器应用程序中的线程模拟了客户端
这允许服务器线程代表该客户端去执行操作 以访问服务器上的对象或验证客户端是否有访问自己对象的能力。

模拟的四个级别:

为了防止滥用模拟机制 Windows不允许服务器在没有得到用户同意的情况下执行模拟。用户线程在连接到服务
器的时候可以指定一个安全服务质量 以此来限制服务器进程可以执行的模拟级别。

1.  Anonymous:服务器无法模拟或识别客户端
2.  Identification:服务器可以获取客户端的身份SID和特权,但不能模拟客户端
3.  Impersonation:默认级别 服务器可以在本地系统上模拟客户端的安全上下文
4.  Delegation:服务器可以在远程系统上模拟客户端的安全上下文。
因为令牌中存储了相关的身份验证凭据

因为Anonymous及Identification等级的令牌没有假设其他安全上下文的能力因而
在Windows中通常关注以下两种等级的令牌:

模拟令牌:Impersonation Token:通常非交互式登录会创建Impersonation token例如:net use,wmi,winrmftp等等。
委派令牌:Delegation Token:通常交互式登录会创建Delegationtoken 例如:传统意义上的登入控制台 本地  使用终端
服务远程登入 远程 或者使用类似于Citrix的解决方案进行远程访问。

注:在某些情况下 非交互式登录也可以产生Delegation Token 通常发生在被信任的计算机或用户帐户进行委派时。
例如:使用EFS加密文件的远程文件服务器。为了加解密文件 EFS需要获得用户的身份验证凭据。因此 一个通过映
射的网络共享进行的非交互式登录需要获得委派令牌才能够正常工作。因此在这种情况下,通常会在域控上对远程文
件服务器进行委派。

65.png

域环境下 EFS第一次如何获得用户的凭据?
式一:直接在文件服务器上使用域用户账号登录一次并且随便加密一个文件这样就可以生成域用户的证书和密钥。
式二:在域用户拥有用户漫游配置文件 Roaming User Profiles 的情况下直接将RUP下载到文件服务器上对应的位置
注:
1.  两种令牌只有系统重启后 才会被清除 否则将会一直驻留在内存中;
2.  委派令牌在用户注销后 该令牌会变为模拟令牌并且依旧有效。
模拟令牌示例

64.png

场景:

域环境下
一台加入域的电脑A作为Client
一台域控作为Server
此处用到incognito.exe,logonsessions64.exe

描述:

net use 建立连接:
1.用户通过交互式登录(这里就是平常的本地登录)电脑A 此时client中会有缓存的用户凭据。
2.刚开始,server端只有一个模拟令牌
3.client使用net use \\<dc-ip>\ipc$  /user:jerrybird命令建立IPC连接。

此时 client会首先将之前缓存的凭据发送dc上进行验证 因为此时密码不对 此时会报错
也就是下面第二张图中的密码或用户在….无效。
之后 client会提示输入新密码后 将获得的新凭据发送到DC上进行身份验证。
身份验证通过之后 在server会创建一个网络登录会话和一个相关联的模拟令牌。
smb server会使用client的模拟令牌创建一个线程 用来代表client进行操作。
(身份验证的过程使用NTLM或者Kerberos协议)
建立连接后server端多出一个模拟令牌

Step1. 如下 刚开始只有一个模拟令牌:

63.png

Step2. client使用net use命令建立连接:

62.png

Step3. 连接建立成功后  会多出一个模拟令牌,正是client输入的用户:

61.png

访问共享文件:

1. 用户通过交互式登录(这里就是平常的本地登录)电脑A 此时client中会有缓存的用户凭据。
2. 刚开始 server端只有一个模拟令牌
3. 在client上使用资源管理器第一次访问server的共享文件。
此时client提示输入网络密码后,将获得的新凭据发送到DC上进行身份验证。
4. 身份验证通过之后,在server会创建一个网络登录会话和一个相关联的模拟令牌。
5. smb server会使用client的模拟令牌创建一个线程 用来代表client进行操作。
身份验证的过程使用NTLM或者Kerberos协议,此处输入的是域用户 因而最后一张图显示认证协议是Kerberos
6. 建立连接后,server端多出一个模拟令牌

Step1. 如下 刚开始只有一个模拟令牌:

60.png

Step2. 访问共享文件,client上提示输入网络密码

59.png

Step3.输入凭据身份验证成功后 server上会多出一个模拟令牌 正是client输入的用户

58.png

注:
经过实验,
单纯的局域网内(非同一工作组),server上没有产生新的模拟令牌;
域环境下产生模拟令牌;
同一工作组下未测试.

0x0106 UAC与关联令牌:

UAC是vista版本引入的一种安全机制 和Linux系统的sudo命令一样是保护系统安全的一道重要屏障 当用户登录Windows
时操作系统会为用户生成一对初始令牌 分别是代表着用户所拥有的全部权限的完整版本令牌即管理员权限令牌以及被限制
管理员权限后的普通令牌 二者互为关联令牌;此后 代表用户的进程所使用的令牌都是由普通令牌继承而来,用来进行常规
的非敏感的操作;当用户需要进行一些需要管理员权限的操作时 比如安装软件、修改重要的系统设置时 都会通过弹出提权
对话框的形式来提示用户面临的风险 征求用户的同意 一旦用户同意,将会切换到当前普通令牌关联的管理员权限令牌 来进
行敏感操作。通过这种与用户交互的方式 避免一些恶意程序在后台悄悄执行敏感操作。

57.png

并不是所有的用户都有关联令牌 一些开机就保持在高权限的用户就只有一个令牌 例如:SYSTEM

56.png

0x02 实践

实践出真知,动手写一份实验代码 代码放在GitHub:https://github.com/chro
blert/CodeLab仓库的AccessToken目录下。

目前有如下功能:
列出所有进程中的主令牌
列出某个进程的主令牌及其线程中的模拟令牌
列出所有具有模拟令牌的线程
列出当前计算机上的登录会话
列出当前进程主令牌信息
待优化:
使用微软未公开函数ZwQueryInformationThread查看某些线程的时候
GetLastError()会返回 Access Denied
将登录会话 访问令牌 线程 进程进行管理
用法:

22.png

0x0201 枚举所有的进程及其主令牌

21.png

0x0202 枚举所有具有模拟令牌的线程

20.png

0x0203 枚举所有的登录会话

19.png

您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

关注

0

粉丝

9021

主题
精彩推荐
热门资讯
网友晒图
图文推荐

Powered by Pcgho! X3.4

© 2008-2022 Pcgho Inc.