中国联合网络通信有限公司哈尔滨软件研究院黑龙江哈尔滨150040
摘要:文章首先提出了通过分析和使用Windows注册表相关的操作来实现对复杂管理模板策略的状态获取、状态设置的可行性,然后对复杂管理模板策略的状态变更进行注册表跟踪分析,最后结合Windows系统相关API给出具体的实现流程和操作,并依据代码实测结果证实其稳定性与可靠性。
关键字:注册表;组策略;管理模板策略
1引言
Windows的安全配置和Windows操作系统用户使用环境的高级配置最常用的方法之一就是使用Windows组策略,对于Windows7和WindowsServer2008R2,仅操作系统就有超过3700个设置[1]。虽然Windows为我们提供了组策略管理器来方便的管理和配置计算机环境,但是由于相关软件开发工作的需求,很多时候需要自己编写应用程序来对组策略进行操作。在大多数情况下组策略是将设置推送到计算机的注册表中来配置安全设置和其他操作行为[2]。有些简单的组策略可以按照注册表路径找到键,然后对值直接修改生效;但是对于占很大比重的管理模板组策略却需要更复杂的操作来完成,过程分析复杂,实现难度大,由于涉及系统安全等诸多因素,微软官方相关资料也比较少。作为Windows系统安全研究和程序开发人员,对复杂管理模板组策略的程序实现的分析和研究有着十分重要的价值和意义。
2Windows注册表
Windows的注册数据库,又称为注册表,就像是一个核心的系统信息库[3],存储着硬件、操作系统、应用程序和用户等各个方面的系统信息,同时可以通过软件被用户访问和更改数据。注册表将数据存储在结构鲜明的树型层次结构中。其中的每个节点被称为“键”。每个“键”都可以包含其他键称为“子键”[4]。结构如图1所示:
图1Windows注册表树状结构
微软为Windows注册表的程序操作提供了一系列API,这些API被封装在Kernel32.dll链接库文件中,使用时只需引入头文件Windows.h即可。这些WindowsAPI可以很方便的对简单的注册表项进行访问和更改,这些函数的具体用法可以在微软官方说明中获得:https://docs.microsoft.com/en-us/windows/desktop/sysinfo/registry-functions。界面如图2所示:
图2微软官网提供的操作Windows注册表的高级系统API
3Windows组策略
在Windows系统中一部分系统桌面、安全和应用可以通过手动设置来完成,但是像系统服务访问控制列表和详细的IP安全配置这些无法通过手动来配置的,那么便只能通过Windows系统中的组策略来实现。组策略可以理解成一组系统配置规则,控制着系统的每个区域。Windows组策略结构图如图3所示:
图3Windows组策略结构图
组策略的设置基本涵盖了每一个注册表的操作,比如:浏览器、桌面、开始菜单等,通过组策略的设置,我们能够在系统中部署、管理、更新、控制、删除软件应用程序,能够控制服务器系统中用户磁盘分配,能够对系统数据进行加密,能够为系统管理员提供文件夹重定向操作来备份和回滚数据来保证数据的安全[5],能够对浏览器进行设置来保证对web安全和高效的访问,同时也能够为用户提供一系列的保证IP安全的设置步骤和系统安全设置,比如:权限验证、网络访问、用户登录和安全沟通等[6]。
管理模板策略则提供了一系列范围更广的系统设置,涵盖了绝大部分的系统设置,用于集中管理ActiveDirectory环境中的计算机和用户。管理模板有助于管理基于注册表的策略[7]。ADM文件用于描述提供给组策略管理员的用户界面和应在目标计算机上更新的注册表项。ADM文件是具有特定语法的文本文件,该文件描述了在启用或禁用策略时将更改的接口和注册表值。ADM文件由组策略对象编辑器(GPEdit)使用,Windows附带了以下ADM文件system.adm、inetres.adm、wmplayer.adm、conf.adm和wuau.adm。它们在GPEdit中合并为统一的“命名空间”,并在管理模板节点下呈现给管理员(对于计算机和用户策略)[8]。
4复杂管理模板策略的分析和实现
在Windows中有很多的管理模板策略条目,按照这些策略所关联的注册表的复杂程度,可以把这些组策略条目分成2种类型:简单管理模板策略和复杂管理模板策略。简单管理模板策略所关联的注册表一般只有2个,此类组策略的设置选项一般只包含三种状态:未配置、已启用和已禁用。而复杂管理模板策略一般会关联2个以上的注册表,并且其设置选项除了未配置、已启用和已禁用外,还会在已启用中包含更多的选项设置,这通常会关联到更多的注册表。
在复杂管理模板策略中,选择“设置客户端连接加密级别”这条策略来举例,该项所在路径为:本地计算机策略->计算机配置->管理模板->Windows组件->远程桌面服务->远程桌面会话主机->安全,此策略设置指定在远程桌面协议(RDP)连接期间是否要求使用特定加密级别来保证客户端计算机和远程桌面会话主机服务器之间的通信安全。如果启用此设置,则在远程连接期间,客户端和远程会话主机服务器之间的所有通信必须使用该设置中指定的加密方法,会附带“加密级别”设置:高级别、低级别和客户端兼容。其中“高级别”设置对客户端与服务器之间传送的数据使用128位的强加密进行加密;“客户端兼容”设置对在客户端和服务器之间传送的数据以客户端支持的最大密钥强度进行加密;“低”设置仅对由客户端发送到服务器的数据使用56位加密进行加密;如果“禁用”或“未配置”此设置,则不会通过“组策略”强制使用用于连接到远程会话主机服务器的加密级别。通过https://getadmx.com/?Category=Windows_7_2008R2&Po
licy=Microsoft.Policies.TerminalServer::TS_ENCRYPTION_POLICY链接可以在线查找当前策略所依赖的注册表项如图4所示:
图4“设置客户端连接加密级别”策略所依赖的注册表项
通过使用软件Regshot2.0来监视这条组策略设置前后注册表的变化,找到了解决问题的方法。1.策略状态由“未配置”转为“已禁用”时,新增注册表键和值如图5、图6所示:
图5“未配置”转为“已禁用”,注册表状态的变化
图6“未配置”转为“已禁用”,注册表的键和值
新增键HKEY_CURRENT_USER\Software\Microsoft\Windows\Current
Version\GroupPolicyObjects\{60798545-BC47-46F5-910E-9756EE3CBB74}
Machine\SOFTWARE\Policies\Microsoft\WindowsNT\TerminalServices,并在该键下新增RG_SZ类型值“**del.MinEncryptionLevel”=“”。2.当状态由“已禁用”转换成“已启用”+“加密级别”-“高级别”时,我们可以看到两个最主要的变化如图7所示:
图7“已禁用”转换成“已启用”+“加密级别”-“高级别”,注册表状态的变化
之前路径下的值“**del.MinEncryptionLevel”=“”已经被删除,同时新增值DWORD类型值"MinEncryptionLevel"=3,进一步将状态分别设置成“低级别”和“客户端兼容”,"MinEncryptionLevel"值分别为1和2。3.当状态由“已启用”+“加密级别”-“高级别”转换成“已禁用”时,如图8所示:"MinEncryptionLevel"=3已经被删除,同时新增值RG_SZ类型值“**del.MinEncryptionLevel”=“”。
当状态由“已启用”+“加密级别”-“高级别”转换成“未配置”时,如图9和图10所示:我们可以看到SOFTWARE键以及"MinEncryptionLevel"=3已经被删除。
图8“已启用”+“加密级别”-“高级别”转换成“已禁用”,注册表状态的变化
图9“已启用”+“加密级别”-“高级别”转换成“未配置”,注册表状态的变化
图10“已启用”+“加密级别”-“高级别”转换成“未配置”,键和值状态的变化
根据以上组策略状态转换及相关注册表项变化过程分析,可以给出该条组策略的状态转换方法流程图11:
图11组策略状态转换及相关键值状态的变化
由于该类组策略状态转换过程中新生成键,比如[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\GroupPolicyObjects\{60798545-BC47-46F5-910E-9756EE3CBB74}Machine\SO
FTWARE]中的{60798545-BC47-46F5-910E-9756EE3CBB74}部分为系统随机生成的GUID值,直接获取该值比较困难,因此不考虑通过普通注册表的操作方法。现给出C++程序设计过程代码:
查询当前该条组策略状态的具体步骤:1.通过自己定义函数调用AdjustTokenPrivileges()函数提取Windows系统权限;2.通过调用函数CoCreateInstance()实例化IGroupPolicyObject的对象;3.通过IGroupPolicyObject的实例化对象调用函数OpenLocalMachineGPO()和GetRegistryKey()获取机器的HKEY;4.通过之前所给定的网站查询到该条组策略所关联的REG_DWORD类型值MinEncryptionLevel,调用RegOpenKeyEx()函数和RegQueryValueEx()函数来获取MinEncryptionLevel的值,如果该值存在为3,2,1,则对应当前该条组策略状态为“已启用-高级别”、“已启用-客户端兼容”和“已启用-低级别”;如果MinEncryptionLevel的值不存在,则调用函数RegQueryValueEx()来获取RG_SZ类型的值“**del.MinEncryptionLevel”,如果该值不存在,则当前状态为“未配置”;如果该值存在,则当前状态为“已禁用“,然后通过RegCloseKey()函数释放HKEY类型的资源。
如果要对状态进行设置,则:设置成”未配置“状态:调用RegOpenKeyEx()函数和RegDeleteValue()函数删除”MinEncryptionLevel“和“**del.MinEncryptionLevel”值。
设置成“已启用”状态:首先调用RegOpenKeyEx()函数查案看是否能打开“MinEncryptionLevel“值所在路径,如果其返回值为ERROR_SUCCESS,则表明该值所在路径存在,可以调用RegSetValueEx()函数设置该值为3,2,1,对应“已启用-高级别”、“已启用-客户端兼容”和“已启用-低级别”三种状态;如果其返回值不为ERROR_SUCCESS,则表明”MinEncryptionLevel“值所在路径不存在,则需调用RegCreateKeyEx()函数新建路径,然后通过RegSetValueEx()函数设置该值为3,2,1。
设置成“已禁用状态”,首先调用RegOpenKeyEx()函数查案看是否能打开“MinEncryptionLevel“值所在路径,如果其返回值为ERROR_SUCCESS,则表明该值所在路径存在,调用RegQueryValueEx()函数查看”MinEncryptionLevel“值是否存在,若存在,调用RegDeleteValue()函数删除该值;若不存在,则调用RegSetValueEx()函数设置“**del.MinEncryptionLevel”值为“”。如果其返回值不为ERROR_SUCCESS,则表明”MinEncryptionLevel“值所在路径不存在,则需调用RegCreateKeyEx()函数新建路径,然后通过RegSetValueEx()函数设置“**del.MinEncryptionLevel”值为“”。最后通过IGroupPolicyObject的对象调用Save()函数来保存设置结果,并调用Release()函数释放资源。至此查询该条组策略状态和设置状态过程结束。
5结束语
本文详细的介绍了Windows组策略中,管理模板策略的实现,所关联