如何以最小的代价恢复遭受入侵的活动目录 - 嘶吼 RoarTalk – 网络安全行业综合服务平台,4hou.com

如何以最小的代价恢复遭受入侵的活动目录

fanyeee 资讯 2021-05-11 10:00:00
116299
收藏

导语:在本文中,我们将从实战的角度为读者详细介绍如何以最小的代价恢复遭受入侵的活动目录。

在本文中,我们将为读者详细介绍活动目录林的入侵恢复(compromise recovery)过程。虽然我已经写了一段时间的博客,并阅读了大量关于活动目录的资料,但有一个主题一直未曾涉足,那就是,当活动目录遭受攻击者入侵后,该如何恢复?

实际上,关于恢复活动目录林(Active Directory forest)的文章或博客并不多见。当我们在互联网上搜索时,最终会找到可能就是来自微软的那篇文章。然而,由于这篇文章缺乏深入的例子,所以,即使管理员(IMO)阅读之后,如果遇到被入侵的情形,也不知道需要采取哪些必要的步骤才能减少进一步的损害。

这篇文章的目的是解释如何在受到主动攻击的情况下恢复活动目录,并将破坏降到最低。需要说明的是,这不是活动目录的安全评估,也不会涉及与活动目录有关的攻击技术。这篇文章的目标是确保我们的Tier-0资源得到保护,以免受到进一步破坏。

我之所以要撰写这篇文章,是因为勒索软件攻击已经呈现泛滥之势。整个网络都面临被恶意加密的风险,甚至有时支付赎金也无济于事。同时,我并不总是相信管理人员会努力研究当前的活动目录配置。

目标读者

这篇文章目标受众如下所示:

· 这样的组织:他们的整个网络刚刚被恶意加密并决定支付赎金,现在正在寻找活动目录的补救和加固策略,以重新建立信任。

· 这样的组织:正在寻找被攻击者入侵后的入侵恢复计划的组织。

· 事件响应人员

· Windows和AD管理员

备份域控制器

域控制器是一个响应身份验证请求并对计算机网络用户的身份进行验证的服务器。它需要保存活动目录数据库,其中存储了所有的用户和计算机的身份信息。这类服务器是任务关键型服务器,应优先进行保护。

我们建议在每个域中至少备份一个可写的域控制器,这样你就有不同的备份可以选择。在这篇文章中,我们将使用Azure中的Recovery Service Vault。不过,使用哪种解决方案并不重要,您可以根据自己的情况进行选择。

Recovery Service Vault是一个管理实体,可用于存储随着时间的推移而创建的恢复点,并提供一个界面来执行备份相关的操作,其中包括按需备份、执行恢复以及创建备份策略。

当我们要备份本地DC时,我们必须在域控制器上安装Microsoft Azure Recovery Services(MARS)代理。一旦完成安装,我们就可以注册机器并开始进行系统状态备份了。

1.png

我们还可以获得我们执行的每项操作(如创建备份或恢复备份)的状态概述。

1.png

在我们完成域控制器的备份之后,可以运行以下脚本来检查AD的备份日期。

脚本

# Source: https://adamtheautomator.com/backup-domain-controller/
$domainControllers | foreach {
    $backups = repadmin.exe /showbackup $_
   
    ## Capture the output ofrepadmin
    $output = @{ 'DomainController' = $_ }
   
    ## Start collectingproperties for output
    for ($i = 0; $i -lt $backups.Count; $i++) { ## Begin looking atrepadmin output
        if ($backups[$i] -match '^(CN|DC)') { ## If the line has apartition.
            ## Assign the partition name and the date/time to the output hashtable
            ## and send $output with the DomainController, Partition and DateTime
            $output.Partition = $backups[$i]
            $output.DateTime = [regex]::Match($backups[$i +2],'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})').Groups[1].Value
            [pscustomobject]$output
        }
    }
}

运行结果

在运行结果中,我们可以看到最后一次备份的日期。

1.png入侵范围

我们的Tier-0资产是首先要保护的最重要的对象,因为攻击者很可能是奔着能够提供域管理或同等权限的身份或系统去的。

在本节中,我们的任务是查找所有的Tier-0帐户和属于Tier-0的服务器。

Tier-0的定义:

Tier-0是具有最高级别权限的、能够对活动目录林有直接或间接管理控制权限的管理账户、用户组、域控制器以及系统。

