使用 Microsoft 登入
登入或建立帳戶。
您好:
選取其他帳戶。
您有多個帳戶
選擇您要用來登入的帳戶。

摘要

樹系信任為 Active Directory 樹系中的資源提供信任來自另一個樹系的識別的方法。 這個信任可以雙向設定。 受信任的樹系是使用者識別的來源。 信任的樹系包含使用者進行驗證的資源。 受信任的樹系可以對信任樹系的使用者進行驗證,而不允許進行相反的操作。

不受限制的 Kerberos 委派是使用者將其認證傳送到服務,讓服務可以代表使用者存取資源的機制。若要啟用不受限制的 Kerberos 委派,Active Directory 中服務的帳戶必須標示為受信任可以委派。 如果使用者和服務屬於不同樹系,則會造成問題。 服務樹系負責允許委派。 委派包括使用者樹系中的使用者認證。

允許一個樹系訂定影響另一個樹系帳戶的安全性決策,將會違反樹系之間的安全性界限。若攻擊者擁有信任的樹系,則可以對受信任樹系中的識別要求 TGT 委派,進而存取受信任樹系中的資源。 這不適用於 Kerberos 限制委派 (KCD)。

Windows Server 2012 引進對 Kerberos 完整委派的樹系界限強制執行 (英文)。 這個功能為受信任的網域新增原則,可根據信任來停用不受限制的委派。 這個功能的預設設定允許不受限制的委派,而且不安全。

下列 Windows Server 版本具有提供安全性強化的更新可供使用:

  • Windows Server 2019

  • Windows Server 2016

  • Windows Server 2012 R2

  • Windows Server 2012

這個功能及安全性強化中的變更已移植到下列版本:

  • Windows Server 2008 R2

  • Windows Server 2008

這些安全性變更會進行下列變更:

  • 安裝 5 月 14 日更新和以後的更新之後,依預設停用新樹系和新外部信任上不受限制的 Kerberos 委派。

  • 安裝 2019 年 7 月 9 日更新和以後的更新之後,停用樹系 (新的和現有的) 和外部信任上不受限制的 Kerberos 委派。

  • 系統管理員可以使用 5 月以後版本的 NETDOM 和 AD PowerShell 模組,藉此啟用不受限制的 Kerberos 委派。

這些更新可能會對樹系或外部信任間目前需要不受限制的 Kerberos 委派的應用程式造成相容性衝突。 對於依預設啟用隔離旗標 (也稱為 asSID 篩選) 的外部信任尤其如此。 具體來說,當您要求新票證時,對於透過所列信任類型使用不受限制委派的服務,驗證要求將會失敗。

如需發行日期,請參閱更新時間表

因應措施

若要在具有對 Kerberos 完整委派的樹系界限強制執行 (英文) 功能的 Windows Server 版本上提供資料和帳戶安全性,您可以在安裝 2019 年 3 月更新之後,將 netdom 旗標 EnableTGTDelegation 設定為 No,如下所示,藉此封鎖連入信任間的 TGT 委派:

netdom.exe trust fabrikam.com /domain:contoso.com /EnableTGTDelegation:No

分別安裝 2019 年 5 月和 7 月更新之後,新的和現有的樹系及外部信任上的 TGT 委派遭到封鎖。

若要重新啟用信任間的委派並回復原始的不安全設定,直到可以啟用限制或資源型委派,請將 EnableTGTDelegation 旗標設定為 Yes

啟用 TGT 委派的 NETDOM 命令列如下所示:

netdom trust <TrustedDomainName > /domain:<TrustingDomainName > /EnableTgtDelegation:Yes

概念上,您可以將用來啟用 TGT 委派的 NETDOM 語法想成:

netdom trust <domain that you are administering> /domain:<domain whose trust NETDOM is modifying> /EnableTgtDelegation:Yes

用來在 contoso.com 伺服器上啟用 fabrakam.com 使用者的 TGT 委派的 NETDOM 語法如下所示:

netdom.exe trust fabrikam.com /domain:contoso.com /EnableTGTDelegation:Yes


