ユーザーアカウント制御(英語: User Account Control, UAC)は、オペレーティングシステムを不正な変更から保護するために設計された、Windows Vistaから導入されたWindowsのセキュリティ機能である。システムの変更に管理者レベルの許可(昇格)が必要な場合、UACはユーザーに通知し、変更を承認または拒否する機会を与える。

本稿では、UACとそれに付随する昇格と仮想化について解説する。また、特に断らない限り、管理者ユーザーとは`BUILTIN\Administrators`グループに所属するユーザーを指し、標準ユーザーとは`BUILTIN\Users`グループに所属するユーザーを指す。

## 歴史

Windows XPまでは、管理者アカウントは管理権限(英語: Administrative rights)を常に持っており、マルウェアを含む全てのソフトウェアは管理特権を持った状態で実行し、システム上の全てのリソースにアクセスすることができた。こうしたセキュリティ上の問題を解決するため、Windows Vistaからは、管理者ユーザーとしてログオンしていても既定で標準ユーザーとして操作を行い、昇格されたアプリケーションのみ管理者権限を使用可能になった。

### 問題点と解決

Windows Vista以降、既定でアプリケーションを標準ユーザーの権限で実行するようになり、2つの問題が発生した。

一つ目は、ユーザーが標準ユーザー権限でのみ動作するアプリケーションのみを実行していたとしても、管理者権限が必要となる場合である。例えば、アプリケーションのインストール時はほとんどの場合、システム全体で共有されるディレクトリやレジストリキーを作成したり、サービスやデバイスドライバーをインストールしたりする必要がある。こうした操作を管理者アカウントに切り替えてから実行するといったこともあり得るが、非常に不便であり、管理者権限を必要としない操作が日常のほとんどでありながら、ユーザーが管理者アカウントに留まったままになる可能性がある。UACはこうした問題を解決するため、管理者ユーザーにログインする際に管理者権限を持つアクセストークンと制限付きトークンを作成(後述)して必要な場合に昇格させ、標準ユーザーの場合でも管理者ユーザーの資格情報を入力した場合に昇格可能にした。つまり、UACはセキュリティ境界ではなく、昇格を承認されたソフトウェアが管理者権限を利用してどういった操作をするかはUACの関知するところではない。

二つ目は、標準ユーザーと同じ権限で動作することを想定していない古いアプリケーションが、保護されたディレクトリやレジストリにアクセスする場合である。こうしたアプリケーションでも互換性を保つため、ファイルシステムとレジストリの仮想化を導入して一定の条件を満たす場合に限り、仮想化されたデータストアに自動的にリダイレクトする。

## ログオン時

### 管理者ユーザーにログオンする場合

ログオンが成功したのち、LSASS(ローカルセキュリティ機関サブシステムサービス、英語: Local Security Authority Subsystem Service, Lsass.exe)は、フル管理者トークン(英語: Full admin token, privileged token)と制限付き管理者トークン(英語: Filtered admin token)の二つのトークンを作成する。ユーザーが起動するアプリケーションのプロセスには制限付きトークンが付与され、ユーザーが昇格を承認したプロセスにのみフル管理者トークンが付与される。

違いは以下の通りである。

|  | フル管理者トークン | 制限付き管理者トークン |
| --- | --- | --- |
| グループ | `BUILTIN/Administrators`のSIDあり | `BUILTIN/Administrators`のSIDなし |
| 特権 | 全て保持 | `SeChangeNotifyPrivilege`、 `SeShutdownPrivilege`、 `SeUndockPrivilege`、 `SeIncreaseWorkingSetPrivilege`、 `SeTimeZonePrivilege` 以外の特権は剥奪。 |
| 整合性レベル | 高(`S-1-16-0x3000`) | 中(`S-1-16-0x2000`) |

### 標準ユーザーにログオンする場合

ログオンが成功したのち、LSASSは、標準ユーザートークン(英語: Standard user token)のみ作成する。

## 昇格

昇格とは、ユーザーがアカウントを切り替えずに管理者権限を取得するための技術である。ユーザーまたはアプリから管理権限を要求された場合、Windowsは昇格ダイアログを表示し、ユーザーに対してその承認を促すか、資格情報の入力を促す。

### 昇格フロー