Tier-0账户

只要某个账户至少属于一个受保护的用户组,那么,它就是Tier-0账户,例如:

· 域管理员

· 企业管理员

· 模式管理员

· 管理员

· 账户操作员

· 备份操作员

· 服务器操作员

· 打印操作员

· 为无约束委派配置的帐户

· 在Tier-0上作为服务运行的服务账户

要查找属于某个受保护组的所有成员,可以使用下面的命令:

([adsisearcher]'(&(objectClass=user)(adminCount=1))').FindAll()

运行结果

在输出的结果中,我们可以看到有多名用户至少属于一个受保护的用户组。

1.png

为无约束委派配置的帐户

现在,请运行下面的命令:

([adsisearcher]'(&(objectCategory=user)(userAccountControl:1.2.840.113556.1.4.803:=524288))').FindAll()

运行结果

在输出的运行结果中,我们可以看到一个账户被配置用于无约束委派。

1.png

Tier-0对象

我们可以在敏感的AD对象上委派权限,如DNC对象、MicrosoftDNS容器、AdminSDHolder容器以及与Tier-0系统相关的GPO。下面,我们列出所有具有GenericAll或以下同等权限的ACE:

· GenericAll

· GenericWrite

· WriteOwner

· WriteDacl

· ExtendedRight

· DS-Replicate-Get-Changes-All (DNC)

下面是具有这种权限的ACE的例子:

· 在域对象上具有DS-Replicate-Get-Changes和DS-Replicate-Get-Changes-All权限的MSOL_[前缀]。

· 在域对象上具有WriteDacl权限的Exchange Windows Permissions成员。

· 在MicrosoftDNS容器上具有GenericAll权限的DnsAdmins成员。

所有在上述AD对象上有敏感权限的ACE都被认为是域管理员或等同于域管理员。

枚举DNC对象上的ACL

请运行下面的命令:

$ADSI=[ADSI]"LDAP://DC=fabrikam,DC=com"
$ADSI.psbase.get_ObjectSecurity().getAccessRules($true, $true,[system.security.principal.NtAccount])

运行结果

在运行结果中,我们可以看到委派给Domain Naming Context对象的所有ACE。

1.png

枚举AdminSDHolder容器上的ACL

为此,请运行下面的命令:

$ADSI=[ADSI]"LDAP://CN=AdminSDHolder,CN=System,DC=fabrikam,DC=com"
$ADSI.psbase.get_ObjectSecurity().getAccessRules($true, $true,[system.security.principal.NtAccount])

运行结果

1.png 在运行结果中,我们可以看到所有拥有AdminSDHolder容器权限的ACE。这个容器只能由DA或具有同等权限的成员进行修改。

枚举MicrosoftDNS容器上的ACL

为此,请运行下面的命令:

$ADSI=[ADSI]"LDAP://CN=MicrosoftDNS,CN=System,DC=fabrikam,DC=com"
$ADSI.psbase.get_ObjectSecurity().getAccessRules($true, $true,[system.security.principal.NtAccount])

运行结果

在运行结果中,我们可以看到所有对MicrosoftDNS容器具有权限的ACE。

1.png

DnsAdmins的成员

为此,请运行下面的命令:

([adsisearcher]'(memberOf=cn=DnsAdmins,CN=Users,dc=fabrikam,dc=com)').FindAll()

运行结果

在运行结果中,我们可以看到DnsAdmins中有3个成员。尽管这个组不是一个受保护的组,但是,它仍然具有升级到DA的路径,所以,这个组的所有成员在功能上都是域管理员。

1.png

Tier-0服务器

对活动目录林具有直接或间接管理控制权的服务器被认为是Tier-0服务器,但我喜欢把为云资源提供升级路径的服务器算作Tier-0服务器。

列出所有域控制器

为此,请运行下面的命令:

([adsisearcher]'(&(objectCategory=computer)(primaryGroupID=516))').FindAll()

运行结果

在运行结果中,我们可以看到网络中所有的域控制器。

1.png

配置为无约束委派授权的服务器(不包括DC)

所有被配置为无约束委派授权的服务器都提供了升级到DA或同等权限的路径,所以需要从Tier-0级对其进行管理。

为此,请运行下面的命令:

([adsisearcher]'(&(objectCategory=computer)(!(primaryGroupID=516)(userAccountControl:1.2.840.113556.1.4.803:=524288)))').FindAll()

