目录
Windows凭据
Windows访问控制模型
访问令牌:
安全标识符(SID):
安全描述符:
令牌安全防御
1、禁止域管理员异机登录
2、开启“审核进程创建”策略
Windows凭据
-
SSPI(Security Support Provider Interface ,安全支持提供程序接口):是windows操作系统中用于执行各种安全相关操作的公用API,可以用来获得身验证、信息完整性校验、信息隐私保等继承的安全服务
-
SSP(Security Support Provider,安全支持提供程序):是一个用于实现身份验证的DDL文件。当操作系统启动时,SSP会被加载到LSA(Local Security Authority,本地安全机构)中
-
SSP的作用时扩展windows的身份验证功能,可以这样简单的理解为:SSP就是一个DLL文件,用来实现身份验证并且维持系统权限
-
常见的SSP类型:
-
NTLM:一种Window网络认证协议,基于挑战/响应(Challenge/Response)验证机制,对主机进行身份验证
-
Kerberos:一种网络身份验证协议,它的优势在于可以提供强大的单点登录机制(SSO)
-
Negotiate:用于在SSPI和SSP之间进行安群支撑的应用程序层。当某个应用程序调入SSPI以登录到网络时,该应用程序会指定一个SSP来处理请求
-
安全通道,也称为SChannel,主要用来需要进行安全超协议(HTTP)通信的wb应用程序
-
摘要身份验证:基于HTTP和SASL(简单认证与安全层)身份验证的质询/响应协议
-
Cred SSP:用于传输安全凭证的网络协议
-
分布式密码验证(DPA):提供使用数字证书完成的对等身份验证
-
用户对用户的公开密钥加密技术(Public Key Cryptography User-toUser,PKU2U)
Windows访问控制模型
访问令牌:
访问令牌由当前登录的Windows所持有,它包含该账号的基础信息,如用户标识符和权限信息
它代表某种请求或者登录机制的凭据,使得用户可以在短时间内执行某种身份认证或者权限操作的验证信息
windows系统中的每个用户登录账号都会生成一个对应的访问令牌。当用户使用账号登录操作系统时,系统会将所登录的账号与安全数据库(SAM)中存储的数据进行对比验证,验证成功后才会生成访问令牌。
如果我们打开的进程/线程正在与具有安全描述符的对象交互,则系统会携带令牌进行访问,因此来表示用户的身份
创建进程时,windows操作系统的内核都会为进程创建并分配一个主令牌,每个进程都含有一主令牌,主令牌描述了进程相关用户账号的安全上下文,同时一个线程可以模拟一个客户端账号,允许此线程在与安全对象交互时使用客户端的安全上下文,一个正模拟客户端的线程拥有一个主令牌和一个模拟令牌
从上面我们可以看到访问令牌又被分为了下面两种:
-
主令牌:与进程相关
主令牌又称为授权令牌(Delegation Token),是一种认证机制,用户交互式登录,是为了减少不必要的认证工作而出现的
由windows操作系统的内核创建并且分配给进程的默认访问令牌
主令牌描述了登录进程返回的安全标识SID,与当前进程相关的用户账户的安全组的权限列表,代表系统可以使用令牌控制用户可以访问哪些安全对象,执行哪些相关的系统操作,
主令牌通常用户本地登录及通过RDP远程登录的场景、
一个完整的主令牌包含以下内容:
用户(User)。用户账号的SID。若用户登录到本地计算机上的一个账号,则他的 SID来自于本地SAM维护的账号数据库;若用户登录到一个域账号,则他的SID来自于活动目录里用户对象的Object-SID属性。
组(Groups)。包含该用户的安全组的SID列表,表中也包含代表活动目录里用户 账号的用户对象的SID-History属性里的SID。
特权(Privileges)。用户和用户的安全组在本地计算机上拥有的特权列表。
所有者(Owner)。特定用户或安全组的SID,这些用户或安全组默认成为用户所 创建或拥有的任何对象的所有者。
主组(Primary Group)。用户的主安全组的SID。这个信息只由POSIX子系统使用, Windows 2000的其他部分对其忽略。
默认任意访问控制表(Default Discretionary Access Control List, DACL)。一组内置 许可权。在没有其他访问控制信息存在时操作系统将其作用于用户所创建的对象。默认DACL向创建所有者和系统赋予完全控制(Full Control)权限。
源(Source)。导致访问令牌被创建的进程,例如会话管理器、LAN管理器或远程 过程调用(RPC)服务器。
类型(Type)。指示访问令牌是主(primary)令牌还是模拟(impersonation)令牌。 主令牌代表一个进程的安全上下文;模拟令牌是服务进程里的一个线程,用来临时接受一个不同的安全上下文(如服务的一个客户的安全上下文)的令牌。
模拟级别(Impersonation Level)。指示服务对该访问令牌所代表的客户的安全上下 文的接受程度。
统计信息(Statistics)。关于访问令牌本身的信息。操作系统在内部使用这个信息。
限制SID(Restricting SID)。由一个被授权创建受限令牌的进程添加到访问令牌里 的可选的SID列表。限制SID可以将线程的访问限制到低于用户被允许的级别。
会话ID(Session ID)。指示访问令牌是否与终端服务(Terminal Services)客户会 话相关。
-
模拟令牌:与线程相关
在默认情况下,当线程开启时候,其所在进程的主令牌会自动附加到该线程上作为它的安全上下文。
而线程可以另一个非主令牌的访问令牌下执行,这个令牌被称为模拟令牌,通常用于客户端/服务器之间的通信
线程能够在与拥有它的进程的上下文不同的安全上下文里执行,这种能力称为模拟,它是为了满足客户/服务器应用的安全需求而设计的。当在一个客户的安全上下文里运行时,服务在某种程度上“是”客户。服务的一个线程使用代表客户资格的访问令牌来访问该客户有权访问的对象。
模拟的主要原因是根据客户的标识执行访问检查。使用客户标识进行访问检查可以根据该客户拥有的许可权来限制或扩展访问。例如,假设一个文件服务器上有包含秘密信息的文件,这些文件都由一个DACL保护。
为了防止客户未经授权就可访问这些文件中的信息,服务可以在访问文件之前模拟客户。
安全标识符(SID):
安全标识符(Security IDentifier)用于标识用户的账号以及其所属的任何组账号,当我们创建一个进程,也就是访问一个资源(进程资源)的时候,访问令牌会被复制一份并且交给进程,进程根据它创建者为它设置的安全描述符中的访问控制列表(ACL)来判断我们是否可以访问,是否有权限执行某一步操作。
SID是一个唯一的字符串,可以代表用户、用户组、域、域组、域成员等角色
SID) (安全标识符 是用于标识 受托人的可变长度的唯一值。 每个帐户都有一个由机构(如 Windows 域控制器)颁发的唯一 SID,并存储在安全数据库中。
每次用户登录时,系统都会从数据库中检索该用户的 SID,并将其置于该用户的 访问令牌 中。
系统使用访问令牌中的 SID 在与 Windows 安全的所有后续交互中标识用户。
Windows 安全性在以下安全元素中使用 SID:
-
在 安全描述符 中,用于标识对象和主组的所有者
-
在 访问控制条目中,标识允许、拒绝或审核访问的受托人
-
在 访问令牌中,用于标识用户和用户所属的组
(1)SID的组成部分
SID 由以下组件组成:
-
SID 结构的修订级别
-
一个 48 位标识符颁发机构值,用于标识颁发 SID 的颁发机构
-
可变数量的子授权或 相对标识符 (RID) 值,这些值相对于颁发 SID 的颁发机构唯一标识受信人
(2)SID结构分析
以下示例使用此表示法显示本地 Administrators 组的已知域相对 SID:
S-1-5-32-544
在此示例中,SID 具有以下组件。 括号中的常量是 Winnt.h 中定义的已知标识符颁发机构和 RID 值:
-
S表示字符串为SID
-
修订级别为 1
-
标识符颁发机构值为 5 (SECURITY_NT_AUTHORITY)
-
第一个子授权值 32 (SECURITY_BUILTIN_DOMAIN_RID)
-
第二个子授权值 544 (DOMAIN_ALIAS_RID_ADMINS)
(3)常见的SID
-
S-1-5-18 (LocalSystem)
-
S-1-5-19 (LocalService)
-
S-1-5-20 (NetworkService)
-
S-1-5-32-544 (Administrators)
-
S-1-5-32-545 (Users)
-
S-1-5-32-550 (PrintOperators)
(4)SID构建方式
在windows操作系统中,因常见的SID名称可能会有所不同,我们应该通过使用API函数来从预定义的标识授权和RID定义的常量中构建SID
如果需要使用 SID,请不要直接操作它们。 请改用以下函数。
函数 | 说明 |
---|---|
AllocateAndInitializeSid | 分配并初始化具有指定数量的子授权的 SID。 |
ConvertSidToStringSid | 将 SID 转换为适合显示、存储或传输的字符串格式。 |
ConvertStringSidToSid | 将字符串格式的 SID 转换为有效的功能 SID。 |
CopySid | 将源 SID 复制到缓冲区。 |
EqualPrefixSid | 测试两个 SID 前缀值是否相等。 SID 前缀是整个 SID,最后一个子授权值除外。 |
EqualSid | 测试两个 SID 是否相等。 它们必须完全匹配才能被视为相等。 |
FreeSid | 使用 AllocateAndInitializeSid 函数释放以前分配的 SID。 |
GetLengthSid | 检索 SID 的长度。 |
GetSidIdentifierAuthority | 检索指向 SID 标识符颁发机构的指针。 |
GetSidLengthRequired | 检索存储具有指定数量的子授权的 SID 所需的缓冲区大小。 |
GetSidSubAuthority | 检索指向 SID 中指定子授权的指针。 |
GetSidSubAuthorityCount | 检索 SID 中的子授权数。 |
InitializeSid | 初始化 SID 结构。 |
IsValidSid | 通过验证修订号是否在已知范围内以及子授权数是否小于最大值来测试 SID 的有效性。 |
LookupAccountName | 检索与指定帐户名称对应的 SID。 |
LookupAccountSid | 检索与指定 SID 对应的帐户名称。 |
(5)构建常见的SID表以及标识符权限和子权限的常量表
有一些已知的 SID 用于标识以下组和用户:
-
Everyone 或 World,这是一个包含所有用户的组。
-
CREATOR_OWNER,用作可继承 ACE 中的占位符。 继承 ACE 后,系统会将CREATOR_OWNER SID 替换为对象创建者的 SID。
-
本地计算机上内置域的 Administrators 组。
有 通用的已知 SID,这些 SID 对于使用此安全模型的所有安全系统(包括 Windows 以外的操作系统)都有意义。 此外,还有一些已知的 SID 仅在 Windows 系统上有意义。
Windows API 为已知标识符颁发机构定义一组常量和 相对标识符 (RID) 值。 可以使用这些常量创建已知的 SID。 以下示例将 SECURITY_WORLD_SID_AUTHORITY 和 SECURITY_WORLD_RID 常量组合在一起,以显示特殊组的通用已知 SID,该组表示所有用户 (Everyone 或 World) :
S-1-1-0
此示例对 SID 使用字符串表示法,其中 S 将字符串标识为 SID,前 1 位是 SID 的修订级别,其余两位是SECURITY_WORLD_SID_AUTHORITY和SECURITY_WORLD_RID常量。
可以使用 AllocateAndInitializeSid 函数通过将标识符颁发机构值与最多 8 个子授权值组合在一起来生成 SID。 例如,若要确定登录用户是否是特定已知组的成员,请调用 AllocateAndInitializeSid 为已知组生成 SID,并使用 EqualSid 函数将该 SID 与用户访问 令牌中的组 SID 进行比较。 有关示例,请参阅 使用 C++ 在访问令牌中搜索 SID。 必须调用 FreeSid 函数才能释放由 AllocateAndInitializeSid 分配的 SID。
本部分的其余部分包含已知 SID 表,以及可用于生成已知 SID 的标识符授权和子授权常量表。
下面是一些 通用的已知 SID。:
通用公认 SID | 字符串值 | 标识 |
---|---|---|
空 SID | S-1-0-0 | 没有成员的组。 这通常在 SID 值未知时使用。 |
World | S-1-1-0 | 包括所有用户的组。 |
Local | S-1-2-0 | 登录到本地 终端 的用户 (物理) 连接到系统。 |
创建者所有者 ID | S-1-3-0 | 安全标识符,将被替换为创建新对象的用户的安全标识符。 此 SID 用于可继承的 ACE。 |
创建者组 ID | S-1-3-1 | 安全标识符,将被替换为创建新对象的用户的主要组 SID。 在可继承 ACE 中使用此 Sid. |
下表列出了预定义的标识符颁发机构常量。 :
标识符颁发机构 | 值 | 字符串值 |
---|---|---|
SECURITY_NULL_SID_AUTHORITY | 0 | S-1-0 |
SECURITY_WORLD_SID_AUTHORITY | 1 | S-1-1 |
SECURITY_LOCAL_SID_AUTHORITY | 2 | S-1-2 |
SECURITY_CREATOR_SID_AUTHORITY | 3 | S-1-3 |
SECURITY_NT_AUTHORITY | 5 | S-1-5 |
RID颁发机构:
相对标识符颁发机构 | 值 | 字符串值 |
---|---|---|
SECURITY_NULL_RID | 0 | S-1-0 |
SECURITY_WORLD_RID | 0 | S-1-1 |
SECURITY_LOCAL_RID | 0 | S-1-2 |
SECURITY_LOCAL_LOGON_RID | 1 | S-1-2 |
SECURITY_CREATOR_OWNER_RID | 0 | S-1-3 |
SECURITY_CREATOR_GROUP_RID | 1 | S-1-3 |
安全描述符:
安全描述符(Security Descriptor)由要访问的对象所有,它包含当前对象的安全信息,假设当用户登录的时候,操作系统会对用户的账户和密码进行身份验证,当登录成功后,系统会自动分配访问令牌
安全描述符包含以下两部分:
-
DACL,任意访问控制列表,包含ACE,决定当前用户以哪种权限访问对象
-
SACL,系统访问控制列表,主要用于系统审计,它的内容指定了当特定账户对这个对象执行特定的操作,将其记录到系统日志中
安全描述符绑定在每个被访问的对象上,当我们携带访问令牌去访问一个带有安全描述符的对象时,安全描述符会检测我们的访问令牌是否具有访问权限
(1)安全描述符的组织结构
安全描述符由SECURITY_DESDCRIPTOR结构以及关联的安全信息组成
typeof struct_SECUURITY_DESCRIPTOR {
BYTE REvision;
BYTE Sbz1;
...
} SECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR;
(2)安全描述符号包含以下的安全信息
安全描述符可以包含以下安全信息:
-
对象的 所有者和主组的安全标识符 (SID) 。
-
一个 DACL ,指定允许或拒绝的特定用户或组的访问权限。
-
一个 SACL,指定为对象生成审核记录的访问尝试的类型。
-
一组控制位,用于限定安全描述符或其单个成员的含义。
(3)安全描述符查看
当我们需要查看某个对象具有什么安全描述符时,可以选择一个文件,右击该对象,选择“属性”选项,进一步查看“安全选项卡
(4)DACL
DACL包含ACE,决定了当前用户以吗那种权限访问对象,系统使用下面几种方式为对象构建DACL
-
对象当前的DACL是对象创建者的安全描中的DACL。除非在安全描述符中的控制位设置了SE_DACL_PROTECTED位,否则系统会将所有的可继承的ACE合并到指定的DACL中。
-
如果创建者未指定安全描述符,则系统将从可继承的ACE构建对象的DACL。
-
如果未指定安全描述符,并且没有可以继承的ACE,则对象的DACL是来自创建者的主令牌或者模拟令牌中的默认DACL
-
如果没有指定的、继承的或者默认的DACL,则系统将创建不具有DACL的对象,从而允许所有人完全的访问该对象
(5)SACL
SACL主要用于系统审计,同时可以指定哪些用户的行为操作记录会被保存到系统日志中,系统使用以下几种方式来为新对象构建SACL
-
对象的SACL是对象创建者指定的安全描述符中的SACL。除非在安全描述符的控制位中设置了SE_SACL_PROTECTED位,否则系统将会将所有可以继承的ACE合并到指定的SACL中。即使SE_SACL_PROTECTED位置已经设置,来自父对象的STSTEM_RESOURCE_ATTRIBUTE和STSTEM_SCOPED_PCOPED_POLICY_ID_ACE也将合并到新对象。
-
如果创建者未指定安全描述符,则系统将从可以继承的ACE构建对象的SACL
-
如果没有指定的或者可以继承的SACL,则该对象没有SACL
-
要为新的对象指定SACL,对象的创建者必须启用SE_SECURITY_NAME特权。
(6)安全描述符字符串
安全描述字符串指的是安全描述符中存储或者传输信息的文本格式。
安全描述符包含二进制格式的安全信息,windows API提供了在二进制安全描述符与文本字符串之间进行相互转换的功能。
字符串格式的安全描述符不起作用,但是对于存储或者传输安全描述符信息很有用
要将安全描述符转换为字符串格式,需要调用ConvertSecurityDescriptorToStringSecurityDescriptor函数
要将字符串转换为安全描述符格式,需要调用ConvertStringSecurityDescriptorToSecurityDescriptor函数
令牌安全防御
Window用访问令牌的方式来记录用户身份,验证用户权限,每个用户都有一个访问令牌,一般攻击者会利用DuplicateTokenEx API来对令牌进行模拟盗窃。
下面几种方式可以一定程度上防御令牌窃取
1、禁止域管理员异机登录
域管理员是在这个域控中管理权限最高的,为了防止域管理员的令牌被恶意窃取,必须禁止域管理员异机登录。如果因为一些特殊原因域管理员登录了其他机器,应该及时的将令牌清除,以防止令牌被窃取
2、开启“审核进程创建”策略
进入组策略中:
根据下图依次点击:
双击打开“审核进程创建页面”后,配置无论成功还是失败都进行审核(在创建进程时会生成审核事件,成功审核记录成功的尝试,而失败的审核记录不成功的尝试),即两个都勾选:
然后可以通过查看器来查看执行访问令牌尝试操作的记录:直接在搜索中搜事件查看器即可
到此,windows认证的基础知识就结束了,下一篇将会分享UAC的相关知识