Windows 安全相关知识下半节,这一章主要讲一下除了SID,DACL这类,还有哪些安全对象也在 Windows 安全中发挥着重要的作用
Windows 安全相关(下)
这一段会尝试介绍一下 Windows 整个操作系统中,参与了安全保护的各个部件。
Access Token 访问令牌
当用户登录操作系统的时候,操作系统会要求用户输入密码,输入的密码会与Windows的安全数据库(security database)的信息进行比较。当密码得到验证(authenticated)之后,系统将会产生一个Access Token,代表了当前登录用户的权限。
每一个 Access Token 都是描述了一个进程或者线程的安全上下文,包括身份以及特权(privilege)。
Access Token 使用场合
当一个线程尝试进行如下操作的时候,操作系统会使用 Access Token 来识别一个用户
与安全对象(Secure Object)进行交互
执行一些需要系统权限的任务(例如对进程进行调试)
Access Token 包含内容
一个Access Token中实际上包含了如下的内容:
用户账户的SID
用户从属组的SID
当前登录会话(logon session)的SID
用户以及从属组所持有的特权
token 从属者的SID
主从属组(primary Group)的SID
当创建安全对象的时候,如果不指定安全描述符时系统会赋予的默认DACL
Access Token 的源
当前 token 是 primary(主token)还是 impersonation(模仿token)
一系列可选的限制Token (Restricted Token)
当前的模仿等级(impersonation level)
一些其他的东西
Primary/Impersonation Token 主Token/模仿token
从逻辑上讲,线程从属进程,而用户直接创建的是进程,所以进程中会持有象征着创建者的Token,这个Token就被称为主token (primary token)。一个主token中会记录当前用户与进程相关联的有效的安全上下文(secure context)。而实际上与安全对象交互的往往是线程,所以默认情况下主token是由线程携带与安全对象进行交互。
不过特殊情况下(例如在一些RPC场合,或者在一些CS架构的软件,server端限制client端权限的时候等),可能会出现某些线程需要以创建当前进程不同的,其他用户的身份访问安全对象 的时候,这个时候会给线程一个特殊的token,被称为模仿token(impersonation token) 。此时的线程使用属于自己的token,并且有不同于进程的权限。
相关API
此时可以使用
1 2 OpenProcessToken OpenThreadToken
来检查当前进程/线程的使用token
Windbg 查看方式
windbg中可以方便的查看一个进程的token
user mode
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 !token 0:000> !token Thread is not impersonating. Using process token... TS Session ID: 0x1 User: S-1-5-21-3132730683-2216882805-422503560-1001 User Groups: 00 S-1-16-8192 Attributes - GroupIntegrity GroupIntegrityEnabled 01 S-1-1-0 Attributes - Mandatory Default Enabled 02 S-1-5-114 Attributes - DenyOnly 03 S-1-5-32-544 Attributes - DenyOnly 04 S-1-5-32-545 Attributes - Mandatory Default Enabled 05 S-1-5-32-559 Attributes - Mandatory Default Enabled 06 S-1-5-4 Attributes - Mandatory Default Enabled 07 S-1-2-1 Attributes - Mandatory Default Enabled 08 S-1-5-11 Attributes - Mandatory Default Enabled 09 S-1-5-15 Attributes - Mandatory Default Enabled 10 S-1-11-96-3623454863-58364-18864-2661722203-1597581903-544001092-2724467026-4283684584-2191855628-1410562263 Attributes - Mandatory Default Enabled 11 S-1-5-113 Attributes - Mandatory Default Enabled 12 S-1-5-5-0-5228497 Attributes - Mandatory Default Enabled LogonId 13 S-1-2-0 Attributes - Mandatory Default Enabled 14 S-1-5-64-36 Attributes - Mandatory Default Enabled Primary Group: S-1-5-21-3132730683-2216882805-422503560-1001 Privs: 00 0x000000013 SeShutdownPrivilege Attributes - 01 0x000000017 SeChangeNotifyPrivilege Attributes - Enabled Default 02 0x000000019 SeUndockPrivilege Attributes - 03 0x000000021 SeIncreaseWorkingSetPrivilege Attributes - 04 0x000000022 SeTimeZonePrivilege Attributes - Auth ID: 0:4fea7c Impersonation Level: Anonymous TokenType: Primary Is restricted token: no. SandBoxInert: 0 Elevation Type: 3 (Limited) Mandatory Policy: TOKEN_MANDATORY_POLICY_VALID_MASK Integrity Level: S-1-16-8192 Attributes - GroupIntegrity GroupIntegrityEnabled Process Trust Level: LocalDumpSid failed to dump Sid at addr 000000ee876fabb8, 0xC0000078; try own SID dump. s-1-0 Attributes - Token Virtualized: Disabled UIAccess: 0 IsAppContainer: 0 Security Attributes Information: 00 Attribute Name: TSA://ProcUnique Value Type : TOKEN_SECURITY_ATTRIBUTE_TYPE_UINT64 Value[0] : 283 Value[1] : 428746286 Device Groups:
kernel mode
1 2 3 !process 0 0 // 找到对应的进程 !process PROCESS //查看具体的进程,找到其中的TOKEN !token TOKEN // 查看token信息
实例:获取Token句柄
通常情况下,我们的程序拿到的token都是伪token(pseudo token) 。这种方式主要是为了托管我们对内核句柄的操作:
1 HANDLE hToken = GetCurrentProcessToken ();
如上,虽然从API可知我们尝试获取了当前进程中的token(也就是primary token)但是此时的token值为:0xfffffffffffffffc
(64位下),显然不是一个真正的handle值。在某些场合下(需要知道确切句柄值的API的时候)会无法正常使用。如果需要知道此时真正的token的时候,需要使用OpenProcessToken
这个API:
1 OpenProcessToken (hProcess, TOKEN_ALL_ACCESS, &hToken);
这里注意,不可以使用DuplicateHandle
这个API!因为这个API在MSDN上写的其实是:
If hSourceHandle is a pseudo handle returned by GetCurrentProcess or GetCurrentThread, DuplicateHandle converts it to a real handle to a process or thread, respectively.
也就是说只有进程和线程的伪句柄才生效 。对于token的伪句柄是不生效的。
Restricted Token 限制令牌
限制令牌是由APICreateRestrictedToken
创建的一种主/模仿token。一个跑在限制token的安全上下文的进程或者模仿线程将会收到访问安全对象的限制,以及一些特权操作的限制。具体来说,会以如下的方式来限制一个token
移除token中的特权
对 token 中的 SIDs 应用 deny-only
的属性,从而让其无法访问到安全对象。(详情看后面的访问令牌中的SID属性
)
显示指定一系列的限制SID来限制安全对象访问
当系统检查一个token是对访问安全对象的访问权限的时候,系统通常会使用一系列的限制SIDs。当一个被限制的进程/线程尝试访问一个安全对象的时候,系统会进行两种检查:
检查token中被启用的SIDs
检查一系列的限制SIDs
只有当两种权限都被允许的时候,才能够访问这个对象。
API CreateProcessAsUser
拥有创建一个有指定token权限的进程,但是一般情况下需要有特权SE_ASSIGNPRIMARYTOKEN_NAME
。然而,当指定的进程token为限制token的时候,创建的父进程可以不具有特权也可创建。
SID Attributes in an Access Token
每一个用户组拥有的访问token
都有一系列的属性来说明操作系统要如何使用这个访问检查,一般来说有如下两种检查方式:
Attribute
Description
SE_GROUP_ENABLED
启用了这个属性的SID能够被进行访问检查。当系统尝试进行访问检查的时候,当检查当前的SID对应的ACE中状态为allowed\deny
的时候,能够被检查到。与此同时,未设置这个属性的(除了SE_GROUP_USE_FOR_DENY_ONLY
)的SID将会被忽略检查
SE_GROUP_USE_FOR_DENY_ONLY
启用这个属性的SID被称为deny-only
的SID,当系统进行访问检查的时候,只会检查对当前SID中deny的权限,而忽略所有allow的权限 ,也就是只关注这个SID被显示的拒绝了什么权限,而不关注其被允许的权限。一旦这个属性被设置的话,SE_GROUP_ENABLED
将无法被设置,并且SID不能被enable。
对访问Token的访问权限控制
一个应用只有在获得相应权限的时候才能够去修改一个ACL。这些权限被记录在访问Token中的安全描述符中。
如果才想要设置一个访问Token的安全描述符的时候,需要调用GetKernelObjectSecurity/SetKernelObjectSecurity
等相关API。
当需要使用OpenProcessToken/OpenThreadToken
获取的Token的时候,系统就会检查请求的权限和记录在token的安全描述符中的DACL中的差异。一般来说一个有效的访问权限token有以下的权限:
标准权限中,不支持SYNCHRONIZE
,其余的DELETE, READ_CONTROL, WRITE_DAC, WRITE_OWNER
都有
拥有 ACCESS_SYSTEM_SECURITY
的SACL的权限
其中Token还有一些只属于自己的权限。可以参考MSDN官方文档
特权 privilege
特权privilege
(例如一般的用户账号或者组账号——在本地计算机中执行的各种与系统相关的操作(例如开关闭系统,加载驱动,更改系统事件等等)的权利。特权(privilege)和之前提到过的访问权限(access right)有两个不同的地方:
特权控制的是对系统资源以及系统相关任务的访问权限,然而访问权限控制的是对安全对象 的访问权限。
只有系统管理员才能够将权限赋予用户/组(相当于提前给予的),然而系统可以基于一个对象的DCAL中的某一个ACE赋予/拒绝其对于某一个安全对象的访问权限。(相当于根据某个设定动态设定)
每一个系统都有一个用户数据库(account database),里面存储了每一个用户/组的特权信息。当用户尝试登录系统的时候,系统将会提供一个包含了当前用户所有特权的访问token ,以及授予用户这个访问token中的用户/组的特权。不过,这个特权只适用于本地计算机,在域中并不适用 。当用户尝试进行一个特权操作的时候,系统将会检查访问token中的特权位,检查其是否包含对应的特权权限,如果有的话,才会允许执行。这里大致展示一下:
TOKEN与Privilege
TOKEN的结构体大致长这个样子
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 32 33 34 35 36 37 typedef struct _TOKEN { TOKEN_SOURCE TokenSource; LUID TokenId; LUID AuthenticationId; LUID ParentTokenId; LARGE_INTEGER ExpirationTime; PERESOURCE TokenLock; LUID ModifiedId; SEP_TOKEN_PRIVILEGES Privileges; SEP_AUDIT_POLICY AuditPolicy; ULONG SessionId; ULONG UserAndGroupCount; ULONG RestrictedSidCount; ULONG VariableLength; ULONG DynamicCharged; ULONG DynamicAvailable; ULONG DefaultOwnerIndex; PSID_AND_ATTRIBUTES UserAndGroups; PSID_AND_ATTRIBUTES RestrictedSids; PVOID PrimaryGroup; ULONG * DynamicPart; PACL DefaultDacl; TOKEN_TYPE TokenType; SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; ULONG TokenFlags; UCHAR TokenInUse; ULONG IntegrityLevelIndex; ULONG MandatoryPolicy; PSECURITY_TOKEN_PROXY_DATA ProxyData; PSECURITY_TOKEN_AUDIT_DATA AuditData; PSEP_LOGON_SESSION_REFERENCES LogonSession; LUID OriginatingLogonSession; SID_AND_ATTRIBUTES_HASH SidHash; SID_AND_ATTRIBUTES_HASH RestrictedSidHash; ULONG VariablePart; } TOKEN, *PTOKEN;
其中SEP_TOKEN_PRIVILEGES
表示的就是当前TOKEN的特权:
1 2 3 4 nt!_SEP_TOKEN_PRIVILEGES +0x000 Present : Uint8B +0x008 Enabled : Uint8B +0x010 EnabledByDefault : Uint8B
这个_SEP_TOKEN_PRIVILEGES.Enabled
中的每一个bit就表示一种特权。前文提到的当用户尝试进行一个特权操作的时候,系统将会检查访问token中的特权位 ,实际上就是检查SEP_TOKEN_PRIVILEGES.Enabled
中的bit位是否为1.
实践:在windbg(kernel debug)下检查当前进程 token 的特权
用之前提过的技巧,首先找到当前进程的TOKEN地址:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 : kd> !process aed07600 1 PROCESS aed07600 SessionId: 1 Cid: 1b90 Peb: 00451000 ParentCid: 0d24 DirBase: 3ffd35c0 ObjectTable: af3f4540 HandleCount: 38. Image: Exploit.exe VadRoot a6f684a0 Vads 31 Clone 0 Private 105. Modified 0. Locked 0. DeviceMap 9cf61548 Token 8bfd18a0 <--------------注意这里 ElapsedTime 00:04:57.845 UserTime 00:00:00.000 KernelTime 00:00:00.000 QuotaPoolUsage[PagedPool] 25664 QuotaPoolUsage[NonPagedPool] 2540 Working Set Sizes (now,min,max) (650, 50, 345) (2600KB, 200KB, 1380KB) PeakWorkingSetSize 784 VirtualSize 16 Mb PeakVirtualSize 17 Mb PageFaultCount 810 MemoryPriority BACKGROUND BasePriority 8 CommitCharge 131
然后这里我们找到了对应token的地址,我们使用dt
去检查一下其内存中的形式:
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 1: kd> dt nt!_TOKEN 8bfd18a0 +0x000 TokenSource : _TOKEN_SOURCE +0x010 TokenId : _LUID +0x018 AuthenticationId : _LUID +0x020 ParentTokenId : _LUID +0x028 ExpirationTime : _LARGE_INTEGER 0x7fffffff`ffffffff +0x030 TokenLock : 0xaedba148 _ERESOURCE +0x034 ModifiedId : _LUID +0x040 Privileges : _SEP_TOKEN_PRIVILEGES +0x058 AuditPolicy : _SEP_AUDIT_POLICY +0x078 SessionId : 1 +0x07c UserAndGroupCount : 0xf +0x080 RestrictedSidCount : 0 +0x084 VariableLength : 0x78 +0x088 DynamicCharged : 0x1000 +0x08c DynamicAvailable : 0 +0x090 DefaultOwnerIndex : 4 +0x094 UserAndGroups : 0x8bfd1b40 _SID_AND_ATTRIBUTES +0x098 RestrictedSids : (null) +0x09c PrimaryGroup : 0xa3379658 Void +0x0a0 DynamicPart : 0xa3379658 -> 0x501 +0x0a4 DefaultDacl : 0xa3379674 _ACL +0x0a8 TokenType : 1 ( TokenPrimary ) +0x0ac ImpersonationLevel : 0 ( SecurityAnonymous ) +0x0b0 TokenFlags : 0x2000 +0x0b4 TokenInUse : 0x1 '' +0x0b8 IntegrityLevelIndex : 0xe +0x0bc MandatoryPolicy : 1 +0x0c0 LogonSession : 0x9e7756c8 _SEP_LOGON_SESSION_REFERENCES +0x0c4 OriginatingLogonSession : _LUID +0x0cc SidHash : _SID_AND_ATTRIBUTES_HASH +0x154 RestrictedSidHash : _SID_AND_ATTRIBUTES_HASH +0x1dc pSecurityAttributes : 0xaf366428 _AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION +0x1e0 Package : (null) +0x1e4 Capabilities : (null) +0x1e8 CapabilityCount : 0 +0x1ec CapabilitiesHash : _SID_AND_ATTRIBUTES_HASH +0x274 LowboxNumberEntry : (null) +0x278 LowboxHandlesEntry : (null) +0x27c pClaimAttributes : (null) +0x280 TrustLevelSid : (null) +0x284 TrustLinkedToken : (null) +0x288 IntegrityLevelSidValue : 0xae8aa528 Void +0x28c TokenSidValues : 0x9e748038 _SEP_SID_VALUES_BLOCK +0x290 IndexEntry : 0xb53e5b20 _SEP_LUID_TO_INDEX_MAP_ENTRY +0x294 DiagnosticInfo : (null) +0x298 BnoIsolationHandlesEntry : (null) +0x29c SessionObject : 0x8e0eb6f8 Void +0x2a0 VariablePart : 0x9e748044 1: kd> dx -id 0,0,aed07600 -r1 (*((ntkrpamp!_SEP_TOKEN_PRIVILEGES *)0x8bfd18e0)) (*((ntkrpamp!_SEP_TOKEN_PRIVILEGES *)0x8bfd18e0)) [Type: _SEP_TOKEN_PRIVILEGES] [+0x000] Present : 0x1e73deff20 [Type: unsigned __int64] [+0x008] Enabled : 0x60800000 [Type: unsigned __int64] [+0x010] EnabledByDefault : 0x60800000 [Type: unsigned __int64]
可以看到,_SEP_TOKEN_PRIVILEGES.Enabled
的值为0x60800000
,写成bit的形式就是:
1 1100000100000000000000000000000
此时直接查看token 的内容为:
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 _EPROCESS 0xffffffffaed07600, _TOKEN 0x0000000000000000 TS Session ID: 0x1 User: S-1-5-21-3717723882-702046769-3252787667-1000 User Groups: 00 S-1-5-21-3717723882-702046769-3252787667-513 Attributes - Mandatory Default Enabled 01 S-1-1-0 Attributes - Mandatory Default Enabled 02 S-1-5-114 Attributes - Mandatory Default Enabled 03 S-1-5-32-544 Attributes - Mandatory Default Enabled Owner 04 S-1-5-32-545 Attributes - Mandatory Default Enabled 05 S-1-5-4 Attributes - Mandatory Default Enabled 06 S-1-2-1 Attributes - Mandatory Default Enabled 07 S-1-5-11 Attributes - Mandatory Default Enabled 08 S-1-5-15 Attributes - Mandatory Default Enabled 09 S-1-5-113 Attributes - Mandatory Default Enabled 10 S-1-5-5-0-141477 Attributes - Mandatory Default Enabled LogonId 11 S-1-2-0 Attributes - Mandatory Default Enabled 12 S-1-5-64-10 Attributes - Mandatory Default Enabled 13 S-1-16-12288 Attributes - GroupIntegrity GroupIntegrityEnabled Primary Group: S-1-5-21-3717723882-702046769-3252787667-513 Privs: 05 0x000000005 SeIncreaseQuotaPrivilege Attributes - 08 0x000000008 SeSecurityPrivilege Attributes - 09 0x000000009 SeTakeOwnershipPrivilege Attributes - 10 0x00000000a SeLoadDriverPrivilege Attributes - 11 0x00000000b SeSystemProfilePrivilege Attributes - 12 0x00000000c SeSystemtimePrivilege Attributes - 13 0x00000000d SeProfileSingleProcessPrivilege Attributes - 14 0x00000000e SeIncreaseBasePriorityPrivilege Attributes - 15 0x00000000f SeCreatePagefilePrivilege Attributes - 17 0x000000011 SeBackupPrivilege Attributes - 18 0x000000012 SeRestorePrivilege Attributes - 19 0x000000013 SeShutdownPrivilege Attributes - 20 0x000000014 SeDebugPrivilege Attributes - 22 0x000000016 SeSystemEnvironmentPrivilege Attributes - 23 0x000000017 SeChangeNotifyPrivilege Attributes - Enabled Default 24 0x000000018 SeRemoteShutdownPrivilege Attributes - 25 0x000000019 SeUndockPrivilege Attributes - 28 0x00000001c SeManageVolumePrivilege Attributes - 29 0x00000001d SeImpersonatePrivilege Attributes - Enabled Default 30 0x00000001e SeCreateGlobalPrivilege Attributes - Enabled Default 33 0x000000021 SeIncreaseWorkingSetPrivilege Attributes - 34 0x000000022 SeTimeZonePrivilege Attributes - 35 0x000000023 SeCreateSymbolicLinkPrivilege Attributes - 36 0x000000024 SeDelegateSessionUserImpersonatePrivilege Attributes - Authentication ID: (0,23098) Impersonation Level: Anonymous TokenType: Primary Source: User32 TokenFlags: 0x2000 ( Token in use ) Token ID: 181366 ParentToken ID: 0 Modified ID: (0, de5e9) RestrictedSidCount: 0 RestrictedSids: 0x0000000000000000 OriginatingLogonSession: 3e7 PackageSid: (null) CapabilityCount: 0 Capabilities: 0x0000000000000000 LowboxNumberEntry: 0x0000000000000000 Security Attributes: Unable to get the offset of nt!_AUTHZBASEP_SECURITY_ATTRIBUTE.ListLink Process Token TrustLevelSid: (null)
注意特权那一栏:
特权的第23,29,30 bit正好都是1,对应在bit的形式就是(注意存在第0位):
1 1100000100000000000000000000000
正好和我们之前和内存中存在的形式看的一致。于是我们就能够知道当前进程中的token拥有的特权有:
SeChangeNotifyPrivilege:这类用户能够绕过NTFS文件系统/注册表中的访问权限的check,也就是对文件有特殊的访问特权就是了。
SeImpersonatePrivilege:这类用户可以模拟已有的token,但是不能创建新的token,也就是模仿token的创建特权。
SeCreateGlobalPrivilege:这类用户可以创建全局的安全对象。(也就是那种跨session的global object的创建权限)
LUID local identifier
之前提到过,每一个安全对象都有一个唯一的SID
,那么特权对象有没有对应的唯一标识符呢?其实是有的,就叫做LUID
,本地唯一标识符(因为特权只对当前机器生效,所以不需要GUID)。LUID可以在每台机器之间都不同,甚至每次重启之后都不同。为了确认当前LUID和特权的对应关系,可以使用API
1 2 LookupPrivilegeValue LookupPrivilegeName
进行切换。
一些杂项
Security system components
Windows下有很多实现了相关安全防护的组件(其中大部分都在%SystemRoot%\System32
这个目录下)
Security reference monitor(SRM)
存在ntoskrnl.exe
这个文件中,定义了acces token的数据结构,并且会对security access
进行checks,以及对不同token分发权限,并且产生安全审计日志。
Local Security Authority Subsystem Service(Lsass)
常见的user-mode
进程,主要用于本地操作系统安全策略管理(登陆用户管理,密码策略,用户(组)权限管理等等),用户权限,并且负责发送安全事件的日志。其中主要功能由Local Security Authority service
(Lsasrv.dll)进行实现。
LSAIso.exe
Lsass使用,或者叫做Credential Guard
,用于存放用户token的hash值,而不是直接在Lsas的内存中存放。由于Lsaiso.exe是Trustlet
进程(与普通用户空间隔离),所以当需要与Lsass.exe
通信的时候,只能使用ALPC
Lsass policy database
数据库中存储了了本地系统安全策略的设置。这个模块被存储在又ACL保护下的HKLM\SECURITY
下的注册表中。其中包含的信息有:
哪个域被授权登入
哪个用户对系统有哪些操控权限
用户被分发的权限
启用的安全审计等级
其中还存储了一些和登陆信息有关的秘密 。
Security Accounts manager(SAM)
这个服务用于管理定义在当前机器中用户名的组的数据库。这个模块由samsrv.dll
实现,并且会被load到进程lsass
.
SAM database
之前提到的被管理的数据库。里面存储了本地用户(组)以及对应密码和其他相关的属性。对于域控制者来说,SAM
·中并不会存放域定义者的用户信息,但是会存放系统管理员恢复的账号和密码。这些数据存放在:HKLM\SAM
Active Directory(活动目录)
这是一个目录服务,包含一个存储域中对象的数据库。一个域由许多的计算机组成,这些计算机会被组织成一个安全组,并且作为一个实体进行管理。AD会将这些对象的信息存放在域中,包括用户,组以及计算机。域用户和组的密码信息以及权限都会被存储在一个在所有计算机中,被设计为域管理员的AD中。AD server 由Ntdsa.dll
实现,同样运行在lsass.exe
进程中。
Authentication packages
这个模块其实是指的哪些运行在lsass 以及其他实现了windows 客户验证的dlls。一个验证dll将会验证一个用户的用户名和密码是否匹配(或者当前机器会不会提供身份认证)。如果匹配,则返回给Lsass用户的安全身份,lsass用此来产生验证用的token。
Interactive logon manager(WinLogon)
这个就是Winlogon.exe
,是第一个用户态的程序,用来进行SAS(Shared Access Signature),并且对登陆的会话进行管理。当用户登陆成功后,winlogon.exe将会创建第一个用户程序。
Login user inerface(LogonUI)
一个用户态的进程LogonUI.exe
可以让用户对自己的身份进行验证。
Credential providers(CPs)
这个是一个COM对象,运行在进程LogonUI中,用来获取用户的用户名和密码,smartcard PIN 码,生物信息(指纹等等),或者其他的身份认证信息。完整的CPs
由authui.dll
,SmartcardCredentialProvider.dll
,BioCredProv.dll
以及FaceCredentialProvider.dll
实现(有些特性win10才加入)
Network logon service(Netlogon)
这个是由Netlogon.dll
(由svchost启动)模块实现的一个功能。用于设置对域控制的安全通道,以及安全请求。例如交互式登陆(如果域是在WIndows NT 4)或者LAN Manager以及NT LAN Manager(V1/V2)的身份认证,这个模块同样也会作为AD的登陆模块使用。
Kernel Security Device Driver(KsecDD)
一个内核态的模块(%SystemRoot%\System32\Drivers\Kescdd.sys
),实现了APLC(Advanced local procedure call
的结构。让其他的内核态安全模块(包括Encryption File System(EFS)
)能与Lsass进行通信
AppLocker
这个功能运行管理员能够指定哪个exe,dll,scripts
能被指定的用户执行。这个模块由内核驱动(%SystemRoot%\System32\Drivers\Appld.sys
)和服务(AppidSvc.dll
)两部分组成
Credential Guard
Crediential Guard
给系统中的不同元素提供了安全边界与保护。不过为了实现这个过程,首先需要知道程序是怎么实现身份验证的
Password:登陆验证,这个是最常见的身份验证方法。
NT one-way function(NT OWF):通常在用户用password登陆成功后,使用NT LAN
用于对传统模块的身份验证。不过在现在的网络系统验证已经不使用这部分内容了
Ticket-granting ticket(TGT):这就是现代的远程网络验证常用的一个验证方式:Kerberos.这也是通常Windows AD域
下常做的验证方式。在登陆成功之后,TGT以及相应的密钥将会被提供给本地机器。