运行结果

在运行结果中,我们可以看到为无约束委派配置了3台服务器。

1.png

下面是Tier-0服务器的示例:

· 域控制器

· 无约束委派服务器

· Azure AD连接

· ADFS

· PKI(证书颁发机构)

· 备份服务器(如Veeam)

Tier-0服务器上的本地管理员

在确定了所有Tier-0服务器之后,我们应该查看这些服务器上的本地管理员,因为Tier-0服务器上的本地管理员也是间接DA或具有同等权限的角色。

查找远程服务器上的所有本地管理员(需要具有服务器的管理员权限)

为此,可运行以下命令:

$LocalGroup =[ADSI]"WinNT://Server/Administrators"
$UserNames = @($LocalGroup.psbase.Invoke("Members"))
$UserNames | foreach {$_.GetType().InvokeMember("Name",'GetProperty', $null, $_, $null)}

运行结果

在运行结果中,我们可以看到用户和Domain Admins组是Tier-0服务器上本地Administrators组的一部分。

1.png

总结

我们已经在本节中找出了所有Tier-0资产,因为我们必须首先保护这些资产免受任何进一步的损害。此外,这对于我们完成下一步操作也是很有帮助的,届时,我们将对AD进行有针对性的加固处理。为此,需要确保记录下所有具有Tier-0权限的帐户和服务器。同时,也不要忘记具有Tier-0权限的本地管理员

补救措施与加固措施

在本节中,我们将进行有针对性的AD加固处理,以保护我们的Tier-0身份和系统。这里的目标是减少Tier-0身份凭证的使用面,并确保我们的AD林重新建立起信任关系,为此,需要重设密码、创建新账户、推出GPO等。

通过组策略拒绝Tier-0身份登录更低级别的系统

当在我们确定了所有的Tier-0账户和用户组之后,需要确保这些账户不能登录到更低级别的受信任系统。

第一个建议是确保该组织有一个适当的OU结构。否则,这个计划会很难完成。第二件事是,我们现在可以创建一个新的组策略,并配置所有的设置,具体如下所示:

1.png

配置GPO后,我们需要将其链接到包含Tier-1服务器和常规客户端工作站的OU上。这样一来,我们的DA或等效帐户就不会再在较低的级别上暴露其凭证了,因为我们已经禁止他们在这些系统上登录。

1.png

为Tier-0身份重新创建新账户

在上一节中,我们已经确定了所有的Tier-0账户。现在,我们必须为每个Tier-0身份重新创建一个新的账户,因为要确定这些账户是否已经被攻破是很有难度的事情。

其中,属于Tier-0的服务账户可能是一个挑战,因为一旦我们这样做,系统就会出现中断,所以要由组织来决定下一步,并评估风险。

一旦我们为所有的Tier-0身份重新创建了新账户,我们就可以执行其他任务,例如将其添加到他们所属的AD组,等等。

重置原来的Tier-0账户的密码

将所有原来的Tier-0账户都转移到一个OU中,并重新设置该OU中的所有这些账户的密码。

这个过程中,服务账户可能是一个很大的挑战,所以,这一步要根据组织的实际情况而定。之后,我们要尝试找到服务账户,在那里也许能够重置密码。

脚本

# Replace the OU path with the correct one
$OU = [ADSI]"LDAP://OU=OU 1,DC=fabrikam,DC=com"
$Child = $OU.Get_Children()
ForEach ($User In $Child)
{
If ($User.Class -eq "user")
{
$User.Invoke("SetPassword", "MyTerriblePassw0rdWillNeverBeUsedAnymore!")
$User.SetInfo()
}
}

禁用所有原Tier-0账户

我们现在要禁用所有原来的Tier-0账户:实际上,我们上面已经将其移动到一个OU里,并且已经为所有的Tier-0管理员创建了新的账户,所以,现在完全可以弃用原来的所有Tier-0账户了。

脚本

