Skip to main content

跨域理论

当我们最终接管了当前域,接下来要做的便是占领更多的域,主要通过利用域信任以及其他的不当配置来实现。在那之前,我们需要熟悉一些跨域理论相关的名词,因为跨域理论较为复杂,涉及到的理论知识比较多。


概念与名词

域信任

域信任是 AD 的一个关键组件,它使一个域中的用户能够对另一个域中的系统和资源进行身份验证和访问。理解域信任的几个方面很重要,包括信任的方向和对资源的访问。信任的方向可以是单向的,也可以是双向的。单向信任是在两个域之间创建的单向身份认证路径,如果域 A 信任域 B,则域 B 中的用户可以访问域 A 中的资源。但是,域 A 中的用户不能访问域 B 中的资源,单向信任发生在不同的森林之间。双向信任是相互的信任,每个域中的用户都可以访问另一个域中的资源。因此,如果域 A 和域 B 之间存在双向信任,则域 A 中的用户可以访问域 B 中的资源,反之亦然。双向信任必定建立在在同一片森林里,可能建立在不同的森林间。尽管信任决定着资源访问的方向,但在建立信任后,域信任不会自动授予来自受信任域的用户访问信任域中所有资源的权限,对资源的实际访问受权限和组成员身份以及特权有关。

image.png

信任还可以根据传递性进行分类。传递信任则是,如果域 A 信任域 B,域 B 信任域 C,则域 A 信任域 C。

image.png

那么非传递信任 (单向或双向) 仅限于信任关系中的两个域。在同一森林内,任意域都是双向信任可传递的。但在森林之间,则默认不成立,例如 森林 A 信任森林 B,森林 B 信任 森林 C,但森林 A 不信任 森林 C,森林 A 甚至不知道森林 C 的存在。

image.png

例如,在我们靶场里,white-bird 域与 raven-med 域相互信任,med-factory 域信任 raven-med 域,但是 med-factory 的信任不能间接延续到 white-bird 域。但是,互相信任的森林各自之中的子域则可以互相访问,因为 prod 域是 raven-med 的子域,因此 white-bird 域与 prod 域也是互相信任,med-factory 域也单向信任 prod 域。

域管理员与企业管理员

这是 AD 中的两个高特权分组,域管理员仅对其特定域具有管理权限,而企业管理员对森林中所有域具有管理访问权限。下图分别是 PROD 与 RAVEN-MED 中 administrator 的信息,我们发现只有 RAVEN-MED\Administrator 属于企业管理员分组。

image.png

image.png


外部安全主体

AD 中的外部主体对象表示来自受信任的外部域的安全主体,这用于将受信任域中的用户或组添加到信任域中的安全组。例如在 Med-factory 域中 (Med-factory 信任 Raven-med),Administrators 组内有个外部成员,该成员为 Raven-med 中的 ExtAdmin 组。

image.png

 

SID 历史

SID history 是一个适用于迁移场景的属性,当用户、组或其他安全主体对象从一个域移动到另一个域时,会为该对象分配一个新的 SID,但旧的 SID 会存储在 SID History 属性中,这允许安全主体在迁移后通过添加他们以前的 SID 来保持对以前域中资源的访问。


额外 SID

