The AuthZ API
Windows的AuthZ API提供安全授权功能,并实现了与安全引用监视器(SRM)相同的安全模型,但是它是完全在用户模式下实现的。这使得那些想要保护其私有对象(比如数据库表)的应用能够充分利用Windows的安全模型,但又不必付出从用户模式到内核模式转换的代价。如果直接依赖于Windows的安全引用监视器,则这种模式转换的代价是必须要付出的。
AuthZ API使用了标准的安全描述符数据结构,SID和特权。但是AuthZ并不使用令牌来表示客户,相反,它使用AUTHZ_CLIENT_CONTEXT。对于所有的访问检查和Windows安全函数,AuthZ都包含了对应的用户模式等价版本。例如,AuthzAccessCheck是Windows API AccessCheck的AuthZ版本,其中的AccessCheck使用了安全引用监视器函数SeAccessCheck。
对于那些使用AuthZ的应用,另一个好处是,它们可以指示AuthZ将安全检查的结果缓存起来,以提高后续的、使用同样客户环境和安全描述符的检查效率。Windows SDK中有关于AuthZ的完整文档。
前面讲到的自主访问控制安全机制是WindwosNT家族从一开始就包含的一个部分,而且这些机制在静态的、受控的环境下工作良好。这种类型的安全检查要用的一个安全ID(SID)和安全组成员的身份,称为基于身份的访问控制(IBAC,identity-based access control);并且当DACL被放进对象的安全描述符时,它要求安全系统必须知道每个可能的访问者的身份。
Windows只支持基于主张的访问控制(CBAC,Claims Based Access Control),其中授予访问权的依据并不是访问者的身份或所属的组,而是赋予访问者并保持在它的访问令牌中的各种任意可能的属性。这些属性是由属性提供者提供的,例如AppLocker这样的属性提供者。CBAC机制提供了很多好处,包括能为身份暂时未知的用户,或为动态计算出来的用户属性,创建一个DACL。CBAC的ACE保存在一个“*-回调”的ACE结构中,它本质上是给AuthZ私有使用的;系统的SeAccessCheck API会忽略它。内核模式的CBAC。使用CBAC的系统组件只有AppLocker,用于设置诸如路径,发布者之类的属性。第三方应用程序可以通过CBAC AuthZAPI来充分利用CBAC。
通过使用CBAC安全检查,能实施功能强大的管理策略,比如下面这些:
1.只运行由公司IT部门批准的应用程序
2. 只允许批准过的应用程序访问你的Microsoft Outlook联系人或日历
3.只允许某个特定楼层里的人员访问该楼层里的打印机
4. 只允许全职人员访问某个内网网站
在成为“有条件的ACE”的结构中可以引用属性;因而可以检查属性的存在或不存在,也可以检查一个或多个属性的值。属性的名称可以包含任意的Unicode字母或数字,以及“:/._”这些字符。属性的值可以使一下几种中的一种:64位整数,Unicode字符串,字节串(byte string)或者数组。
有条件的ACE
安全描述符定义语言(SDDL,Security Descriptor Definition Language)字符串的格式已经被扩展了,可以支持条件表达式。新的SDDL字符串格式如下:AceType;AceFlags;Rights;ObjectGuid;InheritObjectGuid; AccountSid;(ConditionalExpression)。注意,带有条件表达式的ACE专用于主张类型的授权过程(特别是AuthZ API和AppLocker),对象管理器或文件系统不认识这种ACE。
一个有条件的ACE可以包含任意数量的条件,并按以下方式处理:如果条件的计算结果是假,它就被忽略;如果结果是真,它就被应用。通过调用AddConditionalAceAPI,可以把一个有条件的ACE添加到一个对象中:通过AuthzAccessCheck API,可以检查有条件的ACE。
一个有条件的ACE可以指定,仅当用户满足下满列出的标准时,才允许该用户访问某个程序中特定的数据记录:
1. 拥有Role(角色)属性,其值是Architect(架构师)、Program Manager或Development Lead,并且Devision属性的值是Windows。
2. 该用户的ManagementChain属性包含“John Smith”这个值
3. 该用户的CommissionType属性是Officer,并且PayGrade属性高于6
Windows没有提供工具来查看或编辑有条件的ACE。
账户权限和特权Account rights and privileges
进程在运行过程中执行的许多操作是无法通过对象访问保护来授权控制的,因为这些操作并没有与一个特定的对象打交道。例如,当为了做备份而打开文件时,“能够绕过安全检查”这一能力是一个账户的属性,而不是某个对象的属性。Windows使用特权和账户权限来让系统管理员可以控制哪些账户能够执行与安全相关的操作。
特权是指一个账户执行某个与系统相关的操作的权限,比如,关停计算机或者改变系统的时间。而账户权限则吧“执行某一特定登录类型(比如本地登录或交互式登录到一台计算机上)的能力”授予它所针对的账户,或拒绝分配给该账户。
系统管理员利用一些工具来将特权分配给组和账户,这样的工具有针对域账户的活动目录用户和组的MMC加载件(MMC snap-in),或者本地安全策略编辑器(LocalSecurity Policy Editor)。你通过控制面板的Administrator Tools(管理工具)文件夹,或者开始菜单就可以启动本地安全策略编辑器。图7-11显示了本地安全策略编辑器中的用户权限分配配置界面,他现实了Windows上所有可用的特权和账户权限的完整列表。注意该工具并不区分特权和账户权限。然而,你可以对两者进行区分,因为任何不包括词“log on”的用户权限都是一个账户特权。
账户权限
账户权限并不是由安全应用监视器强制实施的,也不储存在令牌中。负责登录的函数式LsaLogonUser。例如,当一个用户以交互方式登录到一台机器上时,Winlogon调用LogonUser API,而LogonUser有调用了LsaLogonUser。LogonUser函数有一个参数指明了要执行的登录类型,包括交互式登录、网络登录、批方式登录、服务方式登录、终端服务器客户。
当一个用户企图登录到系统中时,作为对登录请求的响应,本地安全权为中心(LSA)从LSA策略数据库中获取到已赋予该用户的账户权限。LSA根据已分配给当前登录用户的账户权限,对登录类型进行检查,如果该用户的账户没有“允许此种登录类型”的权限,或者具有“拒绝此种登录类型”的权限,则LSA拒绝此登录请求。
特权
由操作系统定义的特权的数量随着时间的推移而不断增加。用户权限是由LSA在一个地方强制使用的;与此不同的是,不同的特权是由不同的组件来定义的,并且也由这些组件来强制使用。例如,调试特权是由进程管理器(Process Manager)来检查的,它使得一个进程在利用Windows API函数OpenProcess来打开另一个进程的句柄时可以绕过安全检查。
与账户权限不同的是,特权是可以被启用和禁用的。要想让一个特权检查能够成功的通过,该特权必须出现在指定的令牌中,而且它必须是启用的。这种方案背后的思想是,只有当确实有必要使用特权时,这些特权才应该是启用的,所以,一个进程不会毫无意识的执行一个有特权的安全操作。
实验:查看一个特权变成启用的
1. 运行Process Explorer
2.启动timedate.cpl
3. 查看rundll32.exe的Security页面
4.设置时区
超级特权
有几个特权的功能如此强大,以至于一旦用户被授予这样的特权,该用户就成了一个对计算机有完全控制权的超级用户。用户能够通过各种无穷无尽的方式来使用这些特权,以获得对本该禁入的资源的未授权访问,以及执行未授权的操作。然而我们将焦点集中在“利用特权来执行一些代码,有这些代码将本来没有分配给用户的特权授予该用户”,以及“充分利用这种能力,从而在本地机器上执行任何期望的操作”。
本节列出这些特权,并且讨论这些特权可能被发觉和使用的途径。其他的特权,比如“Lock Pages In Physical Memory(将页面锁在物理内存中)”,也可能被发掘出来,并在一个系统上用于实施拒绝服务攻击,但这里没有讨论这些特权。注意,在启用了UAC的系统上,这些特权将仅被授予给那些至少运行于“高”完整性级别的应用程序,即使当前账号已经拥有这些特权也是如此。
1. 调试程序:具有此特权的用户可以打开系统中任何一个进程(除了受保护进程以外),而不必考虑该进程上的安全描述符。例如,用户可以实现这样一个程序,它打开LSASS进程,将可执行代码拷贝到它的地址空间中,然后通过CreateRemoteThread Windows API注入一个线程,让它在一个更加有特权的安全环境中执行这些注入的代码,这部分代码可以授予该用户额外的特权和族成员关系。
2. 接管所有权:这一特权使得特权持有者能够接管任何一个被保护对象(甚至受保护的进程和线程)的所有权。做法是,将它自己的SID写到该对象的安全描述符的所有者域中。前面曾经提到过,所有者总是被授予“读取和修改该安全描述符的DACL”的许可,所以,具有此特权的进程可以修改此DACL,已授予它自己对该对象的完全访问全,然后关闭该对象,再用完全访问权重新打开该对象。这将使得该所有者能够看到敏感的数据,甚至用他自己的程序来替代那些作为正常系统操作的一部分来执行的系统文件(比如LSASS),而在他自己的程序中,他可以将提升的特权授予给一个用户;
3. 恢复文件和目录:被分配了此特权的用户能够用他自己的文件来替代该系统中的任何文件。他可以像上一段中描述的那样来替换系统的文件,从而发掘出强大的威力;
4. 加载和卸载设备驱动程序:一个恶意用户可以使用这种特权将一个设备驱动程序加载到系统中。系统驱动程序被认为是操作系统的可信任部分,操作系统可能会在System账户凭证下执行驱动程序中的代码,所以,一个驱动程序可以启动有特权的程序,这些特权程序在授予用户其他的权限;
5. 创建一个令牌对象:此特权的一种很显然的用法是,生成一些代表任意用户账户的令牌,而且其中的用户账户可以有任意的组成员关系和特权;
6. 作为操作系统的一部分来执行:LSARegisterLogonProcess函数要检查此特权,一个进程调用此函数来建立起它与LSASS之间的可信连接。具有此特权的恶意用户可以建立一个可信的LSASS连接,然后执行LsaLogonUser。LsaLogonUser要求一个有效的用户名和口令,并且接收一组可选的SID列表,他将这些SID加入到它为新登录会话创建的初始令牌中。因此,用户可以使用他自己的用户名和口令来创建一个新得登录会话,而新的登录会话在其令牌中包含多个特权组或用户的SID。
注意,提升起来的特权的适用范围并不会透过机器的边界,扩展到网络上,因为与另一台计算机的任何交互操作都要求通过一个域控制器进行认证,并且要验证域口令。而域口令并不以明文方式或加密形式被储存在一台计算机上,所以恶意代码是无法访问到域口令的。
进程和线程的访问令牌Access tokens of processes and threads
下图把本章到目前为止讲述的概念都放在了一起,演示了基本的进程和线程的安全结构。在图中,注意进程对象、线程对象以及访问令牌本身都带有ACL。
安全审计Security auditing
作为一次访问检查的结果,对象管理器可能会生成一些审计事件;而且有些可供用户应用程序使用的Windows函数也可以直接生成审计事件。内核模式的代码总是允许生成审计事件。有两个特权与审计有关,他们是SeSecurityPrivilege和SeAuditPrivilege。一个进程必须有SeSecurityPrivilege特权才能管理安全事件日志(EventLog),以及查看或这只一个对象的SACL。然而如果一个进程要调用审计系统的服务,那么它必须拥有SeAuditPrivilege特权,这样才能成功的生成一条审计记录。
本地系统的审计策略控制了“审计某种特定类型的安全事件”的决定。审计策略也称为本地安全策略,它是本地系统上LSASS维护的安全策略的一部分,它可以通过本地安全策略编辑器来进行配置。
审计策略配置信息在注册表中被保存为位图形式的值,位于HKEY_LOCAL_MACHINE\SECURITY\Policy\PolAdtEv
在系统初始化时刻,以及当审计策略改变的时候,LSASS给SRM发送消息,告诉它关于审计策略的情况。LSASS负责接收那些根据SRM的审计事件而生成的审计记录,也负责编辑这些记录,并且将它们发送给事件记录器(Event Logger)。之所以由LSASS发送这些记录,是因为它加入了有用的细节,比如为了更加完整的标识出被审计进程而需要的信息。
SRM通过它与LSASS之间的ALPC连接来发送审计记录。然后,事件记录器将审计记录写到安全事件日志中。除了SRM传递过来的审计记录以外,LSASS和SAM也会生成一些审计记录,LSASS直接将它们发送给事件记录器,AuthZ API也允许应用程序生成由他们自己定义的审计。
当SRM接收到审计记录时,这些审计记录被放到一个队列里,以便进一步发送至LSA--它们不是被成批提交的。审计记录通过两种方式之一,被从SRM中转移到安全子系统中。如果一个审计记录比较小(小于最大的ALPC消息长度),那么它被当作一个ALPC消息来发送。这样的审计记录被从SRM‘的地址空间中拷贝到LSASS进程的地址空间中。如果审计记录比较大,那么,SRM使用共享内存,让LSASS直接访问该信息,它在ALPC消息中只是简单地传递一个指针。
对象访问的审计
在很多环境里,审计机制的一个重要应用是维护对受保护对象(特别是文件)的访问日志。要做到这一点,“审计对象访问”策略必须被启用,而且在相关对象的系统访问控制列表(System Access Control List)中必须有审计ACE启用了审计。
当访问者试图打开一个指向某个对象的句柄时,安全引用监视器首先确定该企图是被允许的还是被拒绝的。如果已经启用了对象访问审计,那么SRM接下来就扫描对象的系统ACL。有两种类型的审计ACE:访问被允许和访问被拒绝。一个审计ACE要生成一个对象访问审计记录,它必须匹配访问者持有的任何一个安全ID、必须匹配所请求的任何一个访问方法,并且它的类型(访问被允许或访问被拒绝)必须匹配访问检查的结果。
对象访问的审计记录不仅包含了访问被允许或被拒绝的事实,也包含了访问成功或失败的理由。这个“访问的理由”在一条审计记录中通常的报告形式是一个以SDDL(安全描述定义语言)形式表示的访问控制项。这样,如果有一个对象你认为系统会拒绝对它的访问,但实际上系统却允许他对它的访问,在这种情况下,通过识别出该企图访问成功或失败的访问控制项,审计记录就能让你对这些情形做一下诊断。
实验:对象访问审计
1.在文件的Security->Advnaced->Auditing标签页设置它的审计属性
2.添加Everyone的Full Control到审计列表中
3.启用对象审计
4.打开此文件
5. 在EventViewer中查看审计记录,打开审计记录可以看到访问理由。
全局审计策略
除了单独对象上的对象访问ACE,Windows也允许为启用了对象访问审计的系统定义一个全局的审计策略,为以下对象启用对象访问审计:所有的文件系统对象、所有的注册表键,或者两种都包含。从而一位安全审计员能够确信它所期望的审计将被执行,而不必对它感兴趣的所有对象一个一个的设置或检查SACL。
管理员可以执行auditpol /resourceSACL来设置或查询全局审计策略。
实验:创建全局审计策略
auditpol /resourceSACL /type:File /view
auditpol /resourceSACL /set /type:File /user:Mingzhu /success/failure /access:FW
auditpol /resourceSACL /remove /type:File /user:Mingzhu
高级审计策略设置
作为前面讲的AuditPolicy设置的一个补充,本地安全策略编辑器也提供了一套更细粒度的审计控制,位于高级审计策略配置下。