Windows 11 22H2のスマート アプリ コントロールの挙動 #2

Windows 11 22H2でスマート アプリ コントロールという機能が導入されました。前回はアプリ自身の起動の挙動を確認しました。今回は、この機能によって、アプリからAPIを呼び出したときの挙動はどのように変わるのかを確認します。

スマート アプリ コントロール (Smart App Control)

まずは、「スマート アプリ コントロール」の復習です。

スマート アプリ コントロールとは、マイクロソフトのサイトから引用すると以下の通りです。

Smart App Control は、悪意のあるアプリや信頼されていないアプリをブロックすることで、新しい脅威や新たな脅威を含むマルウェアからの大幅な保護を追加します。 Smart App Control は、望ましくない可能性のあるアプリをブロックするのにも役立ちます。これは、デバイスの実行速度が低下したり、予期しない広告を表示したり、不要な追加のソフトウェアを提供したり、予期しないその他の操作を行ったりする可能性があるアプリです。

(マイクロソフトのサイトより引用)

「信頼されていないアプリ」をブロックし、脅威からの保護をするための仕組みです。

「信頼されていないアプリ」を「信頼されるアプリ」にするためには、アプリのモジュールに電子署名を付与することが、近道の一つでした。

前回の投稿で、電子署名の有り無しで、Windowsがアプリを起動するときの挙動がどのように変化するか確認しました。

今回は、起動をブロックされなかったアプリが、Win32 APIを使って、プロセスを作成したり、モジュールを読み込んだときの挙動にどのような影響があるかどうかを調べます。

スマート アプリ コントロールを有効にしたWindows 11 22H2

スマート アプリ コントロールを有効にしたWindows 11 22H2は、次の手順で用意します。

  1. Windows 11 22H2をクリーンインストールする
  2. 初回起動後、スマートアプリコントロールの設定を「評価」から「オン」に変更する
「スマート アプリ コントロールの設定」画面 (オン モード)

スマート アプリ コントロールを有効にしたPCでアプリの起動

スマート アプリ コントロールを有効にしたWindows PCでは、アプリから新たなアプリを起動したり、モジュールをロードしたりするときの、APIが失敗するかどうかは、アプリのモジュールに電子署名を付与してあるかどうかなどで挙動が異なります。

アプリから呼び出すAPIに関する挙動を確認できるように、テスト用アプリを用意しました。

Smart App Control Test App (スマート アプリ コントロール テスト アプリ)

このテストアプリには、4つのモジュールが含まれています。

  • SmartAppControlTest32_unsigned.exe (32ビットアプリ、電子署名 無し)
  • SmartAppControlTest32_signed.exe (32ビットアプリ、電子署名 有り)
  • SmartAppControlTest64_unsigned.exe (64ビットアプリ、電子署名 無し)
  • SmartAppControlTest64_signed.exe (64ビットアプリ、電子署名 有り)

32ビットアプリ、および、64ビットアプリの、電子署名「あり」(*_signed.exe)と「なし」(*_unsigned.exe)です。

アプリから呼び出すAPIの挙動を確認するためには、信頼されるアプリとして認識されやすい電子署名付きのモジュールを使います。32ビットアプリ、64ビットアプリで同じ挙動であったため、どちらを起動してもかまいません。

このテストアプリでテストできること

アプリからのプロセス起動、ライブラリーの読み込みに対する挙動を確認できるように、ShellExecuteEx() / CreateProcess() / LoadLibrary() の呼び出しを試すことができます。

また、スマート アプリ コントロールの最後のエラーメッセージを確認することができます。

テストアプリのメイン画面

テストアプリのメイン画面は以下の通りです。

Smart App Control Test App 1.0.0

使用方法

4つのモジュールファイルは、署名の有無、および、アプリのビット数の違いだけであり、アプリの機能は全く同じです。

起動すると、ウィンドウには6つのボタンがあります。

  • Browse
  • ShellExecuteEx()
  • CreateProcess()
  • LoadLibrary()
  • Query last error event
  • Close

また、下部は、Resultエリアとなっており、結果が表示されます。

スマート アプリ コントロールを有効にしていないWindows 11の場合は、どのボタンも正常に動作しますが、スマートアプリコントロールを有効にしたWindows 11 22H2以降の場合は、電子署名を付与されていないモジュールに対する操作は失敗することがあることを確認できます。

Browse ボタン

ShellExecuteEx() / CreateProcess() / LoadLibrary() ボタンで使用するファイルを指定します。exeファイルやdllファイルなどの実行ファイル、または、ドキュメントファイル(ShellExecuteEx()のみ対象)を指定可能です。

ShellExecuteEx() ボタン