在 TGT中,存储用户登录信息以及权限的 KERB_VALIDATION_INFO 结构体中有一个属性为 ExtraSids,该属性可以为我们在另一个域中获得访问,这可能发生在域迁移期间或使用 SID 历史功能时。

 typedef struct _KERB_VALIDATION_INFO {
    FILETIME LogonTime;
    FILETIME LogoffTime;
    FILETIME KickOffTime;
    FILETIME PasswordLastSet;
    FILETIME PasswordCanChange;
    FILETIME PasswordMustChange;
    RPC_UNICODE_STRING EffectiveName;
    RPC_UNICODE_STRING FullName;
    RPC_UNICODE_STRING LogonScript;
    RPC_UNICODE_STRING ProfilePath;
    RPC_UNICODE_STRING HomeDirectory;
    RPC_UNICODE_STRING HomeDirectoryDrive;
    USHORT LogonCount;
    USHORT BadPasswordCount;
    ULONG UserId;
    ULONG PrimaryGroupId;
    ULONG GroupCount;
    [size_is(GroupCount)] PGROUP_MEMBERSHIP GroupIds;
    ULONG UserFlags;
    USER_SESSION_KEY UserSessionKey;
    RPC_UNICODE_STRING LogonServer;
    RPC_UNICODE_STRING LogonDomainName;
    PISID LogonDomainId;
    ULONG Reserved1[2];
    ULONG UserAccountControl;
    ULONG SubAuthStatus;
    FILETIME LastSuccessfulILogon;
    FILETIME LastFailedILogon;
    ULONG FailedILogonCount;
    ULONG Reserved3;
    ULONG SidCount;
    [size_is(SidCount)] PKERB_SID_AND_ATTRIBUTES ExtraSids;
    PISID ResourceGroupDomainSid;
    ULONG ResourceGroupCount;
    [size_is(ResourceGroupCount)] PGROUP_MEMBERSHIP ResourceGroupIds;
 } KERB_VALIDATION_INFO, *PKERB_VALIDATION_INFO;


信任密钥 (跨域密钥)

我们刚才说了 ExtraSids,而其技术实现则是通过信任密钥,即 trust key。2个域中,因为都有各自的 krbtgt 账户及对应的 NTLM 哈希,这 2 个域互相不知道对方域中的密码哈希,因此域 B 无法解密来自域 A 的 TGT,因此信任密钥应运而生,域 A 与域 B 需要共同的密钥。而实现方法则是,以上图的 red.local 以及 child1.red.local 为例,域 red.local 中存在 child1$的 的主机账号(虽然这样的主机并不存在),而 child1.red.local 中存在 red$ 的主机账号。这 2 个主机账号实为信任帐号,并且它们的哈希是一致的。我们可以通过 dcsync 获得它们的哈希,更详细的利用方法在下文继续。


跨域 TGT

在 Kerberos 身份认证的上下文中,当一个域中的用户需要访问另一个域中的服务时,将使用跨域 TGT (Inter-realm TGT)。用户所在域与服务所在域共享该跨域 TGT,以允许对用户进行身份验证。

SID 过滤器

在森林之间的信任中,存在着 SID 过滤器的概念。因此,上文提到的 Extrasids 在森林之间的信任中被过滤了,组成员归属不再被盲目信任。例如,来自 red.local 的 TGT 在到达 sec.local 的时候,ExtraSids 会被移除。启用 SID 历史可以一定程度缓解 SID 过滤器的作用,但是无论如何,任何 RID 小于 1000 的 SID 都会被无条件过滤,而无论是域管理员还是企业管理员,其 RID 都是 500+,因此我们无法从森林 A 的 DC 直接移动到森林 B 的 DC。但是,如果我们具有一定特权的自定义的域组,那么会是我们转移到另一个森林的突破口。举个实际例子,森林 B 中的域组 "Server Admin" 显然是自定义的组,该组成员可以以本地管理员权限访问森林 B 中的所有服务器主机,那么我们可以以 Server Admin 组的 SID 作为 ExtraSids。

image.png




 

跨域理论

image.png

AS-REQ - 向当前域的域控制器请求 TGT。
AS-REP - TGT 返回给认证用户
TGS-REQ - 请求访问目标域中某服务的 TGS
TGS-REP - 当前域没有目标域 krbtgt 的密钥,因此返回的是使用跨域密钥加密的跨域 TGT。
TGS-REQ - 跨域 TGT 被传递到目标域,请求特定服务
TGS-REP - 跨域 TGT 被跨域密钥解密和验证,然后 TGS 被返回。