ククログ

株式会社クリアコード > ククログ > Win32 app isolationでアプリケーションを分離する方法

Win32 app isolationでアプリケーションを分離する方法

はじめに

ChronosというChromiumベースの業務ブラウザの開発をしている橋田です。 2023年6月14日、MicrosoftからWin32 app isolationという環境分離技術が発表されました。

今回このWin32 app isolationについて調査したので、使い方について紹介していきたいと思います。

なお、2023年12月現在、Win32 app isolationはOpen Previewであり、使用方法について今後変更される可能性があります。

Win32 app isolationとは

Win32 app isolationは、AppContainerというコンテナ技術を利用し、アプリケーションの権限を制限し、アプリケーションのゼロデイ脆弱性を利用した攻撃などからユーザーを保護することを目的としています。 今回はWin32 app isolationの具体的な使い方について紹介していきます。

Win32 app isolationの実態は、マニフェストによりアクセス権限の制限を行ったMSIXパッケージファイルです。 Win32 app isolationのドキュメントを参照すると、以下の手順でアプリケーションのWin32 app isolation化が可能です。 それぞれの手順について紹介していきます。

  • 環境
    • Windows 11
    • Windows insider version >= 25357
      • Windowsインサイダープログラムに参加
      • Canaryチャネルを受信
  • 手順
    • 専用のMSIXパッケージツールの準備
    • MSIXパッケージの作成
      • 署名ファイルの作成
      • Win32アプリケーションのMSIXパッケージ化
    • MSIXパッケージのIsolated Win32アプリケーション化
    • Application Capability Profilerを使用して、必要な権限の設定
      • デベロッパーモードの設定
      • プロファイリングの実行
      • 作成されたマニフェストの適用

Windows insider version >= 25357 にアップデート

Windows Insider Programに登録します。 登録にはMicrosoftアカウントが必要なので、Microsoftアカウントを登録しておきます。

Windows Insider Programに登録後、Windowsの[設定] -> [Windows Update] -> [Windows Insider Program]からCanaryチャネルを受信します。 その後Windows Updateを実行するとCanaryチャネルのビルドが適用され、Windows insider version >= 25357になります。 現在のバージョンはwinverコマンドなどで確認できます。

専用のMSIXパッケージツールの準備

Win32 app isolationから、最新のACP-MPT-{version}.zipをダウンロードします。 Win32 app isolation向けにカスタマイズされたMSIX Packaging Toolもその中に含まれているため、そちらをインストールします。 ここで、このMSIX Packaging Toolのバージョンが古い場合があり、その場合、Windows Updateが実行されると自動的に最新バージョンにアップデートされる場合があります。 最新バージョンにアップデートされると、カスタマイズされていない状態になってしまうため、実行時にはMSIX Packaging Toolのバージョンを確認してください。

作業中は一時的にWindows Updateを停止する方が良いかもしれません。

ここでは、ダウンロードしたZIPファイルの展開先をC:\test\ACP-MPT-v0.1.1とします。

MSIXパッケージの作成

証明書の作成、インストール

MSIXパッケージを実行するには、原則として証明書が必要です。

パッケージに署名するのに必要な証明書を作成します。 ここでは、テスト用に自己署名証明書を作成します。

https://learn.microsoft.com/ja-jp/windows/msix/package/create-certificate-package-signing

上記内容に沿ってNew-SelfSignedCertificateを使って証明書を作成し、Export-PfxCertificateで.pfxファイルにエクスポートします。

次に.cerファイルを書き出し、信頼されたユーザーとして証明書をインストールします。

Export-Certificate -cert Cert:\CurrentUser\My\<証明書番号>” -FilePath C:\<証明書名>.cer

書き出した.cerファイルをダブルクリックし、証明書ストアの[証明書をすべての次のストアに配置する]->[参照]->[信頼されたユーザー]を選択し、信頼されたユーザーとして証明書をインポートします。

Win32アプリケーションのMSIXパッケージ化

MSIXパッケージの作成方法に従い、MSIXパッケージを作成します。

OSSのテキストエディターであるNotepad++を例に考えます。 ダウンロードページから最新のインストーラーをダウンロードします。

ここでは、ダウンロードしたインストーラーをC:\test\npp.8.6.Installer.x64.exeに配置します。

MSIXパッケージツールを起動し、アプリケーションパッケージを選択し、新しいパッケージを作成します。

ここでは、「このコンピューターにパッケージを作成する」でパッケージを作成します。

スクリーンショット:環境

準備の確認が実行されるので、実行完了を待ちます。

スクリーンショット:コンピュータの準備

パッケージを作成するインストーラーでC:\test\npp.8.6.Installer.x64.exeを指定します。

