红队战术-从域管理员到企业管理员

2021-07-01 15:10:05 浏览数 (3)

前言

一个企业的整个网络划分是非常巨大了,甚至有多个林,而这个域森林权力最大还属企业管理员了,当我们拿到一个域的dc的时候,当然不是红队的终点,我们的最终的目标是企业管理员,只要我们拿下了企业管理员,整个企业内网才算真正拿下。

基础知识补充

企业管理员:是域森林根域中的企业管理员组成员,该组的成员在域森林中的每一个域内的administrators组的成员,对所有的域控制器具有完全的访问权限。

域信任:原本作用是为了解决多域环境下的跨域资源共享问题,Active Directory通过域和林信任关系提供跨多个域或林的安全性。在跨信任进行身份验证之前,Windows必须首先确定用户,计算机或服务所请求的域是否与请求帐户的登录域具有信任关系,为了确定信任关系,Windows安全系统计算接收访问资源请求的服务器的域控制器与请求资源请求的帐户所在域中的域控制器之间的信任路径。

信任架构图

该体系结构为Active Directory提供了有效的通信基础结构。这些包括身份验证协议,网络登录服务,本地安全机构(LSA)和Active Directory中存储的受信任域对象(TDO)。

身份验证协议包括:NTLM协议(Msv1_0.dll)Kerberos协议(Kerberos.dll)网络登录(Netlogon.dll)

LSA(Lsasrv.dll)

本地安全机构(LSA)是受保护的子系统,用于维护有关系统上本地安全所有方面的信息(统称为本地安全策略),并提供各种服务来在名称和标识符之间进行转换。LSA安全子系统以内核模式和用户模式提供服务,以验证对对象的访问,检查用户特权以及生成审核消息,LSA负责检查由受信任或不受信任域中的服务提供的所有会话票证的有效性。

可信域对象

组织内的每个域或林信任都由存储在其域内的“系统”容器中的“受信任域对象”(TDO)表示。

TDO密码

信任关系中的两个域共享一个密码该密码存储在Active Directory的TDO对象中。作为帐户维护过程的一部分,信任域控制器每三十天更改一次存储在TDO中的密码。因为所有双向信任实际上都是两个方向相反的单向信任,所以对于双向信任,此过程发生两次。信任具有信任和信任的一面。在受信任的方面,任何可写域控制器都可以用于该过程。

单向和双向信任

建立以允许访问资源的信任关系可以是单向或双向的。单向信任是在两个域之间创建的单向身份验证路径。在域A和域B之间的单向信任中,域A中的用户可以访问域B中的资源。但是,域B中的用户不能访问域A中的资源。

Active Directory林中的所有域信任都是双向的可传递信任。创建新的子域时,将在新的子域和父域之间自动创建双向传递信任。在双向信任中,域A信任域B,域B信任域A。这意味着可以在两个方向之间的两个域之间传递身份验证请求。某些双向关系可以是非传递性的,也可以是传递性的,具体取决于所创建的信任类型。

传递性和非传递性信托

传递性决定了信任是否可以扩展到与其形成联系的两个域之外,传递信任可用于扩展与其他域的信任关系,非传递信任可用于拒绝与其他域的信任关系。

每次您在林中创建新域时,都会在新域与其父域之间自动创建双向传递信任关系。如果将子域添加到新域,则信任路径将向上流动通过域层次结构,从而扩展在新域及其父域之间创建的初始信任路径。传递信任关系在域树形成时在域树中向上流动,从而在域树中的所有域之间创建传递信任。

身份验证请求遵循这些信任路径,因此林中任何域的帐户都可以由林中的任何其他域进行身份验证。通过单个登录过程,具有适当权限的帐户可以访问林中任何域中的资源。

域环境只会接收来自受信任的域的凭据,域信任利用dns服务器定位两个不同子域的域控制器,所以在设置两个域之间的信任关系的时候,得先在两个DC上设置条件DNS转发器,然后再通过建立受信任的域来添加新的信任关系。

实际操作

第一步获取域信任关系:

代码语言:javascript复制
Nltest /domain_trusts
([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).GetAllTrustRelationships()
Get-ADTrust -Filter *

当然还可以通过拿到的dc去枚举另一个域dc的用户组,sid等。。。

接下来有两种情况,如果我们拿到了一个域的krbtgt账户hash就可以直接生成一个林中的黄金票据,当然这如果控制了一个域的控制器肯定拿到了,第二种就是不用krbtgt,稍微麻烦了一点。

首先第一种,拿到了林下任意域的krbtgt-hash

原理依据,从父域派生出来的子域默认是相互信任关系(这是通过域信任对父域攻击,成功获取企业管理员的关键),所以我们拿到任意子域krbtgt,就可以制作到父域的黄金票据。

获取krbtgt账户的sid

代码语言:javascript复制
wmic useraccount get name,sid

生成黄金票据:

代码语言:javascript复制
Mimikatz "kerberos::golden /user:Administrator /domain:当前域名 /sid:当前域sid /sids:目标域sid /krbtgt:hash"

关键在于:我们需要替换sids的最后三位值从502(krbtgt)替换为519(企业管理员),此过程的这一部分称为SID历史跳跃攻击:sidHistory-hopping,sidHistory跳跃攻击再次证明了林是信任的边界,而不是域。

把当前票据注入内存然后尝试访问目标服务。

现在,由于sidHistory-hopping攻击的出现, 微软发布了允许企业或组织改变krbtgt账户密码的脚本,为了使其对单个域的林有效,密码必须更改两次,也就是说林中每个域中的krbtgt帐户的密码必须要更改两次才有效,次攻击就不是很有效。

第二种,通过域信任密钥:

根据Active Directory技术规范的第6.1.6.9.6.1节,域间信任密钥每30天自动轮换一次,而当krbtgt账户发生了更改,它们不会轮换,因此,如果我们拿到了域信任迷密钥,我们仍然可以通过可以使用sidHistory方法来获得信任。

通过kerberos跨域信任的工作图:

当用户将这个跨域TGT票证引用提交给外部域之前,会被域间信任密钥签名,而TGT也包括在内,那么外部域看到这个签名的时候,就会完全信任此用户TGT票据,并认为此票据所有信息都是正确的,因为这一切都是两个受信任的域控之间协商好了。

依据原理:只要拿到了两个域之间的信任密钥,就可以伪造一张第一个域内的任意用户的TGT

首先得拿到当前域的sid,目标域的sid,信任密钥:

代码语言:javascript复制
mimikatz.exe " privilege::debug"
"lsadump::trust /patch"

使用mimikatz创建信任票据:

代码语言:javascript复制
mimikatz “kerberos::golden /domain:当前域名 /sid:当前域sid /sids:目标域sid /rc4:获取域信任密钥 /user:伪造的用户名 /service:要访问的服务(一般为krbtgt) /target:目标域名 /ticket:票据名(Gamma.kirbi)”

这里只是生成了被域信任密钥签名的tgt,还没有tgs,所以得拿着这个tgt获取tgs

代码语言:javascript复制
Asktgs 票据名(Gamma.kirbi) CIFS/目标的域控

然后把票据注入到内存,然后尝试访问目标服务。

如果外部信任和林信任存在sid过滤机制,则无法利用sidhistiory,则时候就可以根据林中的服务来进行横向,一直找到企业管理员为止

END

0 人点赞