$ObjFilter = "(&(objectCategory=person)(objectCategory=User))"
    $objSearch = New-Object System.DirectoryServices.DirectorySearcher
    $objSearch.PageSize = 15000
    $objSearch.Filter = $ObjFilter
 # Replace the OU path with the correct one
    $objSearch.SearchRoot = "LDAP://OU=OU 0,DC=fabrikam,DC=com"
    $AllObj = $objSearch.FindAll()
    foreach ($Obj in $AllObj)
           {
            $objItemS = $Obj.Properties
            $UserN = $objItemS.name
            $UserDN = $objItemS.distinguishedname
            $user = [ADSI] "LDAP://$userDN"
            $user.psbase.invokeSet('AccountDisabled', $true)
            Write-host -NoNewLine "Account $UserN has been disabled...."
            $user.setinfo()
            Write-host "Done!"
            }

运行结果

在运行结果中,我们可以发现,现在已经禁用了所有原来的Tier-0账户。

1.png

强制所有用户在下一次登录时修改密码

一件重要的事情是强迫所有用户在下次登录时更改密码,如果攻击者窃取了NTDS.DIT文件,这将使所有NT哈希值失效。

脚本

$PLSValue = 0
$ObjFilter = "(&(objectCategory=person)(objectCategory=User))"
    $objSearch = New-Object System.DirectoryServices.DirectorySearcher
    $objSearch.PageSize = 15000
    $objSearch.Filter = $ObjFilter
    $AllObj = $objSearch.FindAll()
    foreach ($Obj in $AllObj)
           {
            $objItemS = $Obj.Properties
            $UserN = $objItemS.name
            $UserDN = $objItemS.distinguishedname
            $user = [ADSI] "LDAP://$userDN"
            $user.psbase.invokeSet("pwdLastSet",$PLSValue)
            Write-host -NoNewLine "Account $UserN needs to change password at next logon...."
            $user.setinfo()
            Write-host "Done!"
            }

运行结果

如您所见,这里强制每个账户在下一次交互式登录时改变他们的密码。

1.png

重置KRBTGT账户的密码两次

KRBTGT账户的密码需要在每个域中重置两次。

为此,请运行下面的命令:

# Reset password of KRBTGT
$adsi = [adsi]"LDAP://CN=krbtgt,CN=Users,DC=fabrikam,DC=com"
$adsi.Invoke("SetPassword", "MyNewPassw0rd!")
$adsi.setinfo()

然后,等待24小时后再进行第二次重置。

*24小时之后*

请运行以下命令:

# Reset password of KRBTGT
$adsi = [adsi]"LDAP://CN=krbtgt,CN=Users,DC=fabrikam,DC=com"
$adsi.Invoke("SetPassword", "MyNewPassw0rd!")
$adsi.setinfo()

现在,我们需要验证KRBTGT的密码是否已轮换。

为此,请运行下面的命令:

$user = [adsi]"LDAP://CN=krbtgt,CN=Users,DC=fabrikam,DC=com"
[PSCustomObject] @{
username = $user.name.Value
pwdLastSet = [datetime]::FromFileTime($user.ConvertLargeIntegerToInt64($user.pwdLastSet.
value))
}

运行结果

在运行结果中,我们可以看到KRBTGT密码的轮换日期。

1.png

重置Azure AD Seamless SSO Account的密码

在每个域中对AzureADSSOACC$帐户的密码进行轮换。为此,需要具有Global Admin权限。

登录Azure AD Connect服务器(Tier-0),因为需要从AAD Connect服务器上执行该任务。不过,下面的PowerShell模块可以帮我们完成这一任务。

Import-Module “C:\Program Files\Microsoft Azure Active Directory Connect\AzureADSSO.psd1”
 
New-AzureADSSOAuthenticationContext # Sign in with a Global Admin account
 
Update-AzureADSSOForest
 
$Cred = Get-Credential
 
Update-AzureADSSOForest -OnPremCredentials $Cred

为了进行验证,我们可以运行以下命令:

$user = [adsi]"LDAP://CN=AzureADSSOACC,CN=Computers,DC=fabrikam,DC=com"
[PSCustomObject] @{
username = $user.name.Value
pwdLastSet = [datetime]::FromFileTime($user.ConvertLargeIntegerToInt64($user.pwdLastSet.
value))
}

运行结果

在这里,我们可以看到AzureADSSOACC账户的轮换日期。

1.png

将ADFS令牌签名证书轮换两次

ADFS令牌签名证书需要轮换两次。微软已经在相关博客中介绍了所有的步骤,所以这里只是复制和粘贴一下就行了。

 

1.  通过检查确保AutoCertificateRollover被设置为True。

Get-AdfsProperties | FL AutoCert*, Certificate*

