域林渗透基础知识
什么是windows域
一个通俗的例子:假设有⼀堆图书,没⼈管理,⼀个班的同学能够随意借阅这些书。由于缺乏管理,图书可能会遇到各种各样的问题,⽐如图书破损、丢失等等。为了解决这个问题,班上设⽴⼀个图书管理员,他负责分配、管理这些图书,任何想借书的⼈都需要向他申请。类⽐这个例⼦,⼀个集体拥有⼀些计算机资源,如果没有⼀个统⼀的管 理系统,每个⼈都能随意操作这些计算机,就会使运维的成本变⾼,为了解决这个问题,我们也可以像管理图书⼀ 样设⽴⼀个管理员,由它来统⼀管理计算机。那么这套体系可以称为⼀个域,域控制器就充当了管理员的⻆⾊,任何加⼊域的计算机都需要服从管理员的管理。
基本概念
活动目录
活动目录是一种目录结构。目录就跟电话簿一样,在需要联系某人的时候就可以在里面检索。windows中的活动目录建立了一种资源和地址的对应关系,类比于电话簿中联系人与其对应的电话号码。
根域
把域的结构想象成一颗树。一颗树的生长是从根开始的。因此,网络中创建的第一个域就是根域,一个域林中只能有一个根域,根域对其他域具备最高管理权限。
域树
域树由多个域组成,这些域形成一个连续的名字空间(相同的dns后缀)。树中的域通过信任关系连接,林包含了一个或多个域。域树中的域层次越深级别越低,一个”.”代表一个层次。比如tree1.tree.com
就比tree.com
低,并且是tree.com
的子域(反之为父域)
域林
创建根域时默认建立一个域林,同时也是整个林的根域,其域名也是林的名称。域树必须建立在域林下,一个域林可以有很多棵域树。已经存在的域不能加入到一个树中,也不能将一个已经存在的域树加入到一个域林中。
DNS
DNS就是域名系统,它可以建立一种ip和名称的关系,DNS服务是windows域能够工作的关键。没有dns,域中的计算机就没办法在逻辑上找到域的管理机(就是域控),尽管它们可能在物理上是相连的。(定位域内DNS服务器或时间服务器,可定位到域控主机)
域控制器
域控制器是运行windows操作系统并承载Active Diretory
的计算机。
只读域控制器
只读域控制器RODC是主机完整域的附加域控制器,存储Active Diretory
数据库分区的只读副本和SYSVOL
文件夹内容的只读副本。
(主要用来存储和域相关的数据,包括组策略设置、脚本等。如果域内部署多台域控制器,所有域控制器之间通过FRS或DFS-R服务相互复制,最终所有域控制器之间完成同步。)
信任关系
- 信任类型
- 信任方向
- 信任传递性
什么是信任?为什么要在域之间建立信任关系?
域是安全边界,若无信任关系,域用户账户只能在本域内使用。
信任关系在两个域之间架起了一座桥梁,使得域用户账户可以跨域使用。
确切的来说就是信任关系使一个域的DC可以验证其他域的用户,这种身份验证需要信任路径。例如:A域与B域没有信任关系,A域上的员工使用自己在A域的账户,不能访问B域上的资源。
总之,两个域之间只有建立适当的信任关系后才可以实现互相访问,这就像两个国家之间要进行友好往来需要建立外交关系一样。
信任的方向
信任是有方向的,信任的方向决定了资源访问的方向。
例如,如果a域信任b域,那么b域中的用户就可以访问a域中的资源。在windows server 2003 中默认建立的信任关系都是双向的,手工建立的则可以根据访问需要建立单项或双向的信任关系。
单向信任:单向信任是在两个域之间创建的单向身份验证路径。
双向信任:双向信任是在两个域之间创建的双向身份验证路径。林中的所有域信任都是双向、可传递的信任。
所有信任关系中只能有两个域:信任域和受信任域。
有一个信任关系(单向信任):A域信任B域,其中A域是信任域,B域是受信任域,这个信任关系指明B域是受A域信任的域,即B域的用户账户可以访问A域的资源(在拥有相应权限的前提下)。从这里我们可以看出,信任关系具有方向性,这个信任关系是单向信任,B域的用户可以访问A域的资源,但A域的用户还不能访问B域的资源。
还有一种信任关系(双向信任):A域和B域之间的双向信任(A域信任B域,且B域信任A域),在这种信任关系下,A域和B域的用户账户都能访问对方域的资源,因为这两个域都得到了对方域的信任。
信任的传递性
信任根据它的传递性可以分为可传递的和不可传递的。
如果A域和B域之间的信任是可传递的,B域和C域之间的信任也是可传递的,那么A域和C域之间就自动创建了信任关系。
如果A域和B域之间的信任是不可传递的,或者B域和C域之间的信任是不可传递的,那么A域和C域之间不会自动创建了信任关系。
从本质上讲,”信任”所做的就是链接两个域之间的认证系统,并允许认证流量通过一个引用系统在这两个域之间传输。如果用户请求访问当前所在域之外的资源的服务主体名称(SPN),则其域控制器将返回一个特殊的引用票证,该票证指向外部域的密钥分发中心(KDC)
用户的票证授予票证(TGT)包含在该TGT-REP(票证授予服务回复)转介票证中,并且该票证用域先前交换的域间信任密钥加密或签名,而不是第一个域的krbtgt账户。这个票证通常被称为”域间票证授予票证或TGT”。然后,外部域通过使用先前协商的域间信任密钥来解密它,然后验证或解密包含在转介票证中的TGT,并且完成正常Kerberos处理过程的其余部分。
因此,基本上,当外部域使用协商的信任密钥解密转介票证时,它看到用户的TGT会说”ok,另一个域已经认证了这个用户,并且说这个用户是谁(注意这里是用户自己说它们是谁)或者是这些用户是哪个用户组的,所以我会相信这个信息是准确的,因为我相信转介的域。”
建立信任的目的是允许来自一个域的用户访问资源(比如服务器上的本地管理员组),以组的形式嵌套,或者用作另一个域的安全主体。林内信任的一个例外是:林中创建的任何域与林中的每个其他域都保持着隐式的双向可传递信任关系。
信任类型
信任类型 | 传递性 | 方向 | 描述 |
---|---|---|---|
外部 | 不可传递 | 单向或双向 | 使用外部信任可提供对位于Windows NT4.0域上的资源或林信任未连接的单独林中域上资源的访问权限。 |
领域 | 可传递或不可传递 | 单向或双向 | 使用领域信任可在非Windows Kerberos领域和Active Directory域之间形成信任关系。 |
林 | 可传递 | 单向或双向 | 使用林信任共享林间的资源。如果林信任是双向信任,在任一林中发出的身份验证请求都可以到达另一个林 |
快捷方式 | 可传递 | 单向或双向 | 使用快捷方式信任改善在一个Active Directory林中两个域之间的用户登录时间。 |
父子信任关系:父子信任关系也就是指同一个林的一部分,子域保留了与父域的隐式双向传递信任。也是遇到的最常见的信任类型。
交叉链接信任关系:交叉链接信任关系又叫做子域之间的”快捷方式信任”,目的是提升转介时间。通常情况下,复杂的林中的引用必须过滤到林根,然后再回到目标域,因此对于地理上分散的那种场景,交叉链接关系可以减少认证的时间。
外部信任关系:在不同域之间创建的隐式非传递性信任关系。“外部信任提供了对尚未加入林信任的林之外的域中资源的访问能力”外部信任强制执行SID过滤。
树根信任关系:林根域和你添加的新树根之间的隐式双向可传递信任关系。
林信任关系:一个林根域和另一个林根域之间的传递信任关系。林信任也强制SID过滤。
MIT信任关系:与非Windows RFC4120兼容的Kerberos域的信任。
如何枚举信任?
枚举信任有三种主要方法:Win32 API调用,各种.NET方法和LDAP。每个方式返回一组不同的信息,每个方式又有不同的执行方法。
.NET方法
.NET方法为我们提供了一些封装的很好的方法,可以枚举出一大堆的域和林信任信息。
[System.DirectoryServices.ActiveDirectory.Domain]
命名空间具有 GetCurrentDomain()
⽅法,这个⽅法返回了 ⼀个静态⽅法 System.DirectoryServices.ActiveDirectory.Domain
类实例。这个类实现了 GetAllTrustRelationships()
⽅法,这个⽅法可以很好地“ 检索该域的所有信任关系。”这种⽅法的优点是利⽤⾮常的 简单 ——信息以易于阅读和理解的⽅式进⾏输出。缺点是它不包含其他枚举⽅法产⽣的⼀些附加信息。
1 | ([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).GetAllTrustRela |
因为此.NET方法默认情况下不会返回林信任,而LDAP枚举则会返回很多额外的信息。所以在使用Powerview时为了执行这个方法,需要运行GET-DomainTrust-NET
林信任在功能上与域信任不同。所以如果你想枚举任何当前的森林->林信任,你需要调用[System.DirectoryServices.ActiveDirectory.Forest]
这个命名空间。⽣成的林对象也有⾃⼰的 GetAllTrustRelationships()
⽅法,它将返回任何当前林的信任关系:
1 | ([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()).GetAllTrustRela |
这是作为powerview的Get-ForestTrust
方法的默认枚举实现。
Win32API
通过使用返回DS_DOMAIN_TRUSTS
结构的DsEnumerateDomianTrusts()
这个Win32 API调用来枚举信任。虽然输出的信息比.NET方法稍微复杂一点,但它会返回了目标域的SID和GUID,以及一些有用的标志和属性。标志和属性可以从以下链接中了解:
DsEnumerateDomainTrustsA function (dsgetdc.h) - Win32 apps | Microsoft Docs
使用Get-DomainTrust-API
调用此方法:
LDAP
域信任在AD中存储为具有TrustedDomain的objectClass的”受信任的域对象”。这意味着你可以使用任何LDAP查询方法来查找有关使用LDAP过滤器存在的任何域信任的信息。
这里是dsquey的执行方式(仅适用于Windows服务器):
1 | dsquery * -filter "(objectClass=trustedDomain)" -attr * |
LDAP枚举方式用作Get-DomainTrust
的默认枚举实现方法:
- DOWNLEVEL:没有运行AD的可信windows域。在powerview中,对于那些不熟悉专业术语的用户来说,会以
WINDOWS_NON_ACTIVE_DIRECTORY
形式作为输出。 - UPLEVEL:运行AD的可信任域。在powerview中,对于那些不熟悉专业术语的用户,这将作为
WINDOWS_ACTIVE_DIRECTORY
作为输出 - MIT:运行非Windows,兼容RFC4120的Kerberos发行版的受信任域。