署名の基本設定で「証明書(.pfx)を使用して署名する」を指定し、上記の「証明書の作成、インストール」で作成した.pfxファイルを指定します。

スクリーンショット:インストーラーの選択

パッケージ情報を入力します。

インストール先は空で構いません。

スクリーンショット:パッケージ情報

次へボタンをクリックすると、インストーラーが実行されます。

スクリーンショット:インストーラー起動

動作確認のためにインストールしているため、ここではminimalインストールとしています。

スクリーンショット:minimal

インストーラーが実行されると、初回起動時のタスクの管理画面となります。 ここでアプリケーションのエントリポイント(直接起動可能なアプリケーション)を指定します。 また、実際に起動し、起動後のタスクをキャプチャすることができます。

スクリーンショット:エントリーポイント

エントリポイントの指定、キャプチャが完了したら、MSIXパッケージを作成します。

スクリーンショット:パッケージの作成

これで、通常のMSIXパッケージが作成できました。

MSIXパッケージのIsolated Win32アプリケーション化

上記のMSIXパッケージのマニフェストを編集し、アプリケーション実行環境を分離(Isolate)します。

Win32 app isolationのマニフェストの編集手順にしたがって編集します。

  • Packageエレメントにxmlns:previewsecurity2="http://schemas.microsoft.com/appx/manifest/preview/windows10/security/2"を追加
    • 追加した場合、PackageエレメントのIgnorableNamespacespreviewsecurity2を追加
  • Packageエレメントにxmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"を追加
    • 追加した場合、PackageエレメントのIgnorableNamespacesuap10を追加
  • Dependenciesエレメント配下のTargetDeviceFamilyエレメントを<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.25357.0" MaxVersionTested="10.0.25357.0" />に変更
  • Applicationエレメントのentrypointtrustlevelruntimebehavioruap10:TrustLevel="appContainer" previewsecurity2:RuntimeBehavior="appSilo"に変更
  • Capabilitiesエレメント配下の<rescap:Capability name="runFullTrust">が不要なら削除
    • comServerFirewallRulesなど、runFullTrust権限が必要なextensionsが存在する場合などに必要

今回のマニフェストを修正すると、以下のようになります。 このマニフェストは、最小の権限の状態になっています。

<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:previewsecurity2="http://schemas.microsoft.com/appx/manifest/preview/windows10/security/2" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10" xmlns:desktop7="http://schemas.microsoft.com/appx/manifest/desktop/windows10/7" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap uap10 desktop7 rescap previewsecurity2">
  <!--Package created by MSIX Packaging Tool version: 1.2023.517.0-->
  <Identity Name="MyNotepadPP" Publisher="CN=Contoso Software, O=Contoso Corporation, C=US" Version="1.0.1.0" ProcessorArchitecture="x64" />
  <Properties>
    <DisplayName>MyNotepadPP</DisplayName>
    <PublisherDisplayName>Contoso</PublisherDisplayName>
    <Description>None</Description>
    <Logo>Assets\StoreLogo.png</Logo>
    <uap10:PackageIntegrity>
      <uap10:Content Enforcement="on" />
    </uap10:PackageIntegrity>
  </Properties>
  <Resources>
    <Resource Language="en-us" />
  </Resources>
  <Dependencies>
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.25357.0" MaxVersionTested="10.0.25357.0" />
  </Dependencies>
  <Applications>
    <Application Id="NOTEPAD" Executable="VFS\ProgramFilesX64\Notepad++\notepad++.exe" uap10:TrustLevel="appContainer" previewsecurity2:RuntimeBehavior="appSilo">
      <uap:VisualElements BackgroundColor="transparent" DisplayName="Notepad++" Square150x150Logo="Assets\NOTEPAD-Square150x150Logo.png" Square44x44Logo="Assets\NOTEPAD-Square44x44Logo.png" Description="Notepad++">
        <uap:DefaultTile Wide310x150Logo="Assets\NOTEPAD-Wide310x150Logo.png" Square310x310Logo="Assets\NOTEPAD-Square310x310Logo.png" Square71x71Logo="Assets\NOTEPAD-Square71x71Logo.png" />
      </uap:VisualElements>
      <Extensions>
        <desktop7:Extension Category="windows.shortcut">
          <desktop7:Shortcut File="[{Common Programs}]\Notepad++.lnk" Icon="[{Package}]\VFS\ProgramFilesX64\Notepad++\notepad++.exe" />
        </desktop7:Extension>
      </Extensions>
    </Application>
  </Applications>
  <Capabilities>
  </Capabilities>
</Package>

このマニフェストを適用して、MSIXパッケージを再作成します。

※パッケージの作成時、証明書を再度指定する必要があるのに注意してください。