否则,可以用这个命令来完成设置:

Set-ADFSProperties -AutoCertificateRollover $true

2. 连接到Microsoft Online Service。

Connect-MsolService

3. 记录内部和云令牌签名证书指纹和过期日期。

Get-MsolFederationProperty -DomainName

 1.png

4. 使用-Urgent选项替换主令牌签名证书,以便让ADFS立即替换主证书(primary certificate),而非使其成为副证书(Secondary certificate)。

Update-AdfsCertificate -CertificateType Token-Signing -Urgent

5. 在与Azure云同步之前,在不使用-Urgent选项的情况下,创建一个副令牌签名证书,以启用两个预置型(on-premise)令牌签名证书。

Update-AdfsCertificate -CertificateType Token-Signing

1.png

 6. 使用预置型的主证书和副证书在线更新云环境,以立即删除云发布的令牌签名证书;否则的话,原来的令牌签名证书仍然能够用于身份验证。

Update-MsolFederatedDomain -DomainName

 1.png

7. 检查是否成功完成了上述步骤并删除了上述步骤3中显示的证书。

Get-MsolFederationProperty -DomainName

1.png

轮换所有的域信任密码

1.  使用下面的命令语法,通过NetDom工具来重置信任密码。例如,假设活动目录林中有两个域——母域和子域,并且我们是在母域中已恢复的DC上运行此命令,则使用以下命令语法:

netdom trust parent domain name /domain:child domain name /resetOneSide /passwordT:password /userO:administrator /passwordO:*

2. 当我们在子域中运行这个命令时,请使用以下命令语法:

netdom trust child domain name /domain:parent domain name /resetOneSide /passwordT:password /userO:administrator /passwordO:*

重置所有域控制器的机器账户

所有域控制器的机器账户都需要进行重置,否则攻击者可能会继续持有相关的访问权限。

相关示例

在这个例子中,我们将重置一个名为“AMS-DC2”的域控制器的机器账户。当涉及到域控制器时,我们不能使用Reset-ComputerMachinePassword cmdlet,因为这会破坏DC的同步。相反,我们需要在每一个域控制器上完成重置任务,但遗憾的是,我目前还没有找到自动化的方法,因为我可不想破坏您的域控制器!

详细步骤

1. 在本地或通过RDP登录到需要修改密码的域控制器上

2.  确保自己在本机和AD中的计算机对象上具有管理权限(如DA或同等权限)。

3.  如果想重置Windows域控制器的密码,则必须停止Kerberos密钥分发中心服务,并将其启动类型设置为Manual。

4.  以管理员身份打开CMD,并运行以下命令。

image.png

6. 如果一切顺利的话,将看到如下所示的内容:

1.png

7. 再次启动密钥分发服务,并将启动类型设为Automatic。

8. 验证域控制器的密码是否已更新:

$user = [adsi]"LDAP://CN=AMS-DC2,OU=Domain Controllers,DC=fabrikam,DC=com"
[PSCustomObject] @{
username = $user.name.Value
pwdLastSet = [datetime]::FromFileTime($user.ConvertLargeIntegerToInt64($user.pwdLastSet.
value))
}

运行结果

在运行结果中,我们可以看到DC的机器账户已经更新。请确保对所有的域控制器都进行同样的处理。是的,这是一个手动任务。

1.png

 

· /s:是用来设置机器账户密码的域控制器的名称。它是运行KDC的服务器。

· /ud:是用于跟/s参数指定的域进行连接的用户账户。它必须是domain/User格式。如果这个参数被省略,则使用当前的用户账户。

· /pd:*表示为/ud参数指定的用户账户指定的密码。其中,这里的星号(*)用来表示密码。例如,本地域控制器计算机是Server1,对等的Windows域控制器是Server2。如果你在Server1上运行Netdom.exe,并使用以下参数,密码将在本地更改,并同时写入Server2。并且,通过复制可以把这个变化传播到其他域控制器上。

重置AAD同步账户的密码

大多数组织都是通过Azure AD Connect在混合状态下运行。这样的话,就需要一个在Domain Root上具有以下权限的(服务)账户来完成密码哈希值的同步。 1.png

这个账户的密码需要修改,因为攻击者可能通过抓取AAD同步账户的NT哈希值来维持权限。在重置这个账户的密码时,请使用一个足够复杂的密码。

为此,可以运行下面的命令:

