Windows レジストリは、サイバー攻撃者にとっては魅力的な攻撃対象です。セキュリティの脆弱性を導入したり、Windows システムを使えなくしてしまうのに、レジストリほど好都合な場所はありません。
セキュリティやトラブルシューティングのためにレジストリ・キーへのアクセス許可をコントロールするには、いくつかの異なる方法がありますが、このブログでは、PowerShell を使った方法を説明します。PowerShell コマンドレットと、ちょっとした .NET マジックを使用すると、レジストリのアクセス許可を自由に読み取って操作できます。
このブログで取り上げる「レジストリのアクセス許可」は、アクセス制御リスト(access control list、ACL)を構成するアクセス制御エントリ(access control entries、ACE)のセットを意味します。ACL は、レジストリ・キーに適用されます。
ACL は IT の多くのエンティティに共通の用語であり、レジストリ・キーに適用されることも一般的な認識です。ACL は、どのアカウントがどのようにしてレジストリ・キーにアクセスできるかを定義します。
レジストリのアクセス許可で、特定のレジストリ・キーにアクセスできるアカウントと、そのアカウントが持つアクセス許可の種類が定義されます。
まず、アクセス許可の変更を加えたいレジストリ・キーを探します。ここでは、HKCU: のパスでランダムに1つ選択しますが、どんなキーを選択しても構いません。
変更を加える前に、現在の ACL を確認し、問題が発生した場合に備えてバックアップを作成することをお勧めします。Get-Acl は、ACL を確認するのに使える PowerShell のコマンドレットです。
PS> $acl = Get-Acl 'HKCU:\AppEvents\EventLabels\ActivatingDocument'
PS> $acl.Access
RegistryRights : ReadKey
AccessControlType : Allow
IdentityReference : APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES
IsInherited : False
InheritanceFlags : ContainerInherit
PropagationFlags : None
--snip--
現在の ACL の情報が獲得できたら、変更を加えることができます。心配な場合は、Export-CliXml コマンドレットを使用して既存の ACL をファイルシステムに保存することもできますが、それについてはここでは触れません。もし興味がある場合は、こちらの、Export-CliXml コマンドレットを使用してオブジェクトをディスクに保存する例をご参照ください。
まず Get-Acl を使用して ACL 情報を入手しましたが、レジストリを使用しているので、この特定の ACL はそのレジストリでのみ機能します。ACL を更新するには、そのレジストリ用にルール(ACE)を追加する必要があります。
PowerShell を使用して Windows レジストリの権限を定義するには、System.Security.AccessControl.RegistryAccessRule オブジェクトを作成します。このオブジェクトを使用すると、ACE が適用されるプリンシパル(ユーザー、グループなど)などの基準、アクセスレベル、そのアクセスを許可するか拒否するかを定義できます。
レジストリ・キーに適切な権限を割り当てる必要がありますが、Microsoft が用意している [RegistryRights 列挙型] ページに記載されている14種類の中から適切なものを選択してください。
適切なレジストリ権限が確認できたら、RegistryAccessRule オブジェクトの作成に取り掛かります。このオブジェクトには3つのパラメータを渡す必要があります。
まず、ID を作成するには、ID リファレンスを渡す System.Security.Principal.NTAccount オブジェクトを作成します。
$idRef = [System.Security.Principal.NTAccount]("HOSTNAME\username")
次に、上記14権限のうちの1つを使用して System.Security.AccessControl.RegistryRights オブジェクトを作成します。
$regRights = [System.Security.AccessControl.RegistryRights]::FullControl
次に、継承フラグと反映フラグを定義します。None、ContainerInherit、ObjectInherit から選択します。これらのオプションの詳細については、こちらをご覧ください。
次の継承 (inheritance) フラグと反映 (propagation) フラグは None に設定されています。つまり、親レジストリ・キーから権限を継承しません。
$inhFlags = [System.Security.AccessControl.InheritanceFlags]::None
$prFlags = [System.Security.AccessControl.PropagationFlags]::None
継承フラグと反映フラグを設定したら、[AccessControlType 列挙型] (アクセス制御タイプ) を設定します。
$acType = [System.Security.AccessControl.AccessControlType]::Allow
最後に、収集したすべてのオブジェクトを使用して RegistryAccessRule オブジェクトを作成します。
$rule = New-Object System.Security.AccessControl.RegistryAccessRule ($idRef, $regRights, $inhFlags, $prFlags, $acType)
これで、$rule 変数に RegistryAccessRule が定義されました。これは次のセクションで必要になります。
次のステップは、AddAccessRule() メソッドを使用して、前のセクションで作成した RegistryAccessRule を現在の ACL に追加することです。
PS> $acl.AddAccessRule($rule)
あるいは、SetAccessRule() メソッドを使用して、既存の ACL を完全に上書きすることもできます。
PS> $acl.SetAccessRule($rule)
ここまで来ましたが、まだ終わりではありません。Set-Acl コマンドを使用してレジストリ・キーに新しい ACL を適用する必要があります。$acl で、適用するキーをポイントして、保存した ACL を Set-Acl に直接渡します。
最初に ACL を収集したのと同じキーに ACL を設定したいので、そのキーパスを Set-Acl の -Path パラメータに渡して適用します。
$acl | Set-Acl -Path 'HKCU:\AppEvents\EventLabels\ActivatingDocument'
レジストリへのアクセス許可ルールが追加された ACL は、元のレジストリ・キーに適用されます。Get-Acl を再度呼び出すと、IdentityReference、RegistryRights、AccessControlType プロパティが意図した通りに変更されていることが確認できます。
PS> (Get-Acl 'HKCU:\AppEvents\EventLabels\ActivatingDocument').Access
RegistryRights : FullControl
AccessControlType : Allow
IdentityReference :\Administrator
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
このブログでは、ACE をキャプチャして変更し、レジストリ・キー に適用する方法を説明しました。PowerShell の Get-Acl コマンドレットを使用して既存の ACL を検索し、Set-Acl コマンドレットを使用して変更を加えることができます。これら2つのコマンドレットを使用するだけで、PowerShellでレジストリのアクセス許可を操作することができます。
Subscribe to get all the news, info and tutorials you need to build better business apps and sites