Kerberos委任とは?非制約委任・制約付き委任・RBCDの違いと設計上の注意点

Active Directory設計・運用

「委任」という言葉、AD環境の設定でたまに見かけるけど、正直よくわからないまま触っている人も多いと思います。
実際、私も最初は「なんとなく別のサーバーに権限を渡す設定」くらいの理解でした。

この委任、設計を誤るとドメイン管理者権限をまるごと乗っ取られるレベルの攻撃経路になります。今回は委任の仕組みと、3種類ある委任方式それぞれのリスクを整理します。

なぜ委任が必要なのか

Webサーバーにログインしたユーザーが、そのWebアプリ経由でバックエンドのDBサーバーにもアクセスする、というシナリオを考えてみます。

ユーザー → Webサーバー(フロントエンド) → DBサーバー(バックエンド)

このとき、DBサーバーは「今アクセスしてきたのは誰なのか」を正しく認識する必要があります。Webサーバーが自分自身の権限でDBにアクセスしてしまうと、ユーザーごとのアクセス制御ができません。

これは「二重ホップ問題」と呼ばれる、Kerberos認証特有の課題です。
委任は、この問題を解決するために「フロントエンドのサービスが、ユーザーの代わりにバックエンドのサービスにアクセスする」ことを許可する仕組みです。

Kerberos委任(Kerberos Delegation)
あるサービス(フロントエンド)が、ユーザーに代わって別のサービス(バックエンド)にアクセスすることを許可する仕組み。二重ホップ問題を解決するために使われる。委任の許可範囲によって「非制約委任」「制約付き委任」「リソースベース制約付き委任」の3種類に分かれる。

非制約委任:一番古くて、一番危険な方式

非制約委任(Unconstrained Delegation)
フロントエンドのサービスが、ユーザーのTGT(チケット交付チケット)をそのまま受け取り、任意のサービスに対してユーザーになりすませる委任方式。委任先の制限が一切ないことが最大のリスク。

非制約委任が設定されたサーバーは、ユーザーがそのサーバーに接続してきた瞬間、そのユーザーのTGTをそのまま保持します。TGTを持っているということは、そのユーザーになりすましてドメイン内のどのサービスにもアクセスできるということです。

これが攻撃者にとって非常に都合が良い状態です。
もしDomain Adminsのアカウントが、非制約委任が設定されたサーバーに一度でもアクセスしてくると、そのサーバーを乗っ取った攻撃者はDomain Adminsになりすませます。

デフォルトでは、ドメインコントローラー自体が非制約委任の設定を持っています。
(Kerberos認証を処理する都合上)

DCが乗っ取られた場合の被害の大きさは今更言うまでもありませんが、DC以外のサーバーに非制約委任が設定されている場合は、即刻見直すべき対象です。

AD攻撃全般の仕組みについては「AD攻撃手法と要塞化」も参照してください。

制約付き委任:委任先を絞る方式

制約付き委任(Constrained Delegation)
フロントエンドのサービスが委任できる先を、あらかじめ指定したサービスのみに制限する方式。S4U2Proxyという拡張機能を使い、ユーザーのTGTを丸ごと渡すのではなく、必要なサービスチケットだけを個別に取得する。

非制約委任と違い、制約付き委任では「このサービスに対してだけ委任を許可する」という設定を、委任元のアカウント(フロントエンドのサービスアカウント)に対して行います。これはmsDS-AllowedToDelegateToという属性で管理されます。

powershell
# 制約付き委任の設定を確認する
Get-ADUser -Identity <サービスアカウント> -Properties msDS-AllowedToDelegateTo

TGTそのものを渡さないため、非制約委任よりはかなり安全です。
ただし、委任元のアカウントが侵害された場合、設定されている委任先のサービスに対しては、依然として任意のユーザーになりすませてしまうリスクは残ります。

リソースベース制約付き委任(RBCD):管理の主体が変わる方式

リソースベース制約付き委任(RBCD:Resource-Based Constrained Delegation)
「誰が委任できるか」を、委任元ではなく委任先(リソース側)が管理する方式。委任先オブジェクトのmsDS-AllowedToActOnBehalfOfOtherIdentity属性に、委任を許可する相手を設定する。Windows Server 2012以降で利用可能。

制約付き委任との一番の違いは「誰が設定を管理するか」です。従来の制約付き委任では委任元(フロントエンド)のアカウントに設定しますが、RBCDでは委任先(バックエンド)のリソース側のオブジェクトに、誰からの委任を受け入れるかを設定します。

powershell
# RBCDの設定を確認する
Get-ADComputer -Identity <バックエンドのサーバー名> -Properties PrincipalsAllowedToDelegateToAccount

# RBCDを設定する例
Set-ADComputer -Identity <バックエンドのサーバー名> `
    -PrincipalsAllowedToDelegateToAccount <フロントエンドのサーバー名>$

この方式の便利な点は、ドメイン管理者の手を借りずに、リソースの管理者自身が委任設定を行えることです。ただしこれは同時に新しい攻撃経路にもなります。

もし攻撃者が、あるコンピューターオブジェクトに対する書き込み権限(GenericWriteGenericAllなど)を何らかの形で手に入れた場合、そのオブジェクトのmsDS-AllowedToActOnBehalfOfOtherIdentity属性を自分の管理するアカウントに向けて書き換えることで、そのリソースに対して任意のユーザーになりすませるようになります。

特にこれがドメインコントローラーに対して設定されていた場合、ドメイン管理者への昇格につながります。

「委任の設定を変えるのにドメイン管理者権限が要らない」という手軽さは、裏を返せば「委任先オブジェクトへの書き込み権限さえあれば誰でも設定を変えられてしまう」というリスクでもあります。

現場で確認しておきたいこと

3種類の委任方式を整理すると、リスクの大きさは
「非制約委任 > 制約付き委任 > RBCD(適切に管理されていれば)」という順番になります。
設計としては、非制約委任は極力使わず、必要であればRBCDに置き換えていくのが現在の推奨です。

まず、ドメイン内に非制約委任が設定されているサーバーがないか棚卸ししてみてください。

powershell
# 非制約委任が設定されているアカウント・コンピューターを確認する(DC以外)
Get-ADComputer -Filter {TrustedForDelegation -eq $true} -Properties TrustedForDelegation |
    Where-Object { $_.DistinguishedName -notlike "*Domain Controllers*" }

Get-ADUser -Filter {TrustedForDelegation -eq $true} -Properties TrustedForDelegation

もしDC以外のサーバーで非制約委任が有効になっているものが見つかったら、そのサーバーの管理体制(誰がアクセスできるか、パッチ管理が行き届いているか)を優先的に見直す価値があります。

RBCDを使っている場合は、msDS-AllowedToActOnBehalfOfOtherIdentityにどのアカウントが登録されているかを定期的に確認し、特にドメインコントローラーに対してこの属性が設定されていないか(通常は設定されていないはずです)を確認しておくと安心です。

特権アカウントの保護設計全体については「AD特権アカウントの設計|Tier0保護と管理者アカウント分離の実務」もあわせてご覧ください。

あわせてご覧ください

参考文献

コメント

タイトルとURLをコピーしました