Active Directory (AD) 環境のセキュリティにおいて、Kerberos認証は中心的な役割を果たしています。しかし、設定の不備や古い機能の利用は、攻撃者に悪用される可能性があります。その代表的な例が「AS-REP Roasting」攻撃であり、この攻撃を実行するためのツールとして広く知られているのが Impacket スイートに含まれる GetNPUsers.py
スクリプトです。
このブログ記事では、GetNPUsers.py
の使い方、AS-REP Roasting攻撃の仕組み、そしてその対策について、初心者にも分かりやすく、かつ深く掘り下げて解説します。ツールの詳細なオプションから、実際の攻撃シナリオ、そして防御策まで網羅的に扱います。
AS-REP Roasting攻撃とは何か? 🔥
AS-REP Roastingは、Active Directory環境におけるKerberos認証の脆弱性を悪用する攻撃手法です。具体的には、ユーザーアカウントの設定で「Kerberos事前認証を要求しない (Do not require Kerberos preauthentication)」オプション (DONT_REQ_PREAUTH
フラグ) が有効になっているアカウントを標的とします。
通常のKerberos認証フローでは、ユーザーは自身のパスワードハッシュで暗号化されたタイムスタンプを含む認証サーバー要求 (AS-REQ) をドメインコントローラー (DC) / キー配布センター (KDC) に送信します。DC/KDCは、保存しているユーザーのパスワードハッシュを使ってタイムスタンプを復号し、認証を検証します。これが「事前認証」です。
しかし、「事前認証を要求しない」設定が有効になっている場合、攻撃者はパスワードを知らなくても、対象ユーザーになりすましてAS-REQを送信できます。 DC/KDCは事前認証を行わずに、ユーザーのパスワードハッシュで暗号化されたデータを含む認証サーバー応答 (AS-REP) メッセージ (具体的にはTGT: Ticket Granting Ticket) を返してしまいます。
攻撃者はこのAS-REPメッセージを取得し、そこに含まれる暗号化された部分 (ユーザーのパスワードハッシュで暗号化されている) をオフラインで解析 (クラッキング) します。比較的弱いパスワードが設定されている場合、ブルートフォース攻撃や辞書攻撃によって元のパスワードを特定できる可能性があります。これがAS-REP Roasting攻撃の核心です。
この攻撃は、ネットワークに接続できれば、必ずしもドメインの認証情報を必要としない場合があるため (LDAP Null Bindが可能など)、初期アクセス段階で認証情報を窃取する目的で利用されることがあります。また、低権限のドメインユーザーアカウントを乗っ取った攻撃者が、さらなる権限昇格や横展開 (Lateral Movement) の足がかりとして利用するケースも見られます。例えば、2021年12月にDiavolランサムウェアグループ、2024年8月にBlackSuitランサムウェアグループがこの手法を用いた攻撃を行っていたことが報告されています。
ImpacketとGetNPUsers.pyの概要 🛠️
Impacketは、ネットワークプロトコルを扱うためのPythonクラスのコレクションです。元々はSecureAuthによって開発・公開されていましたが、現在はFortraによってメンテナンスされています。SMB、MSRPC、Kerberos、LDAPなど、さまざまなプロトコルを実装しており、ペネトレーションテストやセキュリティ研究において非常に強力なツールスイートとして利用されています。
GetNPUsers.py
は、Impacketに含まれるサンプルスクリプトの一つで、まさにAS-REP Roasting攻撃を実行するために設計されています。主な機能は以下の通りです。
- Active Directoryドメイン内のユーザーアカウントを検索する。
- 「Kerberos事前認証を要求しない」設定が有効になっているユーザーを特定する。
- 特定したユーザーに対してAS-REPメッセージ (TGT) の取得を試みる。
- 取得したハッシュデータを、HashcatやJohn the Ripperなどのパスワードクラッキングツールで利用可能な形式で出力する。
ImpacketはPythonで書かれているため、Linux、macOS、Windowsなど、Pythonが動作する様々な環境で利用できます。
Impacketのインストール
Impacketを使用するには、まずPythonとpip (Pythonのパッケージインストーラー) がインストールされている必要があります。インストールはpipコマンドで簡単に行えます。
pip install impacket
もしくは、GitHubからソースコードをクローンしてインストールすることも可能です。
git clone https://github.com/fortra/impacket.git
cd impacket
pip install .
インストール後、impacket-GetNPUsers
(または環境によっては GetNPUsers.py
) コマンドが利用可能になります。
GetNPUsers.pyの使い方と主要オプション ⚙️
GetNPUsers.py
の基本的な構文は以下の通りです。
impacket-GetNPUsers [ドメイン名]/[ユーザー名[:パスワード]] [オプション]
必須引数
-
[ドメイン名]/[ユーザー名[:パスワード]]
: ターゲットとなるドメインを指定します。- 通常、AS-REP Roastingを行う際には、特定のユーザー名やパスワードは不要で、ドメイン名のみを指定します (例:
MYDOMAIN.LOCAL/
)。末尾のスラッシュを忘れないようにしてください。これは、スクリプトにユーザー名が提供されていないことを示すためです。 - もしドメインコントローラーへのLDAP接続に認証が必要な場合は、有効なドメインユーザーの認証情報 (ユーザー名とパスワード) を指定します (例:
MYDOMAIN.LOCAL/validuser:Password123
)。 -no-pass
オプションと共に使用することで、パスワードプロンプトを回避できます。
- 通常、AS-REP Roastingを行う際には、特定のユーザー名やパスワードは不要で、ドメイン名のみを指定します (例:
主要なオプション
GetNPUsers.py
には多くのオプションがありますが、AS-REP Roastingで特によく使われるものを紹介します。
オプション | 説明 |
---|---|
-dc-ip <IPアドレス> |
ターゲットとするドメインコントローラーのIPアドレスを指定します。省略した場合、指定されたドメイン名 (FQDNである必要があります) からDNSで解決を試みます。指定することが推奨されます。 |
-request |
非常に重要なオプションです。このオプションを指定すると、事前認証が不要なユーザーが見つかった場合に、実際にAS-REPメッセージ (TGT) を要求し、クラック可能なハッシュを取得します。このオプションを指定しない場合、脆弱なアカウントをリストアップするだけで、ハッシュは取得しません。 |
-format <hashcat | john> |
取得したハッシュの出力形式を指定します。hashcat (デフォルト) または john (John the Ripper) を指定できます。使用するクラッキングツールに合わせて選択します。 |
-outputfile <ファイル名> |
取得したハッシュを指定されたファイルに保存します。指定しない場合は、標準出力に表示されます。多数のハッシュが見つかる可能性がある場合に便利です。 |
-usersfile <ファイル名> |
テスト対象とするユーザー名が記述されたファイルを指定します (1行に1ユーザー名)。これを指定しない場合、スクリプトはLDAP経由でドメイン内の全ユーザーを検索し、事前認証が不要なユーザーを自動的に特定しようとします。LDAP検索が許可されていない環境や、特定のユーザーリストに対してテストしたい場合に有効です。 |
-no-pass |
パスワード認証を使用しない場合に指定します。特に -k (Kerberos認証/Pass-the-Cache) オプションと併用する場合や、認証情報なしでドメイン名だけを指定する場合に役立ちます。これを指定しないと、パスワードの入力を求められることがあります。 |
-k |
Kerberos認証を使用します。KRB5CCNAME 環境変数に設定されたKerberosチケットキャッシュファイル (ccache) を使って認証 (Pass-the-Cache) を試みます。有効なキャッシュがない場合や環境変数が未設定の場合は、引数で指定されたパスワードや -hashes オプションで指定されたNTLMハッシュ (Overpass-the-Hash) を使ってKerberos認証を行います。 |
-hashes <LMハッシュ:NTハッシュ> |
パスワードの代わりにLMハッシュおよびNTLMハッシュを指定して認証 (Pass-the-Hash / Overpass-the-Hash) を行います。 |
-aesKey <16進数キー> |
パスワードの代わりにAESキー (AES128またはAES256) を指定してKerberos認証 (Pass-the-Key) を行います。 |
-debug |
デバッグモードを有効にします。より詳細な情報やトレースバックが出力され、問題解決に役立ちます。 |
-ts |
出力の各行の先頭にタイムスタンプを追加します。ログ分析などに便利です。 |
実践的な使用例 💻
例1: ドメイン内の脆弱なユーザーをリストアップ (ハッシュ取得なし)
まず、-request
オプションなしで実行し、どのユーザーが事前認証不要に設定されているかを確認します。
impacket-GetNPUsers mydomain.local/ -dc-ip 192.168.1.100
これにより、UserAccountControl
属性で DONT_REQ_PREAUTH
フラグが立っているユーザーの一覧が表示されます (もし見つかれば)。
例2: 脆弱なユーザーのAS-REPハッシュを取得し、Hashcat形式で出力
次に、-request
オプションを追加して、実際にハッシュを取得します。出力形式はデフォルトで hashcat
です。
impacket-GetNPUsers mydomain.local/ -dc-ip 192.168.1.100 -request
成功すると、以下のような形式でハッシュが出力されます。
$krb5asrep$23$user1@MYDOMAIN.LOCAL:f8a3f1...[長いハッシュ文字列]...
$krb5asrep$23$service-account@MYDOMAIN.LOCAL:e3b0c4...[長いハッシュ文字列]...
例3: ハッシュをJohn the Ripper形式でファイルに保存
impacket-GetNPUsers mydomain.local/ -dc-ip 192.168.1.100 -request -format john -outputfile asrep_hashes.john
asrep_hashes.john
というファイルに、John the Ripperで読み込める形式のハッシュが保存されます。
例4: ユーザーリストファイルを使用して特定のユーザーを対象にする
users.txt
というファイルにユーザー名をリストアップしておき、そのユーザーだけを対象に攻撃を試みます。
# users.txt の内容例:
# user1
# user2
# service-account
impacket-GetNPUsers mydomain.local/ -dc-ip 192.168.1.100 -request -usersfile users.txt
例5: ドメイン認証情報を使用してLDAP検索を行う
LDAP検索に認証が必要な場合、有効なドメインアカウント (例: lowprivuser
) の認証情報を使用します。
impacket-GetNPUsers mydomain.local/lowprivuser:Password123 -dc-ip 192.168.1.100 -request
この場合でも、攻撃対象となるのは事前認証が不要なユーザーであり、lowprivuser
自身ではありません (もちろん lowprivuser
も事前認証不要であれば対象になります)。
取得したハッシュの解析 (クラッキング) 🔓
GetNPUsers.py
で取得したAS-REPハッシュは、そのままではパスワードではありません。これはユーザーのパスワードから派生したキーで暗号化されたデータであり、オフラインでクラッキングを試みる必要があります。代表的なクラッキングツールとして Hashcat と John the Ripper があります。
Hashcatを使用する場合
HashcatでAS-REPハッシュ (krb5asrep,etype 23) をクラックするには、モード 18200
を使用します。
hashcat -m 18200 asrep_hashes.hashcat wordlist.txt
-m 18200
: HashcatにAS-REP (etype 23) ハッシュモードを指定します。asrep_hashes.hashcat
:GetNPUsers.py
で-format hashcat
を指定して保存したハッシュファイル。wordlist.txt
: パスワード辞書ファイル。強力な辞書やルールを使用することで、クラック成功率が向上します。
John the Ripperを使用する場合
John the Ripper (JtR) もAS-REPハッシュのクラックに対応しています。
john --wordlist=wordlist.txt asrep_hashes.john
--wordlist=wordlist.txt
: 使用するパスワード辞書ファイルを指定します。asrep_hashes.john
:GetNPUsers.py
で-format john
を指定して保存したハッシュファイル。
JtRは通常、ハッシュ形式を自動で認識します。
クラックに成功すると、対象ユーザーの平文パスワードが判明し、攻撃者はそのアカウントになりすまして更なる活動を行うことが可能になります。
AS-REP Roasting攻撃への対策と緩和策🛡️
AS-REP Roasting攻撃のリスクを軽減するためには、以下の対策を講じることが重要です。
-
Kerberos事前認証の強制: これが最も効果的な対策です。Active Directory内のすべてのユーザーアカウント (特にサービスアカウントや特権アカウント) で「Kerberos事前認証を要求しない」設定が無効になっていること (つまり、事前認証が要求される状態であること) を確認・徹底します。
- PowerShellを使用して、事前認証が無効になっているアカウントを検出できます。
Get-ADUser -Filter {UserAccountControl -band 4194304} -Properties SamAccountName, UserAccountControl | Select-Object SamAccountName, @{Name='PreAuthDisabled';Expression={$_.UserAccountControl -band 4194304}}
- 互換性の問題などでやむを得ず事前認証を無効にする必要があるアカウントが存在する場合、そのアカウントには非常に強力で長いパスワードを設定し、権限を最小限に制限する必要があります。
- 定期的に監査を行い、意図せず事前認証が無効化されたアカウントがないかチェックする体制を整えます。
- PowerShellを使用して、事前認証が無効になっているアカウントを検出できます。
-
強力なパスワードポリシーの適用: たとえAS-REPハッシュが窃取されたとしても、パスワードが十分に長く複雑であれば、オフラインでのクラッキングは非常に困難になります。
- パスワードの長さ (15文字以上を推奨)、複雑性 (大文字、小文字、数字、記号を含む)、定期的な変更を強制します。
- よく使われる単語や単純なパターンを避けるようにユーザー教育を行います。
- パスワード履歴を enforcing し、同じパスワードの再利用を防ぎます。
-
アカウント監査と監視の強化:
- Active Directoryの監査ログ (特にイベントID 4738: ユーザーアカウントの変更) を監視し、「事前認証を要求しない」設定への変更を検知します。
- Kerberos認証イベント (イベントID 4768: Kerberos認証チケット(TGT)が要求された) を監視し、特に事前認証なし (Ticket Encryption Type: 0x17 などで示唆される) でのTGT要求が短時間に多数発生していないか、通常とは異なるソースからの要求がないかなどを分析します。
- 失敗したログオン試行 (イベントID 4625) とイベントID 4768を関連付けて分析し、認証情報なしでのAS-REP Roasting試行を検出することも有効です。
- Microsoft Defender for Identityのようなセキュリティソリューションは、AS-REP Roastingを含む多くのActive Directory関連の攻撃を検知する機能を持っています。
- 最小権限の原則の適用: ユーザーやサービスアカウントには、業務に必要な最小限の権限のみを付与します。これにより、万が一アカウントが侵害された場合の影響を限定できます。
まとめ 🏁
Impacket の GetNPUsers.py
は、Active Directory 環境における AS-REP Roasting 攻撃を容易に実行できる強力なツールです。この攻撃は、「Kerberos事前認証を要求しない」設定が有効になっているアカウントのパスワードハッシュを窃取し、オフラインでのクラッキングを可能にします。
攻撃者はこの手法を用いて初期アクセスの認証情報を得たり、権限昇格を図ったりします。防御側としては、Kerberos事前認証の強制、強力なパスワードポリシーの適用、そして適切な監査と監視体制の構築が不可欠です。
GetNPUsers.py
のようなツールとその背景にある攻撃手法を理解することは、自組織のActive Directory環境を保護するための第一歩となります。常に最新の脅威情報を把握し、適切な対策を講じることが、安全なITインフラを維持する上で極めて重要です。 💪
コメント