4.4 ユーザー インターフェイス特権の分離 (UIPI)

4. 新機能や機能変更に伴う互換性問題

この章では、以下のような新機能や機能変更に伴う、互換性問題について紹介します。

UIPI (User Interface Privilege Isolation) とは

整合性レベルにより、プロセスごとにアクセスできるリソースのレベルを決定することができるため、攻撃によるデータの変更や破壊、悪意のあるコードのインストールの可能性を軽減することができます。

しかし、プロセス間で Windows Messaging (SendMessage()) などを利用して、自由に通信できてしまうと問題が起こります。低い整合性レベルのプロセスが、高い整合性レベルのプロセスにメッセージを送信することができるとなると、低いほうのプロセスから、高いほうのプロセスに対して、悪意のある DLL が注入され、そのコードが管理者権限で実行される危険性があるからです。

そこで、Windows Vista や Windows 7 では、UIPI が既定で有効になっています。UIPI は上位のプロセスを下位のプロセスから保護する機能です。UIPI により、下位のプロセスから上位のプロセスへの通信は許可されません。たとえば、「低 IL」のプロセスから「中 IL」や「高 IL」への通信は失敗しますし、「中 IL」から「高 IL」への通信も失敗します。

許可されていない通信は、下位のプロセスから上位のプロセスへの通信に限ります。同レベルのプロセス間通信は許可されています。たとえば、「中 IL」のプロセスから、他の「中 IL」のプロセスへの通信は可能です。また、上位から下位のレベルへの通信も問題ありません。たとえば、「高 IL」のプロセスから「中 IL」のプロセスへの通信も問題なくおこなえます。

ページのトップへ


UIPI に対応するには

下位レベルのプロセスから、上位 IL のプロセスを呼び出さないようにするのが基本です。

しかし、下位レベルのプロセスから、上位レベルのプロセスをどうしても呼び出さなければならないときには、以下の 2 つの方法が考えられます。

下位レベルのプロセスを、通信したいほうのレベルに合わせて実行します。たとえば、「高 IL」のプロセスと通信したいなら、自身も「高 IL」で実行します。

「中 IL」や「高 IL」で実行する方法は、UAC と同じです。つまり、標準ユーザーとして実行しているときには「中 IL」が使われ、昇格ダイアログ ボックスを使って、管理者に昇格すると「高 IL」で実行します。自身を昇格し、「高 IL」で実行すれば、他のプロセスと通信することができます。

昇格せずに、上位権限のプロセスと通信することもできます。このためには、アプリケーション マニフェストでの設定が必要です。以下にサンプルを示します。ポイントは、「<requestedExecutionLevel level="asInvoker" uiAccess="true"/>」の設定です。「level="asInvoker"」の設定により、このプロセスは標準権限で実行されることが宣言されています。しかし、「uiAccess="true"」の設定により、他のプロセスと通信するときには、「高 IL」として振舞うことができます。そのため、上位権限のプロセスとも通信をすることができるようになります。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly  xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel
          level="asInvoker" uiAccess="true"/>
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>

ただし、「uiAccess="true"」を使用して上位権限のプロセスとやり取りするアプリケーションは、以下の 2 つの条件を満たす必要があります。

  • 署名付きのプログラムである
  • %WinDir% または %ProgramFiles% フォルダに保存されている

高 IL のプロセスと通信するためには、Administrators グループのメンバーでログオンしていなければなりません。一般ユーザーとしてログオンしている場合には、これらの設定をしても高 IL のプロセスと通信することはできません。

ページのトップへ


UIPI による問題を検証するには

下位のプロセスから、上位権限のプロセスへの通信で失敗している場合には、以下のような現象が起こります。

  • 上位権限のプロセスのハンドルの検証に失敗する
  • 上位権限のウィンドウへの SendMessage() や PostMessage() に失敗する

    この場合、エラーは発生しません。下位のプロセスからは送信されたように見えますが、上位のプロセスで破棄されます。ただし、GetLastError() には ERROR_ACCESS_DENIED(5) が返ります。

  • 上位権限のプロセスへのスレッド フックやジャーナル フックに失敗する
  • 上位権限のプロセスへの DLL の注入に失敗する

このような問題が発生し、しかも以下に該当する場合、UIPI の問題である可能性が高いといえます。

  • 権限が同じプロセス間では問題が発生せず、上位権限との間で問題が発生する。
  • 「管理者として実行」やビルトインの Administrator で起動した場合には問題が発生しない。

以上のような問題に対応するためには、「権限を昇格し、自身も上位権限になる」や、「実行権限を昇格せずに、上位の権限のプロセスとやりとりする」ので紹介した手順を実行します。

ページのトップへ