コンテンツにスキップ

Kerberos delegation(委任)は、service account がユーザーの代わりに別サービスへアクセスするための仕組みです。正しく使うと SSO(Single Sign-On)に必要な機能ですが、SPN(Service Principal Name)や委任属性の管理が緩いと、権限昇格や横展開の経路になります。

重要な前提は、KDC が LDAP 上の directory attribute を読んで TGS(service ticket)を発行する点です。SPN の所有者、委任先、RBCD の許可リストはすべて AD object の属性で制御されます。

種類主な属性意味
Unconstrained DelegationTRUSTED_FOR_DELEGATIONservice が受け取った TGT を使って任意の backend へ委任できる。
Constrained Delegation (KCD)msDS-AllowedToDelegateToservice が事前に許可された SPN へだけ委任できる。
RBCDmsDS-AllowedToActOnBehalfOfOtherIdentityresource 側が「誰に自分への委任を許すか」を指定する。

KCD は委任元の account 側に委任先 SPN を持ち、RBCD は委任される resource 側に許可リストを持つ、という向きの違いがあります。

S4U(Service for User)は、service account がユーザーを代理して ticket を取得する Kerberos 拡張です。

  • S4U2self: service account が、任意ユーザーから自分宛ての service ticket を取得する。
  • S4U2Proxy: S4U2self などで得た user context を使い、別 service への service ticket を取得する。
service account -> KDC: S4U2self(User -> service)
service account <- KDC: User to service の ticket
service account -> KDC: S4U2Proxy(User -> backend SPN)
service account <- KDC: User to backend の ticket

can now impersonate users via S4U2Proxy のような表現は、対象 account がユーザーのパスワードを得たという意味ではありません。KDC から「そのユーザーとして特定 service に提示できる ticket」を取得できる、という意味です。

制約として、Account is sensitive and cannot be delegated が有効なユーザーや Protected Users のような保護対象は、委任による代理が制限されます。

RBCD は resource 側の msDS-AllowedToActOnBehalfOfOtherIdentity によって制御されます。

実体は security descriptor ですが、概念的には次のように読めます。

WEB01$:
msDS-AllowedToActOnBehalfOfOtherIdentity = APP01$
意味:
APP01$ は、ユーザーを代理して WEB01 の service ticket を要求できる。

この状態で APP01$ の資格情報を持っていると、たとえば Administrator を代理して cifs/WEB01.example.local の ticket を要求し、SMB へアクセスできます。実際に使える service は、要求する SPN と対象 host の service 構成に依存します。

WriteSPN は、対象 object の servicePrincipalName attribute を変更できる権限です。よくある悪用は targeted Kerberoasting です。

attacker has WriteSPN on user
attacker adds fake SPN to user
attacker requests TGS for that SPN
attacker cracks service ticket offline
attacker removes fake SPN

ただし WriteSPN は Kerberoasting だけに限りません。既存の KCD や service routing と組み合わさると、SPN-jacking に発展します。

SPN-jacking は、SPN の所有者を移動して、KDC が ticket を暗号化する account を変える手法です。

例:

前提:
svc-front は HTTP/web01.example.local へ KCD 可能
attacker は WEB01$ と DC01$ の servicePrincipalName を変更できる
操作:
WEB01$ から HTTP/web01.example.local を削除
DC01$ へ HTTP/web01.example.local を追加
結果:
KDC は HTTP/web01.example.local を DC01$ の SPN として解決する
発行される service ticket は DC01$ の鍵で復号できる

ポイントは、service name の文字列と、SPN を所有する AD account が分離している点です。Kerberos では KDC が SPN を directory で解決し、その所有者の鍵で ticket を暗号化します。SPN の所有者を変えると、同じ SPN 文字列に対して発行される ticket の復号主体が変わります。

SPN を移動する場合は、元 object からの delete と新 object への add を正確に行う必要があります。戻し忘れは Kerberos 障害や意図しない認証先変更につながります。

  • WriteSPN を高権限 user/computer object に広く委任しない。
  • KCD の msDS-AllowedToDelegateTo と RBCD の msDS-AllowedToActOnBehalfOfOtherIdentity を定期棚卸しする。
  • SPN の重複を setspn -X などで検出する。
  • Directory Service Changes の監査を有効化し、servicePrincipalName や委任属性の変更を追跡する。
  • Tier 0 の computer object や DC に対する属性変更権限を厳格に制限する。
  • Protected Users や Account is sensitive and cannot be delegated を高権限 user に適用する。