Browseボタンで指定した実行ファイル、または、ドキュメントファイルをShellExecuteEx() APIを使って開きます。APIの実行結果は、Resultエリアに表示されます。APIの呼び出しが失敗した場合は、スマート アプリ コントロールのエラーイベントの読み出しも行います。

CreateProcess() ボタン

Browseボタンで指定した実行ファイルをCreateProcess() APIを使って開きます。APIの実行結果は、Resultエリアに表示されます。APIの呼び出しが失敗した場合は、スマート アプリ コントロールのエラーイベントの読み出しも行います。

LoadLibrary() ボタン

Browseボタンで指定した実行ファイルをLoadLibrary() APIを使って開きます。APIの実行結果は、Resultエリアに表示されます。APIの呼び出しが失敗した場合は、スマート アプリ コントロールのエラーイベントの読み出しも行います。

Query last error event ボタン

実行や読み込みがスマート アプリ コントロールで阻止されたときにイベントログに出力される、Windowsイベントログの最後(一番新しい)のエラーのアイテムをResultエリアに表示します。

Close ボタン

アプリを閉じます。

Resultエリア

Resultエリアは、二つの結果表示領域があります。

上部の表示エリアは、呼び出したAPIの実行結果が表示されます。

下部の表示エリアは、APIの実行がスマート アプリ コントロールで阻止されたときにイベントログに出力される、Windowsイベントログの最後(一番新しい)のエラーイベントを表示されます。

ShellExecuteEx()の動作確認

信頼されていないアプリ(exeファイル)を指定して、ShellExecuteEx()ボタンをクリックすると、ShellExecuteEx()がスマートアプリコントロールによってブロックされる場合の挙動が確認できます。

アプリの実行がスマートアプリコントロールによりブロックされた場合は、ShellExecuteEx()は、FALSEを返します。GetLastError()で、エラーコードを取得すると、4551 または 4559 が得られます。winerror.h によると、4551の定義名はERROR_SYSTEM_INTEGRITY_POLICY_VIOLATIONであり、4559の定義名はERROR_SYSTEM_INTEGRITY_REPUTATION_OFFLINEとなります。

CreateProcess()の動作確認

信頼されていないアプリ(exeファイル)を指定して、CreateProcess()ボタンをクリックすると、CreateProcess()がスマートアプリコントロールによってブロックされる場合の挙動が確認できます。

アプリの実行がスマートアプリコントロールによりブロックされた場合は、CreateProcess()は、FALSEを返します。GetLastError()で、エラーコードを取得すると、4551 または 4559 が得られます。winerror.h によると、4551の定義名はERROR_SYSTEM_INTEGRITY_POLICY_VIOLATIONであり、4559の定義名はERROR_SYSTEM_INTEGRITY_REPUTATION_OFFLINEとなります。

LoadLibrary()の動作確認

信頼されていないモジュール(dllファイル)を指定して、LoadLibrary()ボタンをクリックすると、LoadLibrary()がスマートアプリコントロールによってブロックされる場合の挙動が確認できます。

アプリの実行がスマートアプリコントロールによりブロックされた場合は、LoadLibrary()は、NULLを返します。GetLastError()で、エラーコードを取得すると、4551 または 4559 が得られます。winerror.h によると、4551の定義名はERROR_SYSTEM_INTEGRITY_POLICY_VIOLATIONであり、4559の定義名はERROR_SYSTEM_INTEGRITY_REPUTATION_OFFLINEとなります。

エラーコードとエラー定義名

スマートアプリコントロールによって、APIが失敗したときのエラーコードはどのAPIでも、ERROR_SYSTEM_INTEGRITY_POLICY_VIOLATION (4551)または、ERROR_SYSTEM_INTEGRITY_REPUTATION_OFFLINE (4559)であることがわかりました。

ERROR_SYSTEM_INTEGRITY_POLICY_VIOLATION (4551)

このERROR_SYSTEM_INTEGRITY_POLICY_VIOLATIONの定義は、winerror.hに以下のように定義されています。

//
// MessageId: ERROR_SYSTEM_INTEGRITY_POLICY_VIOLATION
//
// MessageText:
//
// Your organization used Device Guard to block this app. Contact your support person for more info.
//
#define ERROR_SYSTEM_INTEGRITY_POLICY_VIOLATION 4551L

ERROR_SYSTEM_INTEGRITY_REPUTATION_OFFLINE (4559)

このERROR_SYSTEM_INTEGRITY_REPUTATION_OFFLINEの定義は、winerror.hに以下のように定義されています。

