おい、ちょっと手を止めてこっちを向いてくれ。
日々のインフラ運用やアプリケーション開発、本当にお疲れ様。WAFのチューニングに追われたり、突然のアラート対応に肝を冷やしたり……エンジニアの仕事はいつだってスリルに満ちている。だがな、セキュリティの現場で何百件ものインシデントを踏んできた私から言わせてもらうと、「境界防御(Perimeter Defense)」の時代はとうの昔に終わった。VPNを突破され、ランサムウェアやLiving off the Land(Lolbins)と呼ばれる正規ツールを用いた攻撃者が内部ネットワークに入り込んだ瞬間、従来のセキュリティ対策は紙細工のように崩れ去る。
じゃあ、最終的に何が組織の資産を守るのか?
それが、今回深掘りする「エンドポイントにおける実行制御」、そしてWindows環境における「AppLocker」による徹底的なホワイトリスト運用だ。
今回は、暗号理論(コード署名)がいかにこの実行制御の根幹を支えているかという原理原則から、現場で即座に使えるAppLockerのガチガチなポリシー設定まで、一切の妥協なしで叩き込んでやる。心してついてこい。
—
1. なぜ「動かさせない」ことが最強の防御なのか?
セキュリティの世界では、長らく「脆弱性をすべて塞ぐ」という幻想が信じられてきた。しかし、コードが存在する限り、ゼロデイ脆弱性や複雑な設定ミスは必ず生まれる。アプリケーション開発の現場で、どれだけセキュアコーディングを心がけても、外部依存ライブラリ(npmやpipのパッケージなど)のサプライチェーン攻撃を完全に防ぐことは至難の業だ。
ここで発想を転換する。「攻撃者が侵入すること」を前提(Assume Breach)にし、侵入した後に「任意のペイロードを実行させない」ことに全リソースを張るのだ。
ブラックリストの限界と、暗号署名ベースのホワイトリスト
従来のアンチウイルス(AV)やEDRの一部機能は、既知のマルウェアのハッシュ値や振る舞いを検知する「ブラックリスト方式」をとっていた。しかし、攻撃者は難読化やパッカー、ポリモーフィックな手法を使って、秒速でシグネチャをすり抜けてくる。
これに対抗する唯一にして最強の盾が、「デフォルト拒否(Default Deny)」をベースにしたホワイトリスト運用である。そして、そのホワイトリストの判定基準として信頼の根拠(Trust Anchor)になるのが、「公開鍵暗号に基づくデジタル署名」だ。
開発者が作成したバイナリやスクリプトに対し、信頼された認証局(CA)や社内PKIの秘密鍵で署名を行い、OS側(カーネルおよびエグゼキューター)がその公開鍵で検証する。
- RSAや楕円曲線暗号(ECC)の数学的保証により、バイナリが途中で1バイトでも改ざんされていれば署名検証は即座に失敗する。
- 署名のない野良の実行ファイル(PowerShellスクリプト、EXE、DLLなど)は、たとえ管理者権限を持つユーザーが実行しようとも、OSレベルで強制終了される。
この仕組みをWindows環境で極限まで高めたのが、AppLockerである。
—
2. 攻撃者の視点:なぜ彼らはAppLockerを恐れるのか?
実際のインシデントレスポンスの現場を思い出してほしい。レッドチームや実際のサイバー犯罪グループがターゲットの端末に初期侵入を果たしたあと、彼らが最初に行うのは「足場の確保(Persistence)」と「特権昇格(Privilege Escalation)」、そして「ツールの持ち込み(Ingress Tool Transfer)」だ。
通常、彼らは攻撃用ツール(Mimikatzや Cobalt Strikeのビーコンなど)をC2サーバーからダウンロードし、C:\Users\Public\ や C:\Temp\ などの書き込み可能なディレクトリに配置して実行しようとする。
もし、ここでAppLockerが適切に構成されていればどうなるか?
[攻撃者] 悪意あるEXEを配置 ──> 実行試行 ──> [AppLocker] ホワイトリスト(署名・パス)照合
│
├─> 一致(マイクロソフト純正等) -> 実行許可
└─> 不一致(野良バイナリ) -> 実行即時ブロック & イベントログ記録
攻撃者は、書き込み権限のある場所にファイルを置けても、「実行する権利」を奪われているため、そこで手足を縛られることになる。彼らがよく使うバイナリレス攻撃(Lolbins:certutil.exe や mshta.exe を悪用する手法)に対しても、AppLockerのルールで細かく制御をかけることで、攻撃のキルチェーンを完全にハングさせることができる。
—
3. 【実務設定】AppLockerによる堅牢な実行許可ポリシーの構築
ここからは、実務でそのまま投入できるAppLockerの設定と、その運用上の勘所を解説する。
AppLockerのポリシーは、グループポリシー(GPO)またはローカルセキュリティポリシーを通じて適用する。今回は、現場で最も堅牢とされる「デフォルトで全拒否し、安全なパスと有効な署名を持つものだけを許可する」設計のXMLポリシーの構造と設定手順を示す。
ステップ1: 基本ルールの設計方針
安易に「Program Files以下なら何でも動かしてよし」とすると、書き込み権限のミスをついてそこに悪意あるDLLやEXEを置かれる「DLLハイジャック」や「サブフォルダ悪用」の踏み台にされる。そのため、以下の原則を厳守する。
1. Publisher(発行元)ルールを最優先する:信頼できるパブリッシャー(Microsoftや特定のサードパーティベンダー)の署名があるものだけを許可。
2. Path(パス)ルールは限定的に:どうしても署名がないレガシーアプリや社内製スクリプトのために、書き込み不可の厳密なディレクトリパスのみを指定。
3. Default Rules(既定のルール)の適用:システム管理者(Administrators)には制限を緩めすぎないよう注意(誤って自分たちの首を絞めないよう、管理者の除外設定は慎重に行う)。
ステップ2: AppLockerポリシーのXMLサンプル
以下のXMLは、実務の基盤構築でベースとなる厳格なポリシーのサンプルだ。これをGPOのエクスポート機能等にインポート、またはチューニングして利用してほしい。
<?xml version="1.0" encoding="UTF-8"?>
<AppLockerPolicy Version="1">
<!-- 実行ファイル(EXE / DLL)のポリシー定義 -->
<RuleCollection Type="Exe" EnforcementMode="Enabled">
<!-- 1. 組み込みのビルトイン管理者には一時的な回避を許可(運用時は慎重に検証) -->
<FilePublisherRule Id="a9e1059f-d747-4340-81bb-d52f79f4c398" Name="Windowsの署名付きファイルの全許可" Description="OSの動作に必要なMicrosoft署名ファイルを信頼します" UserOrGroupSid="S-1-1-0" Action="Allow">
<Conditions>
<FilePublisherCondition PublisherName="O=MICROSOFT CORPORATION, L=REDMOND, S=WASHINGTON, C=US" ProductName="*" BinaryName="*">
<BinaryVersionRange LowSection="*" HighSection="*" />
</FilePublisherCondition>
</Conditions>
</FilePublisherRule>
<!-- 2. 社内開発ツールの証明書(独自PKI)による署名許可の例 -->
<FilePublisherRule Id="b8f2060a-e858-5451-92cc-e60g80g5d409" Name="社内開発部署名済みアプリの許可" Description="社内PKIでコード署名されたバイナリの実行を許可します" UserOrGroupSid="S-1-1-0" Action="Allow">
<Conditions>
<FilePublisherCondition PublisherName="CN=My Company Internal Code Signing CA, O=MyCompany, C=JP" ProductName="CoreSystem*" BinaryName="*">
<BinaryVersionRange LowSection="*" HighSection="*" />
</FilePublisherCondition>
</Conditions>
</FilePublisherRule>
<!-- 3. 上記以外はすべて拒否(Default Deny)は自動的に適用される -->
</RuleCollection>
<!-- スクリプト(PowerShell / VBScript / JS)のポリシー定義 -->
<RuleCollection Type="Script" EnforcementMode="Enabled">
<!-- スクリプトは原則として署名必須、または特定の管理スクリプトフォルダのみ許可 -->
<FilePassRule Id="c7c3071b-f969-6562-03dd-f71h91h6e510" Name="管理用スクリプトディレクトリの許可" Description="C:\AuthorizedScripts\ 以下のスクリプトのみ実行を許可(フォルダは標準ユーザー書き込み不可であること)" UserOrGroupSid="S-1-1-0" Action="Allow">
<Conditions>
<FilePathCondition Path="C:\AuthorizedScripts\*" />
</Conditions>
</FilePassRule>
</RuleCollection>
<!-- DLLの制御ポリシー(パフォーマンスとセキュリティのバランスを見て有効化を推奨) -->
<RuleCollection Type="Dll" EnforcementMode="AuditOnly">
<!-- まずは監査モード(AuditOnly)で既存アプリが壊れないかログを監視する -->
</RuleCollection>
</AppLockerPolicy>
—
4. 現場でハマる「落とし穴」とインシデント回避のTips
ここまで読んで、「よし、明日から全端末でAppLockerを強制有効化しよう!」と思ったそこのあなた。少し待て。現場のセキュリティチーフとして、これだけは忠告しておきたい。
事前の「監査モード(Audit Only)」をスキップして強制有効化(Enforced)にすると、翌朝に出社した一般社員や開発者から阿鼻叫喚の嵐が巻き起こる。 社内ニッチな業務アプリ、古い会計ソフト、あるいは独自のインストーラーが使う一時フォルダ内のEXEなどが片っ端からブロックされ、業務が完全停止する。これが「セキュアだが使えないシステム」の典型的な失敗パターンだ。
導入の正しいステップ(Gunslinger Workflow)
1. 監査モード(Audit Only)でデプロイする
AppLockerの設定で、強制モードではなく「監査のみ」を指定してポリシーを全端末に配布する。これにより、アプリがブロックされる代わりに、イベントビューア(Applications and Services Logs > Microsoft > Windows > AppLocker > EXE and DLL)に「もしブロックしていたら、このアプリが動きませんでしたよ」というログ(Event ID: 8002など)が記録される。
2. ログを収集・分析する
SIEMやログ収集基盤(Elasticsearch, Splunkなど)を使い、社内で実際に使われている正当なバイナリのリストを吸い上げる。
3. ホワイトリストを洗練させる
正当な業務アプリのパブリッシャー証明書やハッシュを、例外ルールとしてしっかりと登録する。
4. 段階的強制(Enforcement)への移行
部署ごとに徐々に監査モードから「強制モード(Enabled)」へと切り替えていく。
—
5. おわりに:セキュリティは「完全な静寂」ではなく「レジリエンス」
暗号理論が証明する数学的な信頼と、AppLockerのようなエンドポイントの実行制御が噛み合ったとき、組織のセキュリティポスチャーは劇的に跳ね上がる。攻撃者が侵入したとしても、彼らにできることは「何も実行できずにログを吐き続けること」だけだ。
セキュリティは、魔法の杖を振って一発で完璧になるものじゃない。泥臭いログの分析、開発現場との根気強い調整、そして何より「攻撃者がどうやってすり抜けてくるか」という悪意のシミュレーションの積み重ねだ。
君たちが構築するシステムが、サイバー脅威に対して圧倒的な堅牢性を持つことを期待している。さあ、コードを書こう。そして、守りを固めよう。
コメント