注意事項

  • 每個信任網域 (例如 contoso.com) 的 EnableTGTDelegation 旗標都應在受信任的網域 (在這個案例中,即為 fabrikam.com) 中設定。 設定旗標之後,受信任的網域將不再允許將 TGT 委派給信任網域。

  • EnableTGTDelegation 的安全狀態為 No

  • 若任何應用程式或服務依賴樹系間不受限制的委派,將會在以手動或程式設計方式將 EnableTGTDelegation 設定為 Yes 時發生失敗。 安裝 2019 年 5 月更新和 2019 年 7 月更新之後,新的和現有的信任上的 EnableTGTDelegation 會預設為 NO。 如需有關如何偵測這個失敗的詳細資訊,請參閱尋找依賴不受限制委派的服務。 請參閱更新時間表,以取得影響此因應措施套用方式的時間表變更。

  • 如需有關 NETDOM 的詳細資訊,請參閱 Netdom.exe 文件 (英文)

  • 如果您必須啟用信任上的 TGT 委派,建議您在用戶端電腦上啟用 Windows Defender Credential Guard,以避免這個風險。 這可以防止已啟用並執行 Windows Defender Credential Guard 的電腦中的所有不受限制委派。

  • 如果您擁有樹系或外部信任,並且其中一個設定為隔離,則無法啟用 TGT 委派,因為兩個旗標具有相反的語意。 隔離位元會強化參與網域之間的安全界限。 啟用 TGT 委派會將信任的網域存取權提供給受信任網域中的使用者認證,藉此清除網域之間的安全性界限。 您無法兩者都擁有。

    如果 [隔離] 旗標目前已啟用,請將 quarantine:no 旗標新增到 NETDOM 命令列語法。

  • 如果您已將 EnableTGTDelegation 變更為 Yes,請視需要刪除原始呼叫者和中繼呼叫者上的 Kerberos 票證。 要刪除的相關票證是相關信任間用戶端的轉介 TGT。 這可能牽涉不只一個裝置,視指定的環境中委派躍點的數目而定。

如需有關此程序的詳細資訊,請參閱下列 Windows IT Pro Center 文章:

使用 Windows Defender Credential Guard 保護衍生的網域認證 (部分機器翻譯)

更新時間表

2019 年 3 月 12 日

Kerberos 完整委派的樹系界限強制執行將以更新形式提供使用,以便在本文頂端<適用於>一節中所列、所有支援的 Windows Server 版本上啟用這個功能。 我們建議您在連入樹系信任上設定此功能。

此更新會將對 Kerberos 完整委派的樹系界限強制執行 (英文) 新增至下列系統:

  • Windows Server 2008 R2

  • Windows Server 2008

2019 年 5 月 14 日

已發行更新,將新的安全預設設定新增至新的樹系統和外部信任。 如果您需要信任間的委派,應在安裝 2019 年 7 月 9 日更新之前,先將 EnableTGTDelegation 旗標設定為 Yes。 如果您不需要信任間的委派,則不應設定 EnableTGTDelegation 旗標。 EnableTGTDelegation 旗標將會遭到忽略,直到安裝 2019 年 7 月 9 日更新為止,這讓系統管理員在需要時有時間可以重新啟用不受限制的 Kerberos 委派。

在此更新中,EnableTGTDelegation 旗標將會針對任何新建立的信任,依預設設定為 No。 這與先前的行為相反。 我們建議系統管理員改為重新設定受影響的服務,以便使用資源型限制委派。

如需有關如何偵測相容性問題的詳細資訊,請參閱尋找依賴不受限制委派的服務

2019 年 7 月 9 日

已發行更新,以便在樹系和外部信任的輸入端強制執行新的預設行為。 對於透過所列信任類型使用不受限制委派的服務,驗證要求將會經過驗證,但不包含委派。 當服務嘗試執行委派的操作時,將會發生失敗。

如需緩和措施,請參閱因應措施一節。

尋找依賴不受限制委派的服務