# Replace the OU path with the correct path where your AAD Sync account is stored
$adsi = [adsi]"LDAP://CN=SVC_ADSync,OU=Service accounts,DC=fabrikam,DC=com"
$adsi.Invoke("SetPassword", "MyIncredibleComplexPassw0rdThatYouCantCrackBro")
$adsi.setinfo()

现在,我们需要验证密码是否已经重置。为此,可以运行下面的命令:

$user = [adsi]"LDAP://CN=SVC_ADSync,OU=Service accounts,DC=fabrikam,DC=com"
[PSCustomObject] @{
username = $user.name.Value
pwdLastSet = [datetime]::FromFileTime($user.ConvertLargeIntegerToInt64($user.pwdLastSet.
value))
}

运行结果

在此我们可以看到,密码确实已经修改过了。

1.png

在所有工作站和成员服务器上随机设置本地管理密码

本地管理员密码解决方案(LAPS)是一个密码管理程序,可以用来自动轮换每个独立工作站或服务器上的内置管理员(RID-500)账户。虽然这种方法并不完美,但它的确是可行的,而且也是免费的。如果组织尚未上马能够随机设置每个系统上的本地管理员密码的解决方案的话,不妨试一下LAPS。

注意:不要在域控制器上部署LAPS。

1. 将GPO链接到所有工作站和成员服务器的OU

1.png

2. LAPS软件包的储存位置 1.png

3. 进行设置

1.png

4. 验证LAPS安装是否成功

Get-AdmPwdPassword -ComputerName "Client"

1.png

部署EDR解决方案

部署EDR解决方案以获得对所有端点的可见性是非常重要的一项措施。在本例中,我们将使用Defender for Endpoint。在此阶段,我们将在所有工作站、成员服务器和域控制器上部署MDE。

第一步是下载安装套件,并通过类似于组策略的方式进行部署。所有的步骤都已经详细地记录在这里了

1.png

第二步是接收可能触发的所有警报。一旦攻击者开始频繁活动,我们就可能捕捉到他们的活动踪迹,并发现这些活动发生在哪台机器上。

1.png

如果我们在一台机器上面发现了攻击活动的踪迹,就必须把机器从网络上断开,其中包括断开机器的域连接和撤销VPN证书。

小结

活动目录是大多数组织的身份基础设施,所以,我们需要花大力气来保护其安全。同时,我们已经开始步入云时代,但由于大多数组织都是在一个混合场景下运作的,所以我们也不能只关注云中的所有新东西。

我们一定要保护好自己在企业内部的身份信息,尽量避免在所有较低信任度的系统上暴露身份凭证。这就是为什么攻击者能够轻松实现横向移动的主要原因,因为高权限的凭证无处不在。

最后,但并非最不重要的是:一定要做好事件响应和灾难恢复计划。对于所有的组织和任何潜在的IR团队来说,这都是非常重要的一件事情。

参考资料

· Advice for incident responders on recovery from systemic identity compromises: https://www.microsoft.com/security/blog/2020/12/21/advice-for-incident-responders-on-recovery-from-systemic-identity-compromises/

· Active Directory Forest Recovery Prerequisites: https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/manage/ad-forest-recovery-prerequisties

· Script to reset the KRBTGT password: https://github.com/microsoft/New-KrbtgtKeys.ps1/blob/master/New-KrbtgtKeys.ps1

· Microsoft LAPS: https://www.microsoft.com/en-us/download/details.aspx?id=46899

· Evaluate Microsoft Defender for Endpoint: https://docs.microsoft.com/en-us/microsoft-365/security/defender-endpoint/evaluate-mde?view=o365-worldwide

· Use Netdom.exe to reset machine account passwords of a Windows Server domain controller: https://docs.microsoft.com/en-us/troubleshoot/windows-server/windows-security/use-netdom-reset-domain-controller-password

本文翻译自:https://m365internals.com/2021/04/27/practical-compromise-recovery-guidance-for-active-directory/如若转载,请注明原文地址
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论

 
本站4hou.com,所使用的字体和图片文字等素材部分来源于原作者或互联网共享平台。如使用任何字体和图片文字有侵犯其版权所有方的,嘶吼将配合联系原作者核实,并做出删除处理。
©2022 北京嘶吼文化传媒有限公司 京ICP备16063439号-1 本站由 提供云计算服务