//
// MessageId: ERROR_SYSTEM_INTEGRITY_REPUTATION_OFFLINE
//
// MessageText:
//
// System Integrity policy has been violated.  Unable to contact reputation service for unknown file.
//
#define ERROR_SYSTEM_INTEGRITY_REPUTATION_OFFLINE 4559L

このエラーコードは、PCがオフライン状態で、マイクロソフトのクラウドに接続できず、ファイルが信頼できるかどうかを判定できないときに使用されます。

なお、一度でもマクロソフトクラウドにつないで、判定できたファイルに関しては、このエラーコードは使われません。2度目以降のファイルのアクセスでは、オフラインであっても、このエラーコードは使われず、過去の判定結果が利用されます。

System Integrity Error codes

スマート アプリ コントロールは、WindowsのEnterprise版で提供していた「Windows Defender Application Control (WDAC) 」を、一般向けのWindowsのすべてのSKUでも利用できるようにしたものです。そのため、エラーコードも同じ値が利用されているようです。

winerror.hによると、これらのエラーは、4550から4559までの値をとるようです。

///////////////////////////////////////////////////
//                                               //
//             System Integrity Error codes      //
//                                               //
//                 4550 to 4559                  //
///////////////////////////////////////////////////

今回の確認では、4551と4559のみのエラーコードしか遭遇しませんでした。しかし、この範囲のエラーコードは、返されることがあると想定した方がよさそうです。

特に、以下のエラーコードは、ブロックされたときに使われるエラーコードの可能性が高そうです。

#define ERROR_SYSTEM_INTEGRITY_POLICY_NOT_SIGNED 4553L
#define ERROR_SYSTEM_INTEGRITY_REPUTATION_MALICIOUS 4556L
#define ERROR_SYSTEM_INTEGRITY_REPUTATION_PUA 4557L
#define ERROR_SYSTEM_INTEGRITY_REPUTATION_DANGEROUS_EXT 4558L

ブロックの要因になったファイルの詳細情報

エラーコードで、APIの呼び出しが、スマートアプリコントロールによりブロックされたことがわかります。しかし、エラーコードだけだと、どのファイルが信頼されず、ブロックされたのかわかりません。例えばアプリを起動しようとした場合は、EXEファイルが信頼されずブロックされたのか、関連するいずれかのDLLファイルが信頼されずブラックされたのか、などの直接の要因がわかりません。

では、その情報はどこかにあるのでしょうか?

あります。Windows イベント ログとして記録されています。

プロバイダー: Microsoft-Windows-CodeIntegrity
チャネルパス: Microsoft-Windows-CodeIntegrity/Operational

です。イベントビューアーであれば、「アプリケーションとサービス ログ」の「Microsoft\Windows\CodeIntegrity」の配下にあります。

テストアプリのResultエリアの下側は、Windowsイベント ログのスマートアプリコントロール(Microsoft-Windows-CodeIntegrity/Operational)のログ情報を表示します。

「各API(ShellExecuteEx / CreateProcess / LoadLibrary)」ボタンによって、APIが失敗したときは、ログが反映されるのを2秒程度待ってから、最後のイベントログを表示します。

「Query last error event 」ボタンでは、Windowsイベント ログのスマートアプリコントロールに関連するエラーの一番最後のものを表示します。

スマートアプリコントロールによるAPIのブロックの結果のまとめ

スマートアプリコントロールが有効化されると、ShellExecuteEx() / CreateProcess() APIによるEXEファイルの起動は、EXEファイル、および、依存するDLLファイルがすべて信頼されていないと、ブロックされることがわかりました。

また、LoadLibrary()も、信頼されていないDLLファイルに対しては、ブロックされます。

ブロックを早く解除する近道は、モジュールファイルに電子署名することです。モジュールファイルへの電子署名の付与は今までも重要でした。今回、スマート アプリ コントロールが導入されたことにより、モジュールファイルへの電子署名の付与は、以前にも増して必要なものとなりました。

コードサイニング証明書

モジュールに電子署名を付与するためには、コードサイニング証明書(コードサイニング電子証明書)が必要となります。

電子証明書と電子署名については過去の投稿で扱いました。我々は、モジュールに電子署名するためのコードサイニング証明書には、セクティゴ(旧社名COMODO) の電子証明書を利用しています。

セクティゴのコードサイニング証明書

ここの電子証明書は、

  • 他に比べて安めである
  • 法人だけでなく、個人事業主や個人でも取得可能

などの特徴があり、購入を検討するのもよいと思います。


今回の投稿では、Windows 11 22H2で導入されたスマート アプリ コントロールが、アプリから呼び出すAPIをブロックする挙動を確認したことの説明でした。

“Windows 11 22H2のスマート アプリ コントロールの挙動 #2” への1件の返信

コメントを残す