Windowsの認証情報
1. SSPI
SSPI (Security Support Provider Interface) は、Windows OSにおいて様々なセキュリティ関連操作を実行するための共通APIです。認証、データ整合性の検証、プライバシー保護など、統合されたセキュリティサービスを提供します。これは、複数のセキュリティサポートプロバイダーへの呼び出しインターフェースとして機能します。
2. SSP
SSP (Security Support Provider) は、認証機能を実装するためのDLLファイルです。OSの起動時に、LSA (Local Security Authority) にロードされます。SSPの主な役割は、Windowsの認証機能を拡張することです。シンプルに理解すると、SSPは認証を実行し、システム権限を維持するためのDLLファイルです。以下に、Windowsシステムで一般的なSSPの種類を紹介します。
3. 主要なSSPの種類
- NTLM: Windowsネットワーク認証プロトコル。チャレンジ/レスポンス(Challenge/Response)メカニズムに基づき、ホストの認証に使用されます。
- ケルベロス: ネットワーク認証プロトコル。信頼できる第三者認証サービスとして、強力な暗号化とシングルサインオン(SSO)メカニズムを提供します。
- Negotiate: SSPIと他のSSP間でセキュリティサポートを調整するアプリケーション層です。アプリケーションがSSPIを呼び出してネットワークにログインする際、要求を処理するSSPを指定します。KerberosやNTLM SSPが指定された場合、Negotiateは要求を分析し、クライアントのセキュリティポリシーに基づいて最適なSSPを選択します。
- セキュアチャネル (SChannel): SSL/TLSレコードを使用してデータペイロードを暗号化し、主にセキュアなHTTP通信が必要なWebアプリケーションで使用されます。
- ダイジェスト認証: HTTPとSASL(Simple Authentication and Security Layer)認証に基づくチャレンジ/レスポンスプロトコルです。
- CredSSP: セキュアな認証情報を転送するネットワークプロトコル。通常、RDPやWinRMのリモート管理で、シングルサインオンとネットワークレベル認証を提供するために使用されます。
- 分散パスワード認証 (DPA): デジタル証明書を使用したインターネット認証を提供します。
- ユーザー間公開鍵暗号化 (PKU2U): ドメインに属さないシステム間で、デジタル証明書を使用したピアツーピア認証を提供します。
Windowsのアクセス制御モデル
1. アクセス制御モデルの概要
アクセス制御モデルは、Windows OSにおけるセキュリティの概念であり、アクセストークンとセキュリティ記述子の2つの主要なコンポーネントで構成されます。アクセストークンは、現在ログインしているユーザーが保持するもので、ユーザーアカウントの識別子や権限情報を含みます。セキュリティ記述子は、アクセス対象のオブジェクトが保持するもので、そのオブジェクトのセキュリティ情報を含みます。
ユーザーがログインする際、OSはアカウント名とパスワードを認証します。ログインに成功すると、システムは自動的にアクセストークンを割り当てます。このアクセストークンには、セキュリティ識別子(SID)が含まれており、ユーザーアカウントとその所属グループを識別します。プロセス(リソースへのアクセス)を作成する際、アクセストークンはコピーされ、プロセスに渡されます。プロセスは、その作成者によって設定されたセキュリティ記述子のアクセス制御リスト(ACL)に基づいて、アクセスが許可されているか、特定の操作を実行する権限があるかを判断します。
2. アクセストークン
Windowsのアクセストークンには、主トークン(Primary Token)と偽装トークン(Impersonation Token)の2種類があります。これらは、ある種の要求やログインメカニズムの認証情報を表し、ユーザーが短時間で特定の認証や権限操作の検証を実行できるようにします。Windowsシステムの各ユーザーログインアカウントには、対応するアクセストークンが生成されます。ユーザーがアカウントでOSにログインすると、システムはログインしたアカウントをセキュリティデータベース(SAM)に保存されているデータと照合して認証します。認証が成功すると、アクセストークンが生成されます。プロセスまたはスレッドがセキュリティ記述子を持つオブジェクトとやり取りする場合、システムはアクセストークンを持ち、ユーザーIDを表すためにアクセスします。
プロセスを作成する際、Windows OSのカーネルはプロセス用の主トークンを作成して割り当てます。各プロセスには1つの主トークンがあり、そのプロセスに関連するユーザーアカウントのセキュリティコンテキストを記述します。
同時に、スレッドはクライアントアカウントを偽装でき、セキュリティオブジェクトとやり取りする際にクライアントのセキュリティコンテキストを使用できます。クライアントを偽装しているスレッドは、主トークンと偽装トークンの両方を持ちます。(主トークンはプロセスに関連し、偽装トークンはスレッドに関連します。)
(1) 主トークン
主トークンは、委任トークン(Delegation Token)とも呼ばれ、対話型ログイン用の認証メカニズムです。不要な認証作業を減らすために登場し、Windows OSのカーネルによって作成され、プロセスに割り当てられるデフォルトのアクセストークンです。主トークンは、ログインプロセスから返されたセキュリティ識別子(SID)、現在のプロセスに関連するユーザーアカウントのセキュリティグループの権限リストを記述し、システムがどのセキュリティオブジェクトにアクセスできるか、どの関連システム操作を実行できるかを制御するために使用されます。
主トークンは通常、ローカルログインおよびRDP経由のリモートログインのシナリオで使用されます。完全な主トークンには、以下の内容が含まれます:
- 現在のアカウントSID
- 現在のアカウントが属するセキュリティグループのSID
- トークンのソース(どのプロセスによって作成されたか)
- 所有者のSID
- 主要グループのSID
- アクセス制御リスト
- ユーザーまたはグループが持つ権限のリスト
- 偽装レベル
- 統計情報
- 制限SID
(2) 偽装トークン
デフォルトでは、スレッドが開始されると、その属するプロセスの主トークンが自動的にスレッドにアタッチされ、そのセキュリティコンテキストとして機能します。しかし、スレッドは別の非主トークンで実行できます。このトークンは偽装トークンと呼ばれ、通常、クライアント/サーバー間の通信に使用されます。
ファイル共有のシナリオを例に挙げると、サーバーはユーザーの権限を検証するためにアクセストークンを必要としますが、ユーザーのアクセストークン(メモリにロックされており、直接アクセスできない)を直接取得することはできません。そのため、偽装トークンを生成する必要があります。
3. セキュリティ識別子 (SID)
Windows OSでは、システム内で操作を実行するエンティティを識別するために、セキュリティ識別子(Security Identifier, SID)が一般的に使用されます。
SIDは一意の文字列であり、ユーザー、ユーザーグループ、ドメイン、ドメイングループ、ドメインメンバーなどのロールを表すことができます。
SIDの構成要素
- プレフィックス: 各SIDは「S-」で始まり、セキュリティ識別子であることを示します。
- バージョン番号: 「S-」に続くのはバージョン番号で、通常は「1」で、現在のWindows NT SID形式を表します。
- 認証機関 (Authority): その後の一連の数字は、このSIDを発行した認証機関を表します。Windows NTシステムの場合、これは通常固定の「S-1-5」で、SIDがWindows NTまたはその後継(Windows 2000、XP、Server 2003以降)によって発行されたことを示します。
- サブ認証機関 (Sub-authority values): 認証機関の後に続くのは、ハイフンで区切られた一連の数値で、セキュリティ主体のタイプとインスタンスをさらに区別するために使用されます。例えば、S-1-5の後に「21」のようなシーケンス番号が続き、さらにサブ認証機関番号が続きます。
- ユーザーアカウント、グループ、およびその他の組み込みセキュリティ主体の場合、これらのサブ認証機関値が組み合わされて、一意の識別子が作成されます。
- 特定のSID例(例:`S-1-5-21-3623811015-3361044348-30300820-1013`)では、「21」の後の3つの長整数が3つのサブ認証機関値であり、最後の数字は通常、特定のユーザーまたはグループのID(RID、Relative ID)を表します。
上記のSIDの構造分析から、SIDの構造は、すべてのOSで値が変わらない、一般的なユーザーまたはグループを識別する一連の識別子であることがわかります。
4. セキュリティ記述子
セキュリティ記述子は、DACL(Discretionary Access Control List)とSACL(System Access Control List)を含みます。SACLはオブジェクトへのアクセス要求のログを記録するために使用され、DACLはACE(Access Control Entry)を含み、ユーザーのアクセス権限を設定します。セキュリティ記述子は、アクセスされる各オブジェクトにバインドされます。アクセストークンを持ってセキュリティ記述子を持つオブジェクトにアクセスすると、セキュリティ記述子は、アクセストークンがアクセス権限を持っているかどうかを検証します。
セキュリティ記述子は、SECURITY_DESCRIPTOR構造体と関連するセキュリティ情報で構成されます。以下に、セキュリティ記述子の構造と含まれるセキュリティ情報を詳しく説明します。
(1) セキュリティ記述子の構造
セキュリティ記述子は、SECURITY_DESCRIPTOR構造体と関連するセキュリティ情報で構成されます。その構造体は以下の通りです:
typedef struct _SECURITY_DESCRIPTOR {
BYTE Revision;
BYTE Sbz1;
SECURITY_DESCRIPTOR_CONTROL Control;
PSID Owner;
PSID Group;
PACL Sacl;
PACL Dacl;
} SECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR;
(2) セキュリティ記述子に含まれるセキュリティ情報
セキュリティ記述子には、以下のセキュリティ情報が含まれます。
- オブジェクトの所有者と所属グループのSID
- DACL:ACEを含み、特定のアカウントがこのオブジェクトに対して特定の操作を実行することを許可または拒否する内容を記述します。
- SACL:主にシステム監査に使用され、特定のアカウントがこのオブジェクトに対して特定の操作を実行した場合、その操作をシステムログに記録するように指定します。
- コントロールビット:セキュリティ記述子またはそのメンバーの意味を制限する一連のコントロールビット。
(3) セキュリティ記述子の表示
オブジェクトのセキュリティ記述子を表示するには、オブジェクトを右クリックし、「プロパティ」を選択し、「セキュリティ」タブを表示します。
(4) DACL
DACLはACEを含み、現在のユーザーがオブジェクトにどのような権限でアクセスするかを決定します。
システムは、以下の方法で新しいオブジェクトのDACLを構築します。
- オブジェクトの現在のDACLは、オブジェクト作成者が指定したセキュリティ記述子のDACLです。セキュリティ記述子のコントロールビットにSE_DACL_PROTECTEDビットが設定されていない限り、システムはすべての継承可能なACEを指定されたDACLにマージします。
- 作成者がセキュリティ記述子を指定しない場合、システムは継承可能なACEからオブジェクトのDACLを構築します。
- セキュリティ記述子が指定されておらず、継承可能なACEもない場合、オブジェクトのDACLは、作成者の主トークンまたは偽装トークンのデフォルトDACLから取得されます。
- 指定された、継承された、またはデフォルトのDACLがない場合、システムはDACLを持たないオブジェクトを作成し、すべてのユーザーが完全にアクセスできるようにします。
(5) SACL
SACLは主にシステム監査に使用され、どのユーザーの操作がシステムログに保存されるかを指定できます。システムは、以下の方法で新しいオブジェクトのSACLを構築します。
- オブジェクトのSACLは、オブジェクト作成者が指定したセキュリティ記述子のSACLです。セキュリティ記述子のコントロールビットにSE_SACL_PROTECTEDビットが設定されていない限り、システムはすべての継承可能なACEを指定されたSACLにマージします。SE_SACL_PROTECTEDビットが設定されている場合でも、親オブジェクトからのSYSTEM_RESOURCE_ATTRIBUTE_ACEとSYSTEM_SCOPED_POLICY_ID_ACEは、新しいオブジェクトにマージされます。
- 作成者がセキュリティ記述子を指定しない場合、システムは継承可能なACEからオブジェクトのSACLを構築します。
- 指定されたSACLも継承されたSACLもない場合、オブジェクトにはSACLがありません。
- 新しいオブジェクトにSACLを指定するには、オブジェクトの作成者はSE_SECURITY_NAME特権を有効にする必要があります。新しいオブジェクトのSACLがSYSTEM_RESOURCE_ATTRIBUTE_ACEのみを含む場合、SE_SECURITY_NAME特権は不要です。オブジェクトのSACLが継承されたACEから構築されている場合、作成者はこの特権を必要としません。アプリケーションはセキュリティ記述子の内容を直接操作できません。Windows APIは、オブジェクトのセキュリティ記述子でセキュリティ情報を設定および検索する機能を提供します。さらに、新しいオブジェクトのセキュリティ記述子を作成および初期化するための関数もあります。
(6) セキュリティ記述子文字列
セキュリティ記述子文字列は、セキュリティ記述子に保存または転送される情報のテキスト形式です。セキュリティ記述子にはバイナリ形式のセキュリティ情報が含まれています。Windows APIは、バイナリセキュリティ記述子とテキスト文字列間の変換機能を提供します。文字列形式のセキュリティ記述子は機能しませんが、セキュリティ記述子情報の保存や転送に役立ちます。セキュリティ記述子を文字列形式に変換するには、ConvertSecurityDescriptorToStringSecurityDescriptor関数を呼び出します。文字列形式のセキュリティ記述子を有効な機能的なセキュリティ記述子に変換するには、ConvertStringSecurityDescriptorToSecurityDescriptor関数を呼び出す必要があります。
トークンのセキュリティ防御
Windowsはアクセストークンを使用してユーザーIDを記録し、ユーザーの権限を検証します。各ユーザーにはアクセストークンがあります。一般的な攻撃者は、DuplicateTokenEx APIを使用してトークンを偽装窃取します。彼らはDuplicateTokenEx関数を使用して新しいトークンを作成し、既存のトークンをコピーし、新しいトークンをImpersonateLoggedOnUser関数で使用し、呼び出しスレッドがログイン済みユーザーのセキュリティコンテキストを偽装できるようにします。また、DuplicateTokenExでトークンをコピーし、CreateProcessWithTokenWを使用して、偽装されたユーザーのセキュリティコンテキストで実行される新しいプロセスを作成することもできます。
では、どのようにトークン窃取攻撃を効果的に防御するのでしょうか?以下の2つの方法があります。
1. ドメイン管理者の異機種ログインを禁止する
ドメイン管理者は、ドメインコントローラ全体で最も高い権限を持つ管理者です。ドメイン管理者のトークンが悪意のある窃取から保護されるため、ドメイン管理者の異機種ログインを禁止する必要があります。ドメイン管理者が他のマシンにログインする必要がある特別な状況が発生した場合、トークンが窃取されるのを防ぐために、すぐにトークンをクリアする必要があります。
2. 「プロセスの作成を監査」ポリシーを有効にする
「プロセスの作成を監査」ポリシーを有効にすることで、トークン操作に必要なWindows関数のアクションを監視できます。
- CMDウィンドウでgpedit.mscコマンドを入力し、グループポリシーに入ります。
- 「コンピュータの構成」→「Windows設定」→「セキュリティ設定」→「高度な監査ポリシーの構成」→「システム監査ポリシー-ローカルグループポリシーオブジェクト」→「詳細追跡」→「プロセスの作成を監査」の順に選択します。
- 「プロセスの作成を監査」インターフェースをダブルクリックして開き、成功と失敗の両方を監査するように構成します(プロセスの作成時に監査イベントが生成されます。成功監査は成功した試行を記録し、失敗監査は失敗した試行を記録します)。
- イベントビューアを使用して、アクセストークン操作を試みた記録を表示できます。
UAC (ユーザーアカウント制御)
1. UACの原理の概要
ユーザーアカウント制御(User Account Control, UAC)は、Windows Vistaで導入されたセキュリティ技術で、主な原理はアプリケーションソフトウェアのシステムレベルへのアクセスを制限することで、Windows OSのセキュリティを向上させることです。この機能は一部のユーザーから批判されてきましたが、後続のWindows OSではこの機能が維持されています。例えば、Windows 7では、マイクロソフトはこの機能を維持し、改善しました(UACのセキュリティレベルのカスタマイズ)。
2. UACのレベルの定義
Windows VistaではUACのオンとオフのオプションしかなく、後続のWindows 7ではUACが更新され、UACのホワイトリストが追加され、以下の4つのセキュリティレベルが設定され、オンとオフだけではなくなりました。ユーザーは、独自のアプリケーションシナリオのニーズに応じて、UACのセキュリティレベルを動的に調整できます。
- 第1レベル(最高レベル):Windows VistaのUACに相当し、システム設定を変更するすべての動作(インストールプログラム、Windows設定の変更など)に対して警告を表示します。
- 第2レベル(デフォルトレベル):プログラムがシステム設定を変更しようとする場合にのみUACのプロンプトが表示され、ユーザーがシステム設定を変更する場合にはプロンプトが表示されません。(一般的なプログラムやWebサイトの閲覧には、このレベルの使用が推奨されます。)
- 第3レベル:プログラムがコンピュータを変更しようとする場合にのみ通知プロンプトが表示され、ユーザーがコンピュータを設定変更する場合には通知プロンプトが表示されません。(第2レベルと基本的に同じですが、セキュアデスクトップは使用しません。)
- 第4レベル:UACは常にプロンプトを表示しない(UACを無効に相当)。
3. UACのトリガー条件
ユーザーまたはアプリケーションがUACに関連する操作を開始すると、ウィンドウがポップアップ表示され、「安全デスクトップ」状態で画面が黒くなり、続行するかどうかを尋ねます。このデスクトップはSystemの権限を持ち、他のプログラムは操作を実行する権限がありません。
(**Windowsシステムのセキュアデスクトップ(Winlogon Desktop)**:Windows OSでは、セキュアデスクトップは特別なデスクトップ環境で、ユーザーが日常的に使用するアプリケーションデスクトップとは分離されています。システムがログイン認証、ユーザーアカウント制御(UAC)のプロンプト、またはその他のセキュリティ関連のインタラクションを実行する必要がある場合、この高度にセキュアなデスクトップ環境に切り替わります。この環境では、認証されたコンポーネントとプロセスのみが実行でき、検証プロセスへの干渉や機密情報の窃取を防ぎます。例えば、UACダイアログが表示されると、背景はグレーに暗くなり、すべての非コアプロセスは、ユーザーがセキュアデスクトップ上のプロンプトに応答するまで一時停止されます。)
以下の操作はUACをトリガーします:
- 管理者としてプログラムを実行する
- Windows Updateを構成する
- ユーザーアカウントを追加または削除する
- ユーザーのアカウントタイプを変更する
- ゲスト(Guest)アカウントを構成する(Windows 7および8.1)
- UAC設定を変更する
- ActiveXをインストールする
- プログラムをインストールまたは削除する
- デバイスドライバーをインストールする
- ペアレンタルコントロールを設定する
- システムドライブのルートディレクトリ、Program Files(x86およびx64)ディレクトリ、またはWindowsディレクトリを変更する
- 他のユーザーフォルダを表示する
- ファイル共有またはストリーミングを構成する
- ペアレンタルコントロールパネルを構成する
- Microsoft Management Consoleコンソールと.mscで終わるプログラムを実行する(一部の.mmcプログラムを除く)
- システム復元プログラムを実行する。
- ディスクデフラグメンテーションプログラムを実行する。
- レジストリエディタを実行または変更する。
- 表示言語をインストールまたはアンインストールする(Windows 7)
- Windows評価プログラムを実行する
- Windows電源プログラムを構成する
- Windows機能を構成する
- 日付と時刻コンソールを実行する
- アクセシビリティを構成する
4. UACのユーザーログインプロセス
Windows OSのリソース全体にはACLがあり、このACLは、異なる権限を持つユーザー/プロセスが異なるリソースにアクセスできるかどうかを決定します。スレッドがオブジェクトにアクセスしようとすると、システムは、そのスレッドが保持するアクセストークンと、アクセスされるオブジェクトのセキュリティ記述子のDACLルールをチェックします。セキュリティ記述子にDACLルールが存在しない場合、システムはスレッドが直接アクセスすることを許可します。図は、スレッドがオブジェクトにアクセスするプロセス全体を示しています。
通常、アカウントでOSにログインすると、トークンが生成され、持っている権限が記録されます。管理者権限でログインすると、標準ユーザーアクセストークンと完全な管理者アクセストークンの2つのアクセストークンが生成されます。
Administratorユーザーでログインする場合(UACが有効になっている)、管理コンソールで「ユーザーの追加または削除」操作を実行したいとします。UACは「安全デスクトップ」をポップアップ表示します。状況に応じて「はい」または「いいえ」を選択できます。この理由は、アクセスの前に、システムがプロセスが保持するアクセストークンと、アクセスされるオブジェクトのセキュリティ記述子のDACLルールをチェックし、保持するトークンとルールが正しいかどうかを確認するためです。私たちが持っているアクセストークンは、保護された状態の管理者アクセストークンであるため、プロセスの要求がUAC操作をトリガーすると、UACは通知をポップアップ表示し、許可するかどうかを尋ねます。「はい」ボタンをクリックすると、実際にはプロセスに管理者アクセストークンを送信し、管理者の状態が「保護された状態」から「昇格された状態」に変わります。昇格された状態の管理者アクセストークンを使用して、コンピュータに対して変更操作を実行できます。
ログインしているユーザーが標準ユーザーの場合、Windowsは標準ユーザーアクセストークンをユーザーに割り当てます。標準ユーザーアクセストークンを持つプロセスにアクセスする場合、プロセスがUAC操作をトリガーすると、通知がポップアップ表示され、管理者パスワードを入力するように求められます。この時点では、管理者アクセストークンを持っていませんが、管理者パスワードを入力することで、管理者のアクセストークンを取得し、操作を実行できます。管理者パスワードを入力するプロセスは、本質的には、管理者の資格情報を使用して標準ユーザーに権限を与えるプロセスです。
5. UACの仮想化
UACの仮想化は、リダイレクション操作とも呼ばれます。ユーザーの権限がプログラムの要求する権限に達していない場合、リダイレクション操作が実行されます。仮想化は、ファイルの仮想化とレジストリの仮想化の2つの部分で構成されます。例えば、プログラムが`C:\\Program Files\\Contoso\\Settings.ini`に書き込みを試みるが、ユーザーがそのディレクトリへの書き込み権限を持っていない場合、この書き込み操作は`C:\\Users\\Username\\AppData\\Local\\VirtualStore\\Program Files\\contoso\\settings.ini`にリダイレクトされます。レジストリの場合、プログラムが`HKEY_LOCAL_MACHINE\\Software\\Contoso`に書き込みを試みると、自動的に`HKEY_CURRENT_USER\\Sofware\\Classes\\VirtualStore\\Machine\\Software\\Contoso`または`HKEY_USERS\\UserSID_Classes\\VirtualStore\\Machine\\Software\\Contoso`にリダイレクトされます。
Windowsのセキュリティ認証メカニズム
1. 認証とは何か
認証は、人物やオブジェクトのIDを検証するプロセスであり、主な目的は、人物やオブジェクトが実際のネットワーク環境における真のユーザーであるかどうかを検証することです。実際のネットワーク環境では、通常、暗号化操作が検証に使用されます。ユーザーのみが知っている暗号化操作のキーを使用し、認証交換サーバーは、署名と既知の暗号化キーを比較することで認証試行を行います。Windows OSでは主に、NTLM認証(ローカル認証とネットワーク認証を含む)およびケルベロス認証の2つの認証方法があります。
2. NTLMローカルログイン認証
Windows OSでユーザーを作成する際、そのユーザーのパスワードはSAM(Security Account Manager, セキュリティアカウントマネージャ)ファイルに暗号化されて保存されます。これは、Windows OSがユーザーアカウントのセキュリティを管理するためのメカニズムです。SAMファイルの保存パスは以下の通りです。
%SystemRoot%\\system32\\config\\sam
このSAMファイルを、ローカルコンピュータのすべてのユーザーログイン資格情報を保存するデータベースと理解できます。すべてのユーザーのログイン名とパスワードなどのデータ情報が保存されています。このファイルは、パスワードをNTLMハッシュの方法で暗号化し、SAMファイルに保存します。SAMファイルに保存されているパスワードはすべて暗号化されたハッシュ値です。ユーザーが作成したIDでシステムにログインする場合、システムはローカルSAMファイルに保存されているパスワードを読み取り、入力されたパスワードと照合します。照合が成功すればログイン成功、失敗すればログイン失敗です。ローカル認証プロセスは、ユーザーが入力したパスワードとSAMデータベース内の暗号化されたハッシュ値を照合するプロセスです。
4. ハッシュパスワードの保存方法
Windows OSはユーザーが入力した平文パスワードを保存せず、暗号化してSAMデータベースに保存します。ユーザーがアカウントパスワード資格情報でログインする場合、システムはまずユーザーが入力したアカウントパスワード資格情報をNTLMハッシュに変換し、変換後のハッシュをSAMデータベースのNTLMハッシュと照合します。照合が成功すればログイン成功、失敗すればログイン失敗です。
Windows OSの暗号化ハッシュアルゴリズムは2種類あり、1つはLMハッシュ暗号化アルゴリズム、もう1つはNTLMハッシュ暗号化アルゴリズムで、後者の方が現在より一般的に使用されています。
(1) LMハッシュ
LMハッシュは、早期のWindowsシステムで使用されていたパスワード保存方法で、非常に古いものです。LMハッシュは、以前に使用されていたアルゴリズムとして、多くの問題と欠陥があります。Windows OSは継続的に進化しており、Windows VistaとWindows Server 2008から、LMハッシュ暗号化アルゴリズムをNTLMハッシュ暗号化アルゴリズムに切り替え始めました。
(2) NTLMハッシュ
NTLM(NT LAN Manager)ハッシュは、Windowsがセキュリティと互換性のために設計したハッシュ暗号化アルゴリズムです。マイクロソフトは、LMハッシュ暗号化アルゴリズムに存在する多くのセキュリティ問題を解決するために、Windows NT 3.1でNTLMアルゴリズムを導入しました。現在、Windows VistaとWindows Server 2008以降のOSバージョンでは、NTLMハッシュアルゴリズムがデフォルトで有効になっています。
3. NTLMハッシュアルゴリズムの原理
現在、ほとんどのWindows OSで使用されているパスワードハッシュはNTLMハッシュです。NTLMハッシュ値は、Hex、Unicode、MD4の3段階のエンコード暗号化を経て得られる、文字と数字で構成される32ビットのハッシュ値です。以下にNTLMハッシュの具体的なアルゴリズムを示します。
- ユーザーパスワードをHexエンコードし、16進数形式にします。
- 得られた16進数の結果をUnicodeエンコードに変換します。
- Unicodeに変換した結果をMD4暗号化アルゴリズムで暗号化します。
# -*- coding: utf-8 -*-
import hashlib
import binascii
# ユーザーパスワードを定義
user_pass = "123456"
# 16進数形式に変換
hex_result = binascii.b2a_hex(user_pass.encode('utf-8'))
print("Hexエンコード結果: " + hex_result.decode('utf-8'))
# Unicode形式に変換
unicode_result = hex_result.decode('utf-8').encode('utf-16le')
print("Unicode変換結果: " + unicode_result.hex())
# MD4アルゴリズムで暗号化
md4_hash = hashlib.new('md4', unicode_result).digest()
print("MD4暗号化結果: " + binascii.hexlify(md4_hash).decode('utf-8'))
4. ローカルログイン認証の流れ
Windows OSがログインページに入り、ユーザーがSASキーシーケンス(Ctrl+Alt+Del)を押すと、システムはデフォルトのデスクトップからWinlogonデスクトップに切り替え、LogonUIを起動してユーザーにアカウントとパスワードの入力を促します。ユーザーがアカウントとパスワード情報を入力すると、WinlogonはLsaLogonUserを介してログイン情報を認証パッケージ(MSV1_0)に渡します。MSV1_0認証パッケージは、ログインユーザーのアカウントとパスワードのハッシュ値をローカルSAM Serverデータベースに送信して照合します。照合が成功すると、MSV1_0認証パッケージはユーザーのSIDおよびユーザーが属するグループのSIDを取得し、LSA Serverに送信します。LSA Serverはこの一意のSID情報を使用してセキュリティアクセストークン(アクセストークンにはユーザーのSID、グループSID、および割り当てられた権限が含まれます)を作成し、トークンのハンドルとログイン情報をWinlogonに送信します。Winlogonは、ユーザーのログインプロセスを続行します。
5. NTLMネットワーク認証
1. NTLM認証プロトコル
NTLMは、チャレンジ/レスポンス検証メカニズムに基づくドメイン上のホスト認証プロトコルです。ユーザーホストがドメインに関連するサービスにアクセスを要求すると、サービスはユーザーホストにチャレンジを送信し、ユーザーホストにその認証トークンを使用して検証を行うよう要求し、その結果をサービスに返します。サービスは結果を検証するか、ドメインコントローラに検証を送信できます。サービスまたはドメインコントローラがユーザーホストのIDトークンを確認すると、ユーザーホストはそのサービスを使用できます。現在、NTLMはマイクロソフトによって推奨されておらず、多くの新しい暗号化方式をサポートしていないため、マイクロソフトはケルベロス認証プロトコルを推奨の認証方法として使用しています。
2. NTLM認証の流れ
NTLMはWindowsネットワーク認証プロトコルの1つで、NTLMハッシュを資格情報として認証に使用し、チャレンジ/レスポンス(Challenge/Response)のメッセージ交換モードを採用しています。NTLM認証プロトコルは3つのステップで構成されています。
- ネゴシエーション(Negotiate): 主に両者のプロトコルバージョンを確認するために使用されます。
- チャレンジ(Challenge): チャレンジ/レスポンスです。
- 検証(Auth): 主にチャレンジ完了後に検証結果を確認します。
3. NTLMプロトコルの種類
NTLMプロトコル認証には、NTLM v1とNTLM v2の2つのバージョンがあり、そのうちNTLM v2が最も広く使用されています。
- NTLM v1: NTLM v1プロトコルは、NTLMの最初のバージョンで、サーバーとクライアント間のチャレンジ/レスポンスでNTハッシュとLMハッシュの両方を使用します。
- NTLM v2: NTLM v2はNTLM v1の改良版であり、認証プロトコルとセキュリティ認証メカニズムを強化することで、NTLMのセキュリティを向上させます。NTLM v1とNTLM v2の違いは、Challengeと暗号化アルゴリズムにあります:NTLM v1のChallengeは8ビットの数値で、主な暗号化アルゴリズムはDESです;NTLM v2のChallengeは16ビットの数値で、主な暗号化アルゴリズムはHMAC-MD5です。
4. NTLMプロトコルの認証方法
NTLMプロトコルの認証方法は、対話型NTLM認証と非対話型NTLM認証の2つに分類できます。
- (1) 対話型NTLM認証
対話型NTLM認証は、通常、ユーザーが認証を要求するクライアントシステム、ユーザーパスワード情報を保持するドメインコントローラーの2つのシステムを含み、主にユーザーがクライアントにログインするシナリオで使用されます。 - (2) 非対話型NTLM認証
非対話型NTLM認証は、通常、認証を要求するクライアントシステム、リソースを保存するサーバー、サーバーを代表して認証計算を実行するドメインコントローラーの3つのシステムを含み、この認証方法は対話型で資格情報を提供する必要がなく、ユーザーは1回ログインするだけで、すべての信頼関係のあるアプリケーションシステムおよび共有リソースにアクセスできます。
5. ワークステーション環境でのNTLMの動作メカニズム
以下に、NTLMがワークステーション環境でどのように動作するかを詳しく説明します。
- ユーザーがアカウントとパスワードを入力してクライアントにログインすると、クライアントはユーザーのアカウントとパスワードをNTLMハッシュに変換してキャッシュし、元のパスワードは破棄されます(Windowsのセキュリティ基準により、元のパスワードはいかなる状況でもキャッシュされません)。
- クライアントに正常にログインしたユーザーがサーバーのリソースにアクセスしようとすると、クライアントはType1ネゴシエーションメッセージをサーバーに送信して認証を要求します。このネゴシエーションメッセージには、クライアントがサポートし、サーバーが要求する機能のリストが含まれています。
- クライアントから送信されたType1ネゴシエーションメッセージの認証要求を受け取ったサーバーは、16ビットのランダムな数値、いわゆる「チャレンジ」(Challenge)または「ナンス」(Nonce)を生成し、Type2チャレンジメッセージでクライアントに応答します。この応答メッセージには、サーバーがサポートする同意リストおよびサーバーによって生成された16ビットのChallengeコードが含まれています。
- サーバーから送信されたChallengeコードを受け取ったクライアントは、以前に変換してキャッシュしたNTLMハッシュを使用してChallengeを暗号化計算し、Responseを取得し、Type3認証メッセージでサーバーのチャレンジに応答します。この認証メッセージには、Response、Username、および暗号化されたChallengeが含まれています。
- クライアントから暗号化されたChallengeを受け取ったサーバーは、自身のパスワードのNTLMハッシュを使用してChallengeを暗号化計算し、Net NTLMハッシュ値を取得し、クライアントから送信されたNet NTLMハッシュ値と照合します。照合が成功すれば、クライアントが入力したパスワードが正しいことを証明し、認証が成功します;失敗すれば、認証が失敗します。
6. ドメイン環境でのNTLMの動作メカニズム
以下に、NTLMがドメイン環境でどのように動作するかを詳しく説明します。
- ドメインユーザーがアカウントとパスワードを入力してクライアントにログインすると、クライアントはユーザーのアカウントとパスワードをNTLMハッシュに変換してキャッシュし、元のパスワードは破棄されます。
- クライアントに正常にログインしたユーザーがサーバーのリソースにアクセスしようとすると、クライアントはType1ネゴシエーションメッセージをサーバーに送信して認証を要求します。このネゴシエーションメッセージには、クライアントがサポートし、サーバーが要求する機能のリストが含まれています。
- クライアントから送信されたType1ネゴシエーションメッセージの認証要求を受け取ったサーバーは、16ビットのランダムな数値を生成し、Type2チャレンジメッセージでクライアントに応答します。この応答メッセージには、サーバーがサポートする同意リストおよびサーバーによって生成された16ビットのChallengeコードが含まれています。
- サーバーから送信されたChallengeコードを受け取ったクライアントは、以前に変換してキャッシュしたNTLMハッシュを使用してChallengeを暗号化計算し、Responseを取得し、Type3認証メッセージでサーバーのチャレンジに応答します。この認証メッセージには、Response、Username、および暗号化されたChallengeが含まれています。
- クライアントから暗号化されたChallengeを受け取ったサーバーは、Netlogonプロトコルを介してDC(ドメインコントローラ)にクライアントの検証要求を送信し、同時にType1、Type2、Type3をすべてDCに送信します。
- DCは、Usernameに基づいてADからユーザーアカウントとパスワードのNTLMハッシュをクエリし、このNTLMハッシュを使用してChallengeを暗号化計算して得られたNetNTLMハッシュ値を、サーバーが受信したNetNTLMハッシュ値と照合および検証し、最終的に照合検証結果をサーバーに送信します。
- サーバーはDCからのフィードバック結果に基づいて、クライアントの最終的な検証を行います。
6. ケルベロスドメイン認証
1. ケルベロスの概要
ケルベロスは、マサチューセッツ工科大学(MIT)が開発したネットワーク認証プロトコルで、主な利点は強力な暗号化とシングルサインオン(SSO)メカニズムを提供できることです。信頼できる第三者認証サービスとして、ケルベロスは、ホストOSに依存しない認証を実現するために、従来の暗号技術(共有キーなど)を使用し、ホストアドレスに基づく信頼を必要とせず、ネットワーク上のすべてのホストの物理セキュリティを要求しません。また、ネットワーク上で送信されるデータパケットが任意に読み取られ、変更され、データを挿入される可能性があると仮定しても、通信セキュリティを保証します。
2. ケルベロスの通信ポート
- TCP/UDPの88(Kerberos)ポート:認証とチケットの発行
- TCP/UDPの464ポート:Kerberos Kpaswd(パスワードリセット)プロトコル
- LDAP:389
- LDAPS:636
3. ケルベロスの専門用語
| 用語 | 役割 |
| AS | 認証サービス(クライアントのIDを検証) |
| KDC | キー配布センター(ドメイン内で最も重要なサーバー、ドメインコントローラ) |
| TGT | ユーザーIDを証明するチケット(TGSへのアクセスチケット) |
| TGS | チケット発行サービス |
| ST | サービスへのアクセスチケット |
| krbtgt | 各ドメインにはkrbtgtアカウントがあり、このアカウントはKDCサービスアカウントで、TGTを作成する際に暗号化に使用されます。そのパスワードはランダムに生成されます。 |
| Principal | 認証主体 Name\[/Instance\]@REALM |
| PAC | 特権属性証明書(ユーザーのSID、ユーザーが属するグループ) |
| SPN | サービスプリンシパル名 |
| Session Key | 一時セッションキーa、クライアントとTGSのみが知り、ケルベロス認証において非常に重要です。 |
| Server Session Key | 一時セッションキーb、クライアントとサーバーのみが知り、ケルベロス認証において非常に重要です。 |
| Authenticator | SessionKeyで暗号化され、クライアントの主体名とタイムスタンプを含み、有効期間は2分間です。 |
| Replay Cache | Kerberos5はReplay Cacheを追加し、サービスは2分以内に受信したAuthenticatorをキャッシュし、Authenticatorがキャッシュ内のものと同じ場合、拒否します。 |
4. ケルベロスの役割とコンポーネント
ケルベロスの役割とコンポーネントは以下の通りです。
- KDC: KDCはADDS(ADディレクトリサービス)の一部で、各コントローラーで実行されます。ドメイン内のユーザーとコンピューターにセッションチケットと一時セッションキーを提供し、そのサービスアカウントはkrbtgtです。
- AS: 認証サーバーで、初期認証を実行し、ユーザーにチケット発行チケット(TGT)を発行します。
- TGS: チケット発行サービスで、ユーザーのIDチケットの権限に基づいてサービスチケット(ST)を発行します。
- クライアント: リソース(共有ファイルの表示、データベースのクエリ、リモート接続など)にアクセスするユーザークライアントは、アクセスする前に認証が必要です。
- サーバー: ドメイン内のコンピューター上の特定のサービスに対応し、各サービスには一意のSPNがあります。
5. ケルベロス認証の流れの概要
ケルベロスはチケットベースの認証方法です。クライアントがサーバーのサービスにアクセスする必要がある場合、ST(Service Ticket、サービスチケット)を取得する必要があります。つまり、クライアントはサービスにアクセスする前にSTを準備する必要があり、サービスがSTを検証した後でアクセスできます。しかし、このチケットは直接取得できず、TGT(Ticket Granting Ticket、チケット発行チケット)というIDを証明するチケットが必要です。つまり、クライアントはSTを取得する前に、まずIDを証明するTGTを取得する必要があります。TGTとサービスチケットSTは、KDCによって発行されます。KDCはドメインコントローラーで実行されるため、TGTとSTはドメインコントローラーによって発行されます。ケルベロス認証の流れは以下の通りです。
- ユーザーがログインする際、時間スタンプをNTLMハッシュで暗号化して、パスワードを知っていることをKDCに証明します。このステップは「事前認証」と呼ばれます。
- 事前認証が完了すると、認証サーバーは、有限時間有効なTGTをユーザーに発行します。
- 特定のサービスを認証したい場合、ユーザーはTGTをKDCのTGSに提示します。TGTが有効で、ユーザーがそのサービスの権限を持っている場合、ユーザーはTGSからSTを受け取ります。
- ユーザーはSTをアクセスしたいサービスに提示できます。サービスはユーザーを認証し、TGSに含まれるデータに基づいて認可決定を行います。
6. ケルベロス認証の流れの詳細
(1) AS-REQとAS-REP(クライアントとASのやり取り)
- AS-REQ: ドメイン内のユーザーがクライアントでアカウントとパスワードを入力し、ドメイン内のサービスにアクセスしたい場合、クライアントはASにAuthenticatorの認証要求を送信します。この認証要求には、クライアントのNTLMハッシュで暗号化されたタイムスタンプ、ユーザー名、ホストIP、およびその他のパラメータ情報(メッセージタイプ、バージョン番号、ネゴシエーションオプションなど)が含まれており、認証要求の証拠として機能します。ASが本物かどうかを検証する必要があるため、クライアントのNTLMハッシュを使用して暗号化します。ASが本物であれば、AS-REQを正常に復号できます。
- AS-REP: KDC内のASがクライアントのAS-REQ要求を受け取ると、KDCはクライアントユーザーがADのホワイトリストに存在するかどうかをチェックします。存在し、クライアントのキーを使用してAuthenticatorの事前認証要求を正常に復号できる場合、ASはランダムなsessionKey(CT_SK)を生成し、ユーザーパスワードのNTLMハッシュを使用してsessionKey(CT_SK)を暗号化し、デフォルトアカウントkrbtgtのNTLMハッシュを使用してsessionKey、クライアント情報、クライアントタイムスタンプ、認証の有効期限を暗号化し、TGTを取得し、クライアントにAS-REP応答パケットを送信します。
(2) TGS-REQとTGS-REP(クライアントとTGSのやり取り)
- TGS-REQ: ASから送信された応答パケットを受け取ったクライアントは、自身のNTLMハッシュを使用して2つの暗号文の内容を復号し、TGSとの通信に使用するキーであるsessionKey(CT-SK)およびsessionKey ClientをキャッシュしたTGTを取得します。その後、クライアントはsessionKey(CT_SK)を使用してAuthenticator認証要求を暗号化し、KDC内のTGSに送信し、サーバーのアクセス権限を取得します。Authenticator認証には、クライアントの主体名、タイムスタンプ、クライアントが送信したSS主体名、有効期間、Authenticator、およびTGTが含まれます。
- TGS-REP: TGSがTGS-REQから送信されたAuthenticator認証要求を受け取ると、SS主体名を検証します。検証が成功すると、TGSはkrbtgtアカウントのNTLMハッシュを使用してTGTを復号し、sessionKeyを抽出します。同時に、TGTの有効期限、Authenticator認証のクライアント主体名、およびTGT内のものが一致しているかどうかなど、クライアントを検証します。検証が成功すると、TGSは新しい文字列sessionKeyをランダムに生成し、クライアントに以下の2つの内容を返します。
- 古いsessionKeyで暗号化されたSS主体名、Timestamp(タイムスタンプ)、Lifetime(有効期間)、新しいsessionKey
- サーバーのハッシュで暗号化されたチケットで、主にSSキーで暗号化されたクライアント主体名、SS主体名、IP_List、Timestamp、Lifetime、新しいsessionKeyが含まれます。
(3) AP-REQとAP-REP(クライアントとサーバーのやり取り)
- AP-REQ: クライアントがTGSからの応答を受け取ると、sessionKeyを使用してServer session Keyを復号し、それをAuthenticator(クライアント主体名、Timestamp、ClientAuthenticator、Service Ticketを含む)に暗号化し、SS(サーバー)に送信します。
- AP-REP: サーバーがクライアントから送信されたAP-REQ要求を受け取ると、サービスキーを使用してSTを復号し、その中からService sessionKey情報を抽出します。同時に、TGTの有効期限、Authenticator認証のクライアント主体名、およびTGT内のものが一致しているかどうかなど、クライアントを検証します。検証が成功すると、サーバーはAP-REQ要求パケットのネゴシエーションオプションの構成にサーバーのIDを検証する必要があるかどうかをチェックします。サーバーのIDを検証するように構成されている場合、サーバーは復号されたAuthenticatorを再度Service sessionKeyで暗号化し、AP-REP応答パケットをクライアントに送信します。クライアントはキャッシュされたService sessionKeyを使用して復号し、以前の内容と完全に一致する場合、サーバーがアクセスしているサーバーが同じService sessionKeyを持っていることを証明します。
ケルベロスに関するさらなる知識については、以下を参照してください。