RACF内部架构
整体角色
z/OS访问控制图
为了深入分析RACF,我们回顾其在z/OS整体架构中的角色及其组件的功能。如上图所示,RACF通常可分为服务组件和数据库。还有其他组件,如用于RACF管理和管理的实用程序,或负责事件日志记录和报告的RACF审计和报告解决方案。然而,对于流程的一般理解,我们认为这些组件并非严格必要。RACF数据库存储有关z/OS用户和配置了访问控制的资源的信息。基于这些数据,RACF服务组件在收到其他z/OS组件和子系统的请求时执行所有必要的安全检查。RACF通常通过系统授权设施(SAF)接口与其他子系统交互。各种z/OS组件使用SAF来授权用户对资源的访问或执行用户请求的操作。值得注意的是,虽然本文重点介绍RACF作为标准安全包的操作原理,但z/OS中也可以使用其他安全包,如ACF2或Top Secret。
让我们考虑在时间共享选项(TSO)子系统内用户授权的示例,该子系统是z/OS的命令行界面等效物。我们使用x3270终端仿真器连接到大型机。在z/OS中成功用户身份验证后,TSO子系统使用SAF查询RACF安全包,检查用户是否有权访问TSO资源管理器。RACF服务查询数据库中的用户信息,这些信息存储在用户配置文件中。如果数据库包含所需访问权限的记录,则用户被授权,并且用户配置文件中的信息被放置到新TSO会话的地址空间内的ACEE(访问者环境元素)控制块中。对于在该TSO会话内随后尝试访问其他z/OS资源,RACF使用ACEE中的信息来做出授予用户访问权限的决定。SAF从ACEE读取数据并将其传输到RACF服务。RACF基于数据库中存储的所请求资源的相关配置文件中的信息,做出授予或拒绝访问的决定。然后该决定被发送回SAF,SAF相应地处理用户请求。对于用户在该TSO会话内进一步尝试访问其他资源或执行命令,查询RACF的过程会重复。
因此,RACF处理z/OS内的用户识别、身份验证和授权,以及授予权限。
RACF数据库组件
如上所述,对z/OS内资源的访问决策是基于存储在RACF数据库中的信息做出的。这些数据以记录的形式保存,或者用RACF术语来说,是配置文件。这些包含有关特定z/OS对象的详细信息。虽然RACF数据库可以保存各种配置文件类型,但四种主要类型对安全分析尤其重要:
- 用户配置文件保存用户特定信息,如登录名、密码哈希、特殊属性和用户所属的组。
- 组配置文件包含关于组的信息,包括其成员、所有者、特殊属性、子组列表以及组成员对该组的访问权限。
- 数据集配置文件存储关于数据集的详细信息,包括访问权限、属性和审计策略。
- 通用资源配置文件提供关于资源或资源类的信息,如资源持有者、他们对资源的权限、审计策略和资源所有者。
RACF数据库包含这些配置文件的众多实例。它们共同形成了z/OS内对象和主体之间复杂的关系结构,作为访问决策的基础。
RACF数据库配置文件的逻辑结构
每个配置文件由一个或多个段组成。不同的配置文件类型利用不同的段类型。
例如,用户配置文件实例可能包含以下段:
- BASE:RACF中的核心用户信息(强制段);
- TSO:用户TSO会话参数;
- OMVS:用户在z/OS UNIX子系统内的会话参数;
- KERB:与z/OS网络认证服务相关的数据,对Kerberos协议操作至关重要;
- 以及其他。
用户配置文件段
不同的段类型通过它们存储的字段集来区分。例如,用户配置文件的BASE段包含以下字段:
- PASSWORD:用户的密码哈希;
- PHRASE:用户的密码短语哈希;
- LOGIN:用户的登录名;
- OWNER:用户配置文件的所有者;
- AUTHDATE:在RACF数据库中创建用户配置文件的日期;
- 以及其他。
PASSWORD和PHRASE字段对安全分析特别感兴趣,我们将在后面深入探讨这些。
RACF数据库结构
值得注意的是,RACF数据库以具有特定格式的专用数据集形式存储。掌握这种格式在分析数据库和映射z/OS对象和主体之间的关系时非常有用。
正如我们在上一篇文章中讨论的,数据集是大型机中文件的等效物,由一系列块组成。
RACF DB结构
上图说明了RACF数据库结构,详细描述了数据块及其偏移量。从RACF DB分析的角度,以及随后确定z/OS对象和主体之间的关系时,最关键的块包括:
- 头块,或库存控制块(ICB),包含各种元数据和指向RACF数据库内所有其他数据块的指针。通过读取ICB,您可以访问其余的数据块。
- 索引块,形成一个单链表,包含指向RACF数据库中所有配置文件及其段的指针——即关于所有用户、组、数据集和资源的信息。
- 模板:一个关键的数据块,包含所有配置文件类型(用户、组、数据集和通用资源配置文件)的模板。模板列出了每个可能段类型在相应配置文件类型中的字段并指定了它们的格式。
在剖析RACF数据库结构后,我们确定需要一个实用程序,能够从DB中提取所有相关的配置文件信息,无论其版本如何。该实用程序还需要将提取的数据以方便的格式保存以供离线分析。执行这种类型的分析提供了特定z/OS安装中所有对象和主体之间关系的全面图景,有助于发现可能导致权限提升或横向移动的潜在安全漏洞。
RACF DB分析实用程序
在前一阶段,我们为RACF DB分析实用程序定义了以下功能要求:
- 能够在不需要在大型机上运行命令的情况下离线分析RACF配置文件
- 能够提取存储在DB中的RACF配置文件的详尽信息
- 与各种RACF DB版本兼容
- 直观导航提取的数据,并可以选择以各种格式呈现:纯文本、JSON、SQL等
现有RACF DB分析解决方案概述
我们首先分析了现成工具,并评估了它们对我们特定需求的潜力:
- Racf2john从RACF数据库中提取使用DES和KDFAES算法加密的用户密码哈希(来自PASSWORD字段)。虽然这是一个不错的起点,但我们需要的不仅仅是PASSWORD字段;具体来说,我们还需要从其他配置文件字段(如PHRASE)中检索内容。
- Racf2sql将RACF DB转储作为输入,并将其转换为SQLite数据库,然后可以使用SQL进行查询。这很方便,但转换过程可能会丢失对z/OS安全评估和识别错误配置至关重要的数据。此外,该工具需要由z/OS IRRDBU00实用程序(RACF安全包的一部分)生成的数据库转储,而不是原始数据库本身。
- IRRXUTIL允许查询RACF DB以提取信息。它也是RACF安全包的一部分。它可以方便地与一组用REXX(z/OS中使用的解释性语言)编写的脚本一起使用。然而,这些脚本需要提升的权限(访问FACILITY资源类中的一个或多个IRR.RADMIN.**资源),并且必须直接在大型机上执行,这不适合手头的任务。
- Racf_debug_cleanup.c直接分析来自数据集副本的RACF DB。一个显著的缺点是它只解析BASE段并以纯文本形式输出结果。
如您所见,现有工具不能满足我们的需求。一些实用程序需要在大型机上直接执行。其他工具操作数据集副本并从DB中提取不完整的信息。此外,它们依赖于配置文件段内的硬编码偏移量和签名,这些可能因RACF版本而异。因此,我们决定开发自己的RACF数据库分析实用程序。
介绍racfudit
我们用Golang编写了自己的平台无关实用程序racfudit,并在各种z/OS版本(1.13、2.02和3.1)上进行了测试。下面,我们深入探讨新工具的操作原理、功能和优势。
从RACF DB提取数据
为了离线分析RACF DB信息,我们首先需要一种提取结构化数据的方法。我们为此开发了一种两阶段方法:
- 第一阶段涉及分析存储在RACF DB内的模板。每个模板描述特定的配置文件类型、其组成段以及这些段内的字段,包括它们的类型和大小。这使我们能够获得最新的配置文件类型、其段和相关字段的列表,无论RACF版本如何。
- 在第二阶段,我们遍历所有索引块以从RACF DB中提取每个配置文件及其内容。然后使用在第一阶段获得的模板处理和解析这些收集的配置文件。
第一阶段至关重要,因为RACF DB配置文件以非结构化字节数组的形式存储。模板定义了如何根据其类型处理每个特定配置文件(字节数组)。
因此,我们定义了以下算法来提取结构化数据。
使用模板从RACF DB提取数据
- 我们从大型机卸载RACF DB并读取其头块(ICB)以确定模板的位置。
- 基于每种配置文件类型的模板,我们定义了一种算法,用于根据其类型构建特定配置文件实例的结构。
- 我们使用头块的内容来定位索引块,这些块存储指向所有配置文件实例的指针。
- 我们从索引块列表中顺序读取所有配置文件实例及其段。
- 对于我们读取的每个配置文件实例及其段,我们应用基于相应模板的处理算法。
- 所有处理的配置文件实例以中间状态保存,允许未来以各种格式存储,如纯文本或SQLite。
这种方法的优点是其版本独立性。即使模板和索引块在RACF版本中改变其结构,我们的实用程序也不会丢失数据,因为它基于相关模板动态确定每种配置文件类型的结构。
分析提取的RACF DB信息
我们的racfudit实用程序可以将收集的RACF DB信息呈现为SQLite数据库或纯文本文件。
RACF DB信息作为SQLite DB(顶部)和文本数据(底部)
使用SQLite,您可以执行SQL查询以识别RACF中的错误配置,这些配置可能被利用进行权限提升、横向移动、绕过访问控制或其他渗透测试策略。值得注意的是,用于在SQLite中处理信息的SQL查询集可以适用于根据安全标准和最佳实践验证当前的RACF设置。让我们看一些具体示例,说明如何使用racfudit实用程序来发现安全问题。
收集密码哈希
渗透测试的主要目标之一是获取管理员列表以及使用其凭据进行授权的方法。这对于在大型机上维持持久性、横向移动到其他大型机,甚至转移到运行不同操作系统的服务器都很有用。管理员通常位于SYS1组及其子组中。下面的示例显示了一个查询,用于检索SYS1组中特权用户的密码(PASSWORD)和密码短语(PHRASE)的哈希。
|
|
当然,要登录系统,您需要破解这些哈希以恢复实际密码。我们在下面更详细地介绍了这一点。
搜索数据集中不充分的UACC控制
通用访问权限(UACC)定义了数据集的默认访问权限。此参数指定所有没有配置特定访问权限的用户的访问级别。如果对包含敏感数据的数据集或APF库设置了提升的访问权限(UPDATE或更高),则对UACC值的控制不足可能构成重大风险,这可能允许权限提升。下面的查询有助于识别具有默认ALTER访问权限的数据集,这些权限允许用户读取、删除和修改数据集。
|
|
UACC字段不仅存在于数据集配置文件中;它也存在于其他配置文件类型中。此字段配置中的弱控制可能使渗透测试者能够访问资源。
RACF配置文件关系
如前所述,各种RACF实体具有关系。有些是明确定义的;例如,用户名可能列在组配置文件的成员字段(USERID字段)中。然而,也存在隐式关系。例如,如果用户组对特定数据集具有UPDATE访问权限,则该组的每个成员隐式具有对该数据集的写访问权限。这是隐式关系的一个简单示例。接下来,我们深入探讨RACF数据库中更复杂和特定的关系,渗透测试者可以利用这些关系。
RACF配置文件字段
深入探讨RACF内部架构发现,在各种场景中,访问权限和其他属性的错误配置可能难以检测和修复。这些看似微小的错误可能至关重要,可能导致大型机泄露。RACF数据库中的显式和隐式关系共同定义了大型机当前的安全状况。如前所述,RACF数据库中的每种配置文件类型都具有唯一的字段和属性集,用于描述配置文件如何相互关联。基于这些字段和属性,我们编制了关键字段列表,这些字段有助于构建和分析关系链。
-
用户配置文件字段
- SPECIAL:指示用户有权执行任何RACF命令,并授予他们对RACF数据库中所有配置文件的完全控制。
- OPERATIONS:指示用户是否有权访问DATASET、DASDVOL、GDASDVOL、PSFMPL、TAPEVOL、VMBATCH、VMCMD、VMMDISK、VMNODE和VMRDR类的所有RACF保护资源。虽然指定了此字段的用户的操作受到某些限制,但在渗透测试上下文中,OPERATIONS字段通常表示完全的数据集访问权限。
- AUDITOR:指示用户是否有权访问审计信息。
- AUTHOR:用户的创建者。它对用户具有某些特权,例如更改其密码的能力。
- REVOKE:指示用户是否可以登录系统。
- 密码TYPE:指定密码和密码短语的哈希类型(DES或KDFAES)。此字段并非本机存在于用户配置文件中,但可以根据不同密码和密码短语的存储方式创建。
- Group-SPECIAL:指示用户是否对由组或组字段定义的范围内的所有配置文件具有完全控制。这是一个特别有趣的字段,我们在下面更详细地探讨。
- Group-OPERATIONS:指示用户是否有权访问由组或组字段定义的范围内的DATASET、DASDVOL、GDASDVOL、PSFMPL、TAPEVOL、VMBATCH、VMCMD、VMMDISK、VMNODE和VMRDR类的所有RACF保护资源。
- Group-AUDITOR:指示用户是否有权访问由组或组字段定义的范围内的审计信息。
- CLAUTH(类权限):允许用户在指定类或类中创建配置文件。此字段允许委派单个类的管理权限。
- GROUPIDS:包含用户所属的组列表。
- UACC(通用访问权限):定义用户创建新配置文件时的UACC值。
-
组配置文件字段
- UACC(通用访问权限):定义用户连接到组时创建的新配置文件的UACC值。
- OWNER:组的创建者。所有者对当前组及其子组具有特定特权。
- USERIDS:组内的用户列表。顺序很重要。
- USERACS:具有各自访问组权限的组成员列表。顺序很重要。
- SUPGROUP:上级组的名称。
-
通用资源和数据集配置文件字段
- UACC(通用访问权限):定义对资源或数据集的默认访问权限。
- OWNER:资源或数据集的创建者,对其持有某些特权。
- WARNING:指示资源或数据集是否处于WARNING模式。
- USERIDS:与资源或数据集关联的用户ID列表。顺序很重要。
- USERACS:具有对资源或数据集访问权限的用户列表。顺序很重要。
RACF配置文件关系链
上面列出的字段证明了RACF配置文件之间存在关系。我们决定将这些关系命名为类似于BloodHound中使用的名称,BloodHound是一种用于分析Active Directory错误配置的流行工具。以下是一些这些关系的示例——列表并非详尽无遗。
- Owner:主体拥有对象。
- MemberOf:主体是对象的一部分。
- AllowJoin:主体有权将自己添加到对象。
- AllowConnect:主体有权将另一个对象添加到指定对象。
- AllowCreate:主体有权创建对象的实例。
- AllowAlter:主体对对象具有ALTER特权。
- AllowUpdate:主体对对象具有UPDATE特权。
- AllowRead:主体对对象具有READ特权。
- CLAuthTo:主体有权在CLAUTH字段中定义的对象中创建实例。
- GroupSpecial:主体对由group-SPECIAL字段定义的对象的影晌范围内的所有配置文件具有完全控制。
- GroupOperations:主体有权执行与由group-OPERATIONS字段定义的对象相关的某些操作。
- ImpersonateTo:主体授予对象代表主体执行某些操作的特权。
- ResetPassword:主体授予另一个对象重置指定对象密码或密码短语的特权。
- UnixAdmin:主体在z/OS UNIX中授予对象超级用户特权。
- SetAPF:主体授予另一个对象在指定对象上设置APF标志的特权。
这些关系在构建主体-对象互连图时作为边。下面是特定配置文件类型之间潜在关系的示例。
RACF配置文件之间的关系示例
可视化和分析这些关系帮助我们识别了描述潜在RACF安全问题的特定链,例如从低权限用户到高权限用户的路径。在我们深入探讨这些链的示例之前,让我们考虑RACF数据库实体之间关系的另一个有趣且独特的特征。
隐式RACF配置文件关系
我们观察到用户配置文件中的group-SPECIAL、group-OPERATIONS和group-AUDITOR字段的一个迷人特征。如果用户在任何这些字段中指定了组,则该组的影晌范围扩展了用户自己的范围。
具有group-SPECIAL字段的用户的影响范围
例如,考虑USER1在group-SPECIAL字段中指定了GROUP1。如果GROUP1拥有GROUP2,而GROUP2随后拥有USER5,则USER1获得对USER5的特权。这不仅仅是关于数据访问;USER1实质上成为USER5的所有者。z/OS的一个独特方面是,这种访问级别允许USER1,例如,更改USER5的密码,即使USER5持有特权属性,如SPECIAL、OPERATIONS、ROAUDIT、AUDITOR或PROTECTED。
下面是一个使用racfudit实用程序生成的SQL查询,用于识别指定用户拥有特殊属性的所有用户和组:
|
|
这是一个查询,用于查找所有者(AUTHOR)不是标准默认管理员的用户:
|
|
让我们说明如何通过这些隐式配置文件关系提升用户权限。
通过group-SPECIAL字段提升权限
在此场景中,用户TESTUSR的group-SPECIAL字段