パッケージをインストールし起動すると、設定ファイルが読み込めない、ファイルが保存できないといったファイルアクセス制限がかかっていることがわかります。

スクリーンショット:読み込みエラー

この状態から、マニフェストの<Capabilities>に適切な<Capability>を追加して、このアプリケーションに権限を付与していきます。 必要な権限はApplication Capability Profilerを使用して設定します。

Application Capability Profilerを使用して、必要な権限の設定

https://github.com/microsoft/win32-app-isolation/blob/main/docs/profiler/application-capability-profiler.md

上記の手順に従い、作成したMSIXパッケージ(Isolated Win32アプリケーション)に必要な権限を取得します。

デベロッパーモードの設定

Windowsの[設定]->[プライバシーとセキュリティ]->[デベロッパーモード]をONにします。

https://learn.microsoft.com/ja-jp/windows/apps/get-started/enable-your-device-for-development

レジストリーのHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlockに1を指定することでもデベロッパーモードにすることができます。 一例として、Powershellを管理者権限で実行し、以下のコマンドを実行します。

PS C:\WINDOWS\system32> reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" /t REG_DWORD /f /v "AllowAllTrustedApps" /d "1"

https://learn.microsoft.com/ja-jp/windows/apps/get-started/developer-mode-features-and-debugging#use-regedit-to-enable-your-device

また、Windows 11 Pro/Enterprise/Educationであれば、グループポリシーから有効にすることも可能です。

https://learn.microsoft.com/ja-jp/windows/apps/get-started/developer-mode-features-and-debugging#use-gpedit-to-enable-your-device

Powershell 7のインストール

プロファイリングにはPowershell 7が必要です。 現在使用しているPowershellのバージョンが7未満の場合、Powershell 7をインストールします。 現在使用しているPowershellのバージョンはGet-Hostコマンドなどで確認できます。

PS C:> Get-Host

Name             : ConsoleHost
Version          : 7.4.0
InstanceId       : 52a98369-bc7b-4543-8b12-014b2c1111f8
UI               : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture   : ja-JP
CurrentUICulture : ja-JP
PrivateData      : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
DebuggerEnabled  : True
IsRunspacePushed : False
Runspace         : System.Management.Automation.Runspaces.LocalRunspace

wprコマンドの取得

プロファイリングに必要なため、Windows パフォーマンス レコーダーをインストールします。

Get-Command wpr

プロファイリングの実行

https://github.com/microsoft/win32-app-isolation/blob/main/docs/profiler/application-capability-profiler.md#profiling-step-2-start-profiling

上記の手順に従い、プロファイリングを実行します。

まず、作成済みのパッケージファイルをMSIX パッケージツールで開きます。 マニフェスト開き、内容をローカルのXMLファイルにコピーします。

ここでは、コピー先のファイル名をC:\test\MyNotepadPPManifest.xmlとします。

ACP-MPT-{version}.zipの展開先をC:\test\ACP-MPT-v0.1.1とします。

以下のコマンドを実行し、プロファイリングを開始します。 以下、実行するコマンドの詳細は上記のURLを参照してください。

PS C:\test> cd C:\test\ACP-MPT-v0.1.1\ACP
PS C:\test\ACP-MPT-v0.1.1\ACP> Import-Module .\Microsoft.Windows.Win32Isolation.ApplicationCapabilityProfiler.dll
PS C:\test\ACP-MPT-v0.1.1\ACP> cd C:\test
PS C:\test> Start-Profiling -ManifestPath MyNotepadPPManifest.xml

プロファイリング開始後、MSIXパッケージからインストールしたアプリケーションを起動します。 プロファイリング中はアクセス制限がない状態でアプリケーションが動作します。 この状態でファイルを開いて保存といった、想定される動作シナリオを実行します。 プロファイリング中にアプリケーションで実行されたファイルアクセスなどがキャプチャーされ、プロファイル終了時に結果ファイルに出力されます。

シナリオを実行し終えたらプロファイリングを終了します。

PS C:\test> Stop-Profiling
Press Ctrl+C to cancel the stop operation.
The trace was successfully saved.


Is Developer Mode enabled? Yes.
The request was completed successfully!

The following event trace log file was collected. It can be parsed by Get-ProfilingResults to identify useful capability access information.
C:\test\trace.etl

生のプロファイル結果であるC:\test\trace.etlを利用可能なプロファイル結果に変換します。

PS C:\test> Get-ProfilingResults -EtlFilePaths trace.etl -ManifestPath .\MyNotepadPPManifest.xml
C:\test\trace.etl: parsing file and searching for capabilities...
C:\test\trace.etl: done parsing!

Identifying capabilities that grant the desired access...
Done identifying capabilities!