昇格を必要とする実行可能ファイルを実行すると、`SvcHost.exe`上で実行されているアプリケーション情報サービス(英語: AIS, appinfo.dll)が呼び出され、`consent.exe`を実行する。セキュアデスクトップが有効になっている場合、`consent.exe`は現在のデスクトップの背景をWinlogonデスクトップ上に描画し、昇格が必要なアプリケーションの情報を表示したダイアログを表示する。ユーザーが昇格を承認、もしくは有効な資格情報を入力したら、AISは`CreateProcessAsUser`を通じて親プロセスよりも権限が高いアクセストークンを付与したプロセスを作成し、親プロセスを呼び出し元に設定し直して終了する。

### 昇格ダイアログ

マルウェア等がそのウィンドウオブジェクトにアクセスして外観等を変更することを防ぐために、consent.exeのダイアログは既定で隔離されたWinlogonデスクトップ上に表示される。

有効な電子署名が付与された実行可能ファイルが昇格されようとしている場合、昇格ダイアログには空色の帯が描画される。電子署名がない場合、ダイアログには黄色の帯が表示され、発行元も「不明」と表示される。

### ユーザーが昇格要求

ユーザーは昇格させたいアプリケーションをWindows Explorerの「管理者で実行」を使用するか、「プログラムの実行」において`Ctrl`+`⇧ Shift`+`⏎ Enter`を使用することで、Windowsに昇格を要求できる。

管理者ユーザーがアプリケーションを管理者権限で実行する際、昇格ダイアログはユーザーに「はい」か「いいえ」を表示して管理権限への昇格の承認または拒否を促す。こうした昇格を「承認昇格(英語: Consent elevation)」と呼ぶ。「はい」を押して許可した場合、アプリケーションには上記2つのうちのフル管理者トークンが付与され、管理権限を使用することが可能になる。

標準ユーザーがアプリケーションを管理者権限で実行する際、昇格ダイアログは管理者アカウントのユーザー名とパスワードの入力を促し、その資格情報から新たに管理権限をもつアクセストークンを作成しアプリケーションに付与する。管理者アカウントの資格情報を知る人物が標準ユーザーに代わって入力する必要があるため、こうした昇格を「肩越し昇格(英語: Over-the-shoulder elevation)」と呼ぶ。

### アプリが昇格要求

アプリケーションが管理者権限を必要とする場合、アプリケーション側から実行時に昇格を要求することができる。

### 自動昇格

UACは以下の条件を満たす場合、アプリケーションを自動で昇格させ、ユーザーに昇格ダイアログを表示しない。

- 発行元が「Microsoft Windows」である(「Microsoft」ではいけない)電子署名が付随する。
- `%SystemRoot%\System32`やその複数のサブディレクトリ、`%ProgramFiles%`内の`Windows Defender`や`Windows Journal`等のサブディレクトリのいずれかにその実行可能ファイルが存在する。
- アプリケーションマニフェストに`autoElevate`が定義されている。

## 仮想化

ファイルシステムとレジストリの仮想化は、Vista以降、ユーザーが実行するアプリケーションが標準ユーザー権限で実行するようにしたために、正常に動作しない可能性のあるWindows Vista以前のレガシーアプリケーションの後方互換性を保つための技術である。

### ファイルシステムの仮想化

ファイルシステムの仮想化は`Luafv.sys`ドライバで実装されており、以下の条件を満たす場合、保護されたストレージへのアクセスは自動的にリダイレクトされる。

- 32ビットアプリケーションである。
- 管理者権限で実行されていない。
- カーネルモードのイメージが呼び出し元でない。
- 呼び出し元が偽装をしていない。
- 実行可能イメージにUAC互換のあるマニフェストが付随していない。
- 管理者ユーザーがレジストリへの書き込み権限を持っている。
- 呼び出し元がサービスのような非対話型プロセスでない。

### レジストリの仮想化

レジストリの仮想化はWindowsエグゼキュティブであるコンフィグレーションマネージャに実装されており、以下の条件を満たす場合、仮想化可能なレジストリキーへのアクセスは自動的にリダイレクトされる。

- 32ビットアプリケーションである。
- 管理者権限で実行されていない。
- カーネルモードのイメージが呼び出し元でない。
- 呼び出し元が偽装をしていない。
- 実行可能イメージにUAC互換のあるマニフェストが付随していない。
- 管理者ユーザーがレジストリへの書き込み権限を持っている。
- 呼び出し元がサービスのような非対話型プロセスでない。
- 以下のキーまたはサブキーでない。
  - `HKLM\Software\Classes`
  - `HKLM\Software\Microsoft\Windows`
  - `HKLM\Software\Microsoft\Windows NT`