若要掃描具有允許 TGT 委派的連入信任的樹系,並尋找允許不受限制委派的任何安全性主體,請在指令碼檔案中執行下列 PowerShell 指令碼 (例如,Get-RiskyServiceAccountsByTrust.ps1 -Collect):

注意

您也可以傳遞 -ScanAll 旗標,以便在不允許 TGT 委派的信任間進行搜尋。


[CmdletBinding()]  
Param  
(  
    [switch]$Collect, 
    [switch]$ScanAll 
) 
 
if ($Debug) {  
    $DebugPreference = 'Continue'  
} 
else { 
    $DebugPreference = 'SilentlyContinue'  
} 

function Get-AdTrustsAtRisk 
{ 
    [CmdletBinding()]  
    Param  
    (  
        [string]$Direction = "Inbound", 
        [switch]$ScanAll 
    ) 
 
    if ($ScanAll) { 
        return get-adtrust -filter {Direction -eq $Direction} 
    } 
    else { 
        return get-adtrust -filter {Direction -eq $Direction -and TGTDelegation -eq $false} 
    } 
} 
 
function Get-ServiceAccountsAtRisk 
{ 
    [CmdletBinding()]  
    Param  
    (  
        [string]$DN = (Get-ADDomain).DistinguishedName, 
        [string]$Server = (Get-ADDomain).Name 
    ) 
 
    Write-Debug "Searching $DN via $Server" 
 
    $SERVER_TRUST_ACCOUNT = 0x2000  
    $TRUSTED_FOR_DELEGATION = 0x80000  
    $TRUSTED_TO_AUTH_FOR_DELEGATION= 0x1000000  
    $PARTIAL_SECRETS_ACCOUNT = 0x4000000    
 
    $bitmask = $TRUSTED_FOR_DELEGATION -bor $TRUSTED_TO_AUTH_FOR_DELEGATION -bor $PARTIAL_SECRETS_ACCOUNT  
  
$filter = @"  
(& 
  (servicePrincipalname=*) 
  (| 
    (msDS-AllowedToActOnBehalfOfOtherIdentity=*) 
    (msDS-AllowedToDelegateTo=*) 
    (UserAccountControl:1.2.840.113556.1.4.804:=$bitmask) 
  ) 
  (| 
    (objectcategory=computer) 
    (objectcategory=person) 
    (objectcategory=msDS-GroupManagedServiceAccount) 
    (objectcategory=msDS-ManagedServiceAccount) 
  ) 
) 
"@ -replace "[\s\n]", ''  
  
    $propertylist = @(  
        "servicePrincipalname",   
        "useraccountcontrol",   
        "samaccountname",   
        "msDS-AllowedToDelegateTo",   
        "msDS-AllowedToActOnBehalfOfOtherIdentity"  
    )  
 
    $riskyAccounts = @() 
 
    try { 
        $accounts = Get-ADObject -LDAPFilter $filter -SearchBase $DN -SearchScope Subtree -Properties $propertylist -Server $Server 
    } 
    catch { 
        Write-Warning "Failed to query $Server. Consider investigating seperately. $($_.Exception.Message)" 
    } 
              
    foreach ($account in $accounts) {  
        $isDC = ($account.useraccountcontrol -band $SERVER_TRUST_ACCOUNT) -ne 0  
        $fullDelegation = ($account.useraccountcontrol -band $TRUSTED_FOR_DELEGATION) -ne 0  
        $constrainedDelegation = ($account.'msDS-AllowedToDelegateTo').count -gt 0  
        $isRODC = ($account.useraccountcontrol -band $PARTIAL_SECRETS_ACCOUNT) -ne 0  
        $resourceDelegation = $account.'msDS-AllowedToActOnBehalfOfOtherIdentity' -ne $null  
      
        $acct = [PSCustomobject] @{  
            domain = $Server 
            sAMAccountName = $account.samaccountname  
            objectClass = $account.objectclass          
            isDC = $isDC  
            isRODC = $isRODC  
            fullDelegation = $fullDelegation  
            constrainedDelegation = $constrainedDelegation  
            resourceDelegation = $resourceDelegation  
        }  
 
        if ($fullDelegation) {  
            $riskyAccounts += $acct    
        } 
    }  
 
    return $riskyAccounts 
} 
 
function Get-RiskyServiceAccountsByTrust  
{ 
    [CmdletBinding()]  
    Param  
    ( 
        [switch]$ScanAll 
    ) 
     
    $riskyAccounts = @() 
 
    $trustTypes = $("Inbound", "Bidirectional") 
 
    foreach ($type in $trustTypes) { 
 
        $riskyTrusts = Get-AdTrustsAtRisk -Direction $type -ScanAll:$ScanAll 
 
        foreach ($trust in $riskyTrusts) { 
            $domain = $null 
     
            try { 
                $domain = Get-AdDomain $trust.Name -ErrorVariable eatError -ErrorAction Ignore 
            } catch { 
                write-debug $_.Exception.Message 
            } 
 
            if($eatError -ne $null) { 
                Write-Warning "Couldn't find domain: $($trust.Name)" 
            } 
 
            if ($domain -ne $null) { 
                $accts = Get-ServiceAccountsAtRisk -DN $domain.DistinguishedName -Server $domain.DNSRoot 
 
                foreach ($acct in $accts) { 
                    Write-Debug "Risky: $($acct.sAMAccountName) in $($acct.domain)" 
                }             
 
                $risky = [PSCustomobject] @{  
                    Domain = $trust.Name 
                    Accounts = $accts 
                } 
 
                $riskyAccounts += $risky 
            } 
        } 
    } 
 
    return $riskyAccounts 
} 
 
if ($Collect) { 
   Get-RiskyServiceAccountsByTrust -ScanAll:$ScanAll | Select-Object -expandProperty Accounts | format-table 
}

PowerShell 指令碼的輸出會列出網域中設定用於連入信任 (來自已設定不受限制委派的執行網域) 的 Active Directory 安全性主體。 輸出會類似下列範例。

domain

sAMAccountName

objectClass

partner.fabrikam.com

dangerous

user

partner.fabrikam.com

labsrv$

computer


透過 Windows 事件偵測不受限制的委派

發行 Kerberos 票證時,Active Directory 網域控制站會記錄下列安全性事件。 這些事件包含有關目標網域的資訊。 您可以使用這些事件來判斷不受限制的委派是否用於連入信任之間。

注意

請檢查包含與受信任網域名稱相符之 TargetDomainName 值的事件。

事件記錄檔

事件來源

事件識別碼

詳細資料

安全性

Microsoft-Windows-Security-Auditing

4768

Kerberos TGT 已發行。

安全性

Microsoft-Windows-Security-Auditing

4769

Kerberos 服務票證已發行。

安全性

Microsoft-Windows-Security-Auditing

4770

Kerberos 服務票證已更新。


疑難排解驗證失敗

停用不受限制的委派時,如果應用程式依賴不受限制的委派,則應用程式可能會遇到與這些變更相關的相容性問題。 這些應用程式應設定為使用限制委派或以資源為主的限制委派。 如需詳細資訊,請參閱 Kerberos 限制委派概觀 (部分機器翻譯)

依賴信任間來回行程驗證的應用程式並未受支援使用限制委派。 例如,如果樹系 A 中的使用者向樹系 B 中的應用程式驗證,並且樹系 B 中的應用程式嘗試將票證委派回樹系 A,則委派會失敗。

需要更多協助嗎?

想要其他選項嗎?

探索訂閱權益、瀏覽訓練課程、瞭解如何保護您的裝置等等。

社群可協助您詢問並回答問題、提供意見反應,以及聆聽來自具有豐富知識的專家意見。

這項資訊有幫助嗎?

您對語言品質的滿意度如何?
以下何者是您會在意的事項?
按下 [提交] 後,您的意見反應將用來改善 Microsoft 產品與服務。 您的 IT 管理員將能夠收集這些資料。 隱私權聲明。

感謝您的意見反應!

×