Writing C:\test\MyNotepadPPManifest.xml...
Done writing C:\test\MyNotepadPPManifest.xml.
Writing C:\test\AccessAttemptRecords.csv...
Done writing C:\test\AccessAttemptRecords.csv.
Writing C:\test\summary.txt...
Done writing C:\test\summary.txt.

2023/12/18 10:31:05
Microsoft.Windows.Win32Isolation.CapabilityAccessParser

Output Guide

Input parsed: C:\test\trace.etl
Target(s): ...

The following files were output.
- C:\test\summary.txt:
        Summary of identified capabilities and/or failures for the given execution.
- C:\test\AccessAttemptRecords.csv:
        Comma-separated values file containing detailed information on the parsed access attempt events.

The following files contain the capabilities to be manifested by each application package profiled. Please declare them in their corresponding package manifest and reinstall the package.

- C:\test\MyNotepadPPManifest.xml



Troubleshooting Guide

If the application still experiences access and/or compatibility issues after it's packaged and installed with the capabilities identified, consider whether the traces parsed cover all critical application scenarios. If not, consider retrying with traces for all critical application scenarios. Otherwise, please submit the following files to Microsoft for analysis and extension of support.

Troubleshooting files to submit:
C:\test\AccessAttemptRecords.csv
C:\test\trace.etl

The request was completed successfully!

MyNotepadPPManifest.xmlのCapabilitiesがキャプチャーされた結果をもとに更新されています。 この更新後のMyNotepadPPManifest.xmlの内容をMSIXパッケージツールから再適用します。

Win32 app isolationの動作環境について

Win32 app isolationにより分離されたアプリケーションは、アプリケーションコンテナ(AppContainer)で仮想化されたパッケージ上で動作します。 アプリケーションコンテナ上では、ファイルシステムやレジストリが仮想化されています。

https://learn.microsoft.com/ja-jp/windows/msix/desktop/desktop-to-uwp-behind-the-scenes

  • C:\Program Files\WindowsApps\<package_full_name>\VFSに仮想ファイルシステムフォルダーが作成されます
    • システム系の
    • 例えばC:\Windows\System32の読み取りはC:\Program Files\WindowsApps\<package_full_name>\VFS\SystemX86C:\Windows\System32の内容がマージされた内容が読み込まれます
  • AppDataへの書き込みはC:\Users\<ユーザー名>\AppData配下のパッケージごとの場所に行われます
    • 例えば、今回作成したMyNotepadPPパッケージであればC:\Users\<ユーザー名>\AppData\Local\Packages\MyNotepadPP_<パブリッシャーID>に作成されます。
  • パッケージ内(C:\Program Files\WindowsApps\<パッケージ>)への書き込みは禁止されています
    • 変更を加えられるのは基本的にはパッケージインストール、更新、アンインストール時のみです
  • パッケージ外へのアクセスはアクセス許可がある場合のみ許可されます
  • パッケージの仮想レジストリはregistry.datに記録されています
    • 仮想レジストリはMSIXパッケージ作成時に指定できます
    • HKLM\Softwareの読み取りはregistry.datの内容とマージされます
    • HKCUへの書き込みは、C:\Users\<ユーザー名>\AppData配下のパッケージごとの場所に行われます
    • パッケージ内のレジストリへの書き込みは禁止されています
    • パッケージ外への書き込みはアクセス権がある場合のみ許可されます

これに加え、Capabilitiesでアプリ機能の宣言をすることで、使用可能な機能を制限できます。

https://learn.microsoft.com/ja-jp/windows/uwp/packaging/app-capability-declarations

Win32 app isolationでは、更に以下のような権限が追加されています。

https://github.com/microsoft/win32-app-isolation/blob/main/docs/packaging/msix-packaging-tool.md#msix---isolated-win32

例えば以下の権限があります。

  • isolatedWin32-print
    • 印刷の許可
  • isolatedWin32-sysTrayIcon
    • システムトレイに通知を表示することを許可
  • isolatedWin32-promptForAccess
    • ファイルアクセスをしようとした場合に、ユーザーにアクセスを許可するかどうか尋ねる
  • isolatedWin32-accessToPublisherDirectory

先の手順の通り、ACPにより必要な権限は自動でプロファイルできます。 例えば、プロファイル中に印刷を実行し、プロファイル結果を作成すれば、isolatedWin32-printが付与されたマニフェストが生成されます。

おわりに

今回、Win32 app isolationの使用方法について紹介しました。 本記事が少しでも皆さんの役に立てば幸いです。

また、クリアコードではこのように、業務で得た知見や成果を公開することを重視しています。 クリアコードで働くことに興味を持たれた方は、クリアコードの採用情報をぜひご覧ください。