【実務・中級編】 WindowsのレジストリによるLM/NTLM認証の無効化とKerberosの強制 – インフラ・ネットワーク & クラウドセキュリティ防御ガイド

認証の「遺物」を葬れ:LM/NTLMを無効化し、Kerberosへ完全移行するための実践的ガイド

「まだNTLMを使っているのか? それはもう、攻撃者に『どうぞ侵入してください』と招待状を送っているのと同じだ」

現場でインシデント対応をしていると、いまだに20年前のプロトコルに足をすくわれるシステムに遭遇する。特にWindows環境において、LM(LAN Manager)やNTLM(NT LAN Manager)認証は、現代のネットワーク攻撃においては「素通り」の代名詞だ。今日は、なぜこれらを殺し、Kerberosへ強制移行すべきなのか、そして現場でどう設定すべきかを深掘りする。

1. なぜNTLMは「攻撃者の遊園地」なのか

攻撃者がなぜNTLMを執拗に狙うのか。理由はシンプルで、「認証情報が奪いやすいから」だ。

NTLM認証のプロセスには「チャレンジ・レスポンス」という仕組みがあるが、これが極めて脆弱だ。攻撃者は中間者攻撃(MitM)を仕掛け、クライアントとサーバーの間に割って入る。特に Responder というツールを使えば、ネットワーク上の「NTLM認証情報」をいとも簡単にキャプチャし、ハッシュとして抽出できる。

一度ハッシュを手に入れれば、たとえパスワードそのものを知らなくても、Pass-the-Hash(PtH)攻撃で別のサーバーへ横展開(ラテラルムーブメント)が可能になる。Kerberosであれば、チケット(TGT)の有効期限や、暗号化アルゴリズムの強度で防御できるが、NTLMにはそのバリアがない。

2. レジストリによる「LM/NTLM」の封印

OSレベルでこれらを無効化するには、レジストリ操作が最も確実だ。以下の設定は、ドメイン環境でKerberosを強制し、レガシーな認証を切り捨てるための「最低限の防波堤」だ。

レジストリ設定ファイル(.reg)

以下の内容を disable_ntlm.reg として保存し、検証環境でテストした後に適用してほしい。

Windows Registry Editor Version 5.00

; LM応答を送信しない(送信してもLMハッシュのみ)
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa]
"LmCompatibilityLevel"=dword:00000005

; NTLMv1の無効化とNTLMv2の強制、Kerberosのみの利用を促進
"RestrictSendingNTLMTraffic"=dword:00000002

; NTLM認証の入力を完全に拒否(※影響範囲が非常に大きいため、必ず事前検証を!)
"NetworkSecurityLevel"=dword:00000004
  • 警告: LmCompatibilityLevel を 5 に設定すると、古いNASやレガシーなプリンター、あるいは認証をKerberosに対応していない古い業務アプリが即座に死ぬ。まずは 3 (NTLMv2のみ送信)から始め、徐々に引き締めるのが運用の鉄則だ。

3. アプリケーション層からのアプローチ

インフラ側で防御するのと同時に、アプリケーション開発側でも「認証のモダン化」を意識する必要がある。例えば、Webアプリケーションから社内APIを叩く際、安易に NTLM認証 を使った接続ロジックを組んではいけない。

PythonでActive Directory連携を行う場合、requests-ntlm などで妥協せず、Kerberos 認証(GSSAPI)を必須にする実装を心がけるべきだ。

PythonによるKerberos認証の実装例

gssapi ライブラリを使用して、認証プロトコルを限定するサンプルだ。

import requests
from requests_kerberos import HTTPKerberosAuth

def secure_api_request(url):
    # Kerberos認証を強制する(NTLMへのフォールバックを無効化)
    # mutual_authentication=True で相互認証を必須にする
    auth = HTTPKerberosAuth(mutual_authentication=True, sanitize_mutual_error_response=True)
    
    try:
        response = requests.get(url, auth=auth, timeout=5)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        # 認証失敗ログを詳細に残し、インシデント検知を迅速化する
        print(f"Auth Error: {e}")
        return None

4. 現場の教訓:いきなり「遮断」してはいけない

最後に、ホワイトハッカーとしての忠告だ。どれだけ「セキュリティ的に正しい」設定でも、現場の業務を止めてしまえば、それは「脆弱な運用」よりも罪が深い。

1. 監査モードを先行させる: Audit NTLM authentication のポリシーを有効にし、どのサーバーがどのクライアントからNTLMで接続されているか、イベントログ(Event ID: 4624, 8004等)を最低1週間は追跡しろ。
2. Kerberos委任の確認: Kerberosに切り替えると、Double-Hop 問題(WebサーバーからDBサーバーへ認証を委任する処理)でつまづくことが多い。「制約付き委任(Constrained Delegation)」の設定が必須になることを忘れるな。
3. レガシーの切り捨て: どうしてもKerberosに対応できない古いアプリがあるなら、そのサーバーをVLANで隔離し、ゼロトラストの原則に従って厳密にアクセス制御せよ。

認証プロトコルの要塞化は、「痛みを伴う作業」だ。だが、その痛みは、将来発生するであろう大規模なランサムウェア攻撃から組織を守るための、必要経費である。まずは、君の環境の LmCompatibilityLevel を確認することから始めてほしい。

コメント

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