[MS14-025] グループ ポリシー基本設定の脆弱性により、特権が昇格される (2014 年 5 月 13 日)

はじめに

マイクロソフトはセキュリティ情報 MS14-025 を公開しました。このセキュリティ情報の詳細を参照するには、次のいずれかのマイクロソフト Web サイトにアクセスしてください。

このセキュリティ更新プログラムに関するヘルプとサポートを受ける方法

更新プログラムのインストールのヘルプ:
Windows Update サポート ページ

IT プロフェッショナル向けのセキュリティ ソリューション:
セキュリティに関するトラブルシューティングとサポート

ウイルスとマルウェアから Windows を搭載しているコンピューターを保護する:
ウイルスとセキュリティ サポート ページ

国ごとのローカル サポート:
インターナショナル サポート

詳細

既知の問題およびこのセキュリティ更新プログラムの関連情報

以下の資料には、各製品のバージョンに関連付けられているこのセキュリティ更新プログラムに関する追加情報が掲載されています。資料には、既知の問題に関する情報が掲載されている可能性があります。この場合、既知の問題の一覧は各資料のリンクの下に示されています。
  • 2928120



    [MS14-025] 更新プログラム 2919355 がインストールされたシステムの Windows リモート サーバー管理ツール用のセキュリティ更新プログラムについて (2014 年 5 月 13 日)

  • 2961899

    [MS14-025] 更新プログラム 2919355 がインストールされていないシステムの Windows リモート サーバー管理ツール用のセキュリティ更新プログラムについて (2014 年 5 月 13 日)

グループ ポリシー基本設定

概要

一部のグループ ポリシー基本設定ではパスワードを保存できます。セキュリティが保護されない方法でパスワードが保存されていたため、この機能は削除されています。この資料では、ユーザー インターフェイスの変更と、使用できる回避策について説明します。

以下のグループ ポリシー基本設定では、ユーザー名とパスワードが保存できなくなります。
  • ドライブ マップ
  • ローカル ユーザーとグループ
  • スケジュールされたタスク
  • サービス
  • データ ソース
この変更は、これらの基本設定に含まれるパスワードに依存する、環境内の既存のグループ ポリシー オブジェクト (GPO) の動作に影響します。また、この機能を使用して新しいグループ ポリシー基本設定を作成することもできなくなります。

ドライブ マップ、ローカル ユーザーとグループ、およびサービスに関しては、Windows の他のより安全な機能により、同じような目的を達成できる場合があります。

スケジュールされたタスクとデータ ソースに関しては、グループ ポリシー基本設定のパスワードの安全ではない機能により、以前は利用できた同じ目的を達成することはできなくなります。

状況

この変更によって、次のグループ ポリシー基本設定が影響を受けます。それぞれの基本設定を簡潔に説明してから、より詳細に説明します。また、同じタスクを実行できるようにする回避策も示されています。
影響を受ける基本設定ユーザーに適用されるかどうか
コンピューターに適用されるかどうか
ローカル ユーザー管理はいはい
マップされたドライブはい
いいえ
サービス
いいえ
はい
スケジュールされたタスク (上位レベル)はいはい
スケジュールされたタスク (下位レベル)はいはい
即時タスク (上位レベル)はいはい
即時タスク (下位レベル)はいはい
データ ソースはいはい

変更の概要

  • 影響を受けるすべての基本設定のパスワード フィールドは無効です。管理者は、これらのパスワード フィールドを使用して新しい基本設定を作成することはできません。
  • 一部の基本設定でユーザー名フィールドは無効です。
  • パスワードが含まれる既存の基本設定を更新することはできません。特定の基本設定に応じて、削除または無効にすることのみ可能です。
  • 基本設定に対する "削除" および "無効化" の動作は変更されていません。
  • CPassword 属性が含まれる基本設定を管理者が開くと、管理者には、最近廃止されたことを通知する次の警告ダイアログ ボックスが表示されます。CPassword 属性が必要である新規または既存の基本設定に対する変更を保存しようとしても、同じダイアログ ボックスが表示されます。"削除" および "無効化" の操作でのみ、警告ダイアログ ボックスが表示されません。





状況 1: ローカル ユーザー管理

ローカル ユーザー管理基本設定は、コンピューター上に既知のパスワードがあるローカル管理者を作成するために頻繁に使用されます。この機能は、グループ ポリシー基本設定がパスワードを保存する方法により、セキュリティが保護されていません。そのため、この機能は利用できません。以下の基本設定が影響を受けます。
  • コンピューターの構成 -> コントロール パネルの設定 -> ローカル ユーザーとグループ -> 新規 -> ローカル ユーザー
  • ユーザーの構成 -> コントロール パネルの設定 -> ローカル ユーザーとグループ -> 新規 -> ローカル ユーザー

重要な変更

操作: 作成または置換
  • [ユーザー名]、[パスワード]、および [パスワードの確認] フィールドは無効です。
  • 管理者が、パスワードが含まれる既存の基本設定を開くか、そのような基本設定に変更を保存しようとすると、警告ダイアログ ボックスが表示されます。




操作: 更新
  • [パスワード] および [パスワードの確認] フィールドは無効です。
  • 管理者が、パスワードが含まれる既存の基本設定を開くか、そのような基本設定に変更を保存しようとすると、警告ダイアログ ボックスが表示されます。




操作: 削除
  • 動作に変更なし

回避策

ローカル管理者パスワードの設定に関して以前にグループポリシー基本設定に依存した管理者向けに、CPassword に対する安全な代替手段として、次のスクリプトが提供されています。内容をコピーして、新しい Windows PowerShell ファイルに保存し、.EXAMPLE セクションに記載されている方法でスクリプトを実行します。

マイクロソフトは、説明を目的としたプログラミングの例を提供するだけであり、市場性および特定目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。この資料は、例示されているプログラミング言語やプロシージャの作成およびデバッグに使用するツールについて理解されているユーザーを対象としています。マイクロソフト サポート窓口では、特定のプロシージャの機能説明に関するご質問に対して支援いたしますが、本例を特定の目的を満たすために機能を追加したり、プロシージャを構築することは行いません。

 
function Invoke-PasswordRoll
{
<#
.SYNOPSIS

このスクリプトを使用すると、リモート マシン上のローカル アカウントのパスワードをランダムなパスワードに設定できます。ユーザー名/パスワード/サーバーの組み合わせは、CSV ファイルに保存されます。
CSV ファイルに保存されるアカウントのパスワードを、管理者が選択したパスワードを使用して暗号化すると、クリアテキストのアカウント パスワードがディスクに書き込まれないようにすることができます。
このファイルの別の関数を使用すると、暗号化したパスワードの暗号化を解除できます: ConvertTo-CleartextPassword


Function: Invoke-PasswordRoll
Author:Microsoft
Version: 1.0

.DESCRIPTION

このスクリプトを使用すると、リモート マシン上のローカル アカウントのパスワードをランダムなパスワードに設定できます。ユーザー名/パスワード/サーバーの組み合わせは、CSV ファイルに保存されます。
CSV ファイルに保存されるアカウントのパスワードを、管理者が選択したパスワードを使用して暗号化すると、クリアテキストのアカウント パスワードがディスクに書き込まれないようにすることができます。
このファイルの別の関数を使用すると、暗号化したパスワードの暗号化を解除できます: ConvertTo-CleartextPassword

.PARAMETER ComputerName

PowerShell リモート処理を使用してスクリプトを実行する対象であるコンピューターの配列。

.PARAMETER LocalAccounts

パスワードを変更する必要があるローカル アカウントの配列。

.PARAMETER TsvFileName

ユーザー名/パスワード/サーバーの組み合わせの出力先であるファイル。

.PARAMETER EncryptionKey

TSV ファイルの暗号化に使用するパスワード。AES 暗号化を使用します。TSV ファイルに保存されるパスワードのみが暗号化され、ユーザー名とサーバー名はクリアテキストになります。

.PARAMETER PasswordLength

ローカル アカウントに対してランダムに生成されるパスワードの長さ。

.PARAMETER NoEncryption

TSV ファイルに保存されるアカウント パスワードを暗号化しないでください。このようにすると、クリアテキスト パスワードがディスクに書き込まれます。

.EXAMPLE

. .\Invoke-PasswordRoll.ps1 #このスクリプト ファイルに関数を読み込む
Invoke-PasswordRoll -ComputerName (Get-Content computerlist.txt) -LocalAccounts @("administrator","CustomLocalAdmin") -TsvFileName "LocalAdminCredentials.tsv" -EncryptionKey "Password1"

ファイル "computerlist.txt" に保存されているすべてのコンピューターに接続します。ローカル アカウント "administrator" と "CustomLocalAdmin" の一方または両方がシステム上に存在する場合、そのパスワードは、
長さが 20 (既定) のランダムに生成されたパスワードに変更されます。ユーザー名/パスワード/サーバーの組み合わせは LocalAdminCredentials.tsv に保存され、アカウントのパスワードはパスワード "Password1" を使用して AES で暗号化されます。

.EXAMPLE

. .\Invoke-PasswordRoll.ps1 #このスクリプト ファイルに関数を読み込む
Invoke-PasswordRoll -ComputerName (Get-Content computerlist.txt) -LocalAccounts @("administrator") -TsvFileName "LocalAdminCredentials.tsv" -NoEncryption -PasswordLength 40

ファイル "computerlist.txt" に保存されているすべてのコンピューターに接続します。ローカル アカウント "administrator" がシステム上に存在する場合、そのパスワードは、長さが 40 のランダムに生成されたパスワードに変更されます。
ユーザー名/パスワード/サーバーの組み合わせは暗号化されずに LocalAdminCredentials.tsv に保存されます。

.NOTES
必要条件:
-PowerShellv2 以降のインストールが必要
-スクリプトを実行する対象であるすべてのシステム上で PowerShell リモート処理の有効化が必要

スクリプトの動作:
-ローカル アカウントがシステム上に存在するが、LocalAccounts パラメーターで指定されていない場合、スクリプトは画面に警告を表示し、このローカル アカウントの存在を通知します。このような状態になっても、スクリプトは実行を継続します。
-ローカル アカウントが LocalAccounts パラメーターで指定されていても、アカウントがコンピューター上に存在しない場合は、何の処理も行われません (アカウントは作成されません)。
-このファイルに含まれている関数 ConvertTo-CleartextPassword を使用すると、TSV ファイルに暗号化された状態で保存されているパスワードの暗号化を解除できます。
-ComputerName で指定されているサーバーに接続できない場合、PowerShell はエラー メッセージを出力します。
-マイクロソフトは、企業に、すべてのローカル アカウントとドメイン アカウントのパスワードを定期的に更新することを推奨します。

#>
[CmdletBinding(DefaultParameterSetName="Encryption")]
Param(
[Parameter(Mandatory=$true)]
[String[]]
$ComputerName,

[Parameter(Mandatory=$true)]
[String[]]
$LocalAccounts,

[Parameter(Mandatory=$true)]
[String]
$TsvFileName,

[Parameter(ParameterSetName="Encryption", Mandatory=$true)]
[String]
$EncryptionKey,

[Parameter()]
[ValidateRange(20,120)]
[Int]
$PasswordLength = 20,

[Parameter(ParameterSetName="NoEncryption", Mandatory=$true)]
[Switch]
$NoEncryption
)


#必要なすべての .NET クラスを読み込む
Add-Type -AssemblyName "System.Web" -ErrorAction Stop


#これは、ComputerName で指定されているすべてのコンピューターで実行されるスクリプトブロックである
$RemoteRollScript = {
Param(
[Parameter(Mandatory=$true, Position=1)]
[String[]]
$Passwords,

[Parameter(Mandatory=$true, Position=2)]
[String[]]
$LocalAccounts,

#ここに配置してあるのは、スクリプトの接続先であったサーバー名を記録できるようにするためで、DNS レコードに混乱が生じることがあるため、これを用意すると有効である。
[Parameter(Mandatory=$true, Position=3)]
[String]
$TargettedServerName
)

$LocalUsers = Get-WmiObject Win32_UserAccount -Filter "LocalAccount=true" | Foreach {$_.Name}

#コンピューターに、パスワードがこのスクリプトにより展開されないローカル ユーザー アカウントがあるかどうかを確認する
foreach ($User in $LocalUsers)
{
if ($LocalAccounts -inotcontains $User)
{
Write-Warning "Server:'$($TargettedServerName)' has a local account '$($User)' whos password is NOT being changed by this script"
}
}

#このサーバー上に存在する指定のローカル アカウントごとに、パスワードを変更する
$PasswordIndex = 0
foreach ($LocalAdmin in $LocalAccounts)
{
$Password = $Passwords[$PasswordIndex]

if ($LocalUsers -icontains $LocalAdmin)
{
try
{
$objUser = [ADSI]"WinNT://localhost/$($LocalAdmin), user"
$objUser.psbase.Invoke("SetPassword", $Password)

$Properties = @{
TargettedServerName = $TargettedServerName
Username = $LocalAdmin
Password = $Password
RealServerName = $env:computername
}

$ReturnData = New-Object PSObject -Property $Properties
Write-Output $ReturnData
}
catch
{
Write-Error "Error changing password for user:$($LocalAdmin) on server:$($TargettedServerName)"
}
}

$PasswordIndex++
}
}


#リモート マシン上ではなく、このスクリプトを実行するクライアント上でパスワードを生成します。.NET Client Profile では System.Web.Security が使用できません。スクリプトを実行する
# クライアント上でこの呼び出しを行うと、(パスワードが展開されるすべてのシステムではなく) 1 台のコンピューターでのみ完全な .NET ランタイムのインストールが必要になります。
function Create-RandomPassword
{
Param(
[Parameter(Mandatory=$true)]
[ValidateRange(20,120)]
[Int]
$PasswordLength
)

$Password = [System.Web.Security.Membership]::GeneratePassword($PasswordLength, $PasswordLength / 4)

#この処理は絶対に失敗しないはずですが、この場所に正当性のチェックを配置
if ($Password.Length -ne $PasswordLength)
{
throw new Exception("Password returned by GeneratePassword is not the same length as required.Required length:$($PasswordLength). Generated length: $($Password.Length)")
}

return $Password
}


#メイン機能 - パスワードを生成し、マシンにリモート接続して指定のローカル アカウントのパスワードを変更する
if ($PsCmdlet.ParameterSetName -ieq "Encryption")
{
try
{
$Sha256 = new-object System.Security.Cryptography.SHA256CryptoServiceProvider
$SecureStringKey = $Sha256.ComputeHash([System.Text.UnicodeEncoding]::Unicode.GetBytes($EncryptionKey))
}
catch
{
Write-Error "Error creating TSV encryption key" -ErrorAction Stop
}
}

foreach ($Computer in $ComputerName)
{
#変更可能なアカウントごとに 1 つのパスワードを生成する必要がある
$Passwords = @()
for ($i = 0; $i -lt $LocalAccounts.Length; $i++)
{
$Passwords += Create-RandomPassword -PasswordLength $PasswordLength
}

Write-Output "Connecting to server '$($Computer)' to roll specified local admin passwords"
$Result = Invoke-Command -ScriptBlock $RemoteRollScript -ArgumentList @($Passwords, $LocalAccounts, $Computer) -ComputerName $Computer
#暗号化が使用されている場合、ディスクに書き込む前に、ユーザーが指定したキーでパスワードを暗号化する
if ($Result -ne $null)
{
if ($PsCmdlet.ParameterSetName -ieq "NoEncryption")
{
$Result | Select-Object Username,Password,TargettedServerName,RealServerName | Export-Csv -Append -Path $TsvFileName -NoTypeInformation
}
else
{
#Filters out $null entries returned
$Result = $Result | Select-Object Username,Password,TargettedServerName,RealServerName

foreach ($Record in $Result)
{
$PasswordSecureString = ConvertTo-SecureString -AsPlainText -Force -String ($Record.Password)
$Record | Add-Member -MemberType NoteProperty -Name EncryptedPassword -Value (ConvertFrom-SecureString -Key $SecureStringKey -SecureString $PasswordSecureString)
$Record.PSObject.Properties.Remove("Password")
$Record | Select-Object Username,EncryptedPassword,TargettedServerName,RealServerName | Export-Csv -Append -Path $TsvFileName -NoTypeInformation
}
}
}
}
}


function ConvertTo-CleartextPassword
{
<#
.SYNOPSIS
この関数を使用すると、関数 Invoke-PasswordRoll により暗号化された状態で保存されたパスワードの暗号化を解除できます。

Function: ConvertTo-CleartextPassword
Author:Microsoft
Version: 1.0

.DESCRIPTION
この関数を使用すると、関数 Invoke-PasswordRoll により暗号化された状態で保存されたパスワードの暗号化を解除できます。


.PARAMETER EncryptedPassword

TSV ファイルに保存された暗号化パスワード。

.PARAMETER EncryptionKey

暗号化を行うために使用されるパスワード。


.EXAMPLE

. .\Invoke-PasswordRoll.ps1 #このスクリプト ファイルに関数を読み込む
ConvertTo-CleartextPassword -EncryptionKey "Password1" -EncryptedPassword 76492d1116743f0423413b16050a5345MgB8AGcAZgBaAHUAaQBwADAAQgB2AGgAcABNADMASwBaAFoAQQBzADEAeABjAEEAPQA9AHwAZgBiAGYAMAA1ADYANgA2ADEANwBkADQAZgAwADMANABjAGUAZQAxAGIAMABiADkANgBiADkAMAA4ADcANwBhADMAYQA3AGYAOABkADcAMQA5ADQAMwBmAGYANQBhADEAYQBjADcANABkADIANgBhADUANwBlADgAMAAyADQANgA1ADIAOQA0AGMAZQA0ADEAMwAzADcANQAyADUANAAzADYAMAA1AGEANgAzADEAMQA5ADAAYwBmADQAZAA2AGQA"

TSV ファイルに保存された暗号化パスワードの暗号化を解除します。

#>
Param(
[Parameter(Mandatory=$true)]
[String]
$EncryptedPassword,

[Parameter(Mandatory=$true)]
[String]
$EncryptionKey
)

$Sha256 = new-object System.Security.Cryptography.SHA256CryptoServiceProvider
$SecureStringKey = $Sha256.ComputeHash([System.Text.UnicodeEncoding]::Unicode.GetBytes($EncryptionKey))

[SecureString]$SecureStringPassword = ConvertTo-SecureString -String $EncryptedPassword -Key $SecureStringKey
Write-Output ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($SecureStringPassword)))
}
Active Directory グループを作成し、グループ ポリシー基本設定 -> ローカル グループを通じてローカル Administrators グループに追加することで、管理者はコンピューターにローカル管理者アカウントを追加できます。この操作では、資格情報はキャッシュされません。ダイアログ ボックスは次のような形式です。ユーザーがこれらの資格情報を使用してログオンしている場合、この回避策では、Active Directory ドメイン サービスに接続する必要はありません。





状況 2: マップされたドライブ

管理者はドライブ マップを使用してユーザーにネットワークの場所を割り当てます。ドライブへの承認済みアクセスを確保するため、パスワード保護機能が使用されます。以下の基本設定が影響を受けます。
  • ユーザーの構成 -> Windows の設定 -> ドライブ マップ -> 新規 -> マップされたドライブ

重要な変更

操作: 作成、更新、または置換
  • [ユーザー名]、[パスワード]、および [パスワードの確認] フィールドは無効です。



操作: 削除
  • 動作に変更なし

回避策

認証にパスワード方式を使用する代わりに、エクスプローラーを使用して共有のアクセス許可を管理し、ユーザーに権限を割り当てることができます。Active Directory オブジェクトを使用すると、フォルダーに対するアクセス許可を制御できます。


状況 3: サービス

サービスの基本設定を使用すると、元のセキュリティ コンテキスト以外のコンテキストで実行されるように、サービスのプロパティを変更することができます。以下の基本設定が影響を受けます。
  • コンピューターの構成 -> コントロール パネルの設定 -> サービス -> 新規 -> サービス

重要な変更

スタートアップ: 変更なし、自動、または手動
  • [パスワード] および [パスワードの確認] フィールドは無効です。
  • 管理者はビルトイン アカウントのみを使用できます。



スタートアップ: 無効
  • 動作に変更なし
新しいダイアログ ボックス
  • このアカウントに対してビルトイン以外のユーザーを使用しようとする管理者には、以下の警告が表示されます。




回避策


サービスは、依然としてローカル システム アカウントとして実行できます。サービスのアクセス許可は、サポート技術情報の以下の資料に記載されている方法で変更できます。
256345 グループ ポリシーを構成してシステム サービスのセキュリティを設定する方法

注:
構成するサービスが存在しない場合は、サービスが実行中であるコンピューター上で設定を構成する必要があります。


状況 4: スケジュールされたタスクおよび即時タスク (上位レベル)

これらは、特定のセキュリティ コンテキストでスケジュールされたタスクを実行するために使用されます。当該ユーザーがログオンしていない場合に任意のユーザーとして実行するための、スケジュールされたタスクの資格情報を保存する機能は使用できなくなりました。以下の基本設定が影響を受けます (一部のプラットフォームでは "Windows 7 以降" が "Windows Vista およびそれ以降" に置き換えられていることに注意してください)。
  • コンピューターの構成 -> コントロール パネルの設定 -> スケジュールされたタスク -> 新規 -> スケジュールされたタスク (Windows 7 以降)
  • コンピューターの構成 -> コントロール パネルの設定 -> スケジュールされたタスク -> 新規 -> 即時タスク (Windows 7 以降)
  • ユーザーの構成 -> コントロール パネルの設定 -> スケジュールされたタスク -> 新規 -> スケジュールされたタスク (Windows 7 以降)
  • ユーザーの構成 -> コントロール パネルの設定 -> スケジュールされたタスク -> 新規 -> 即時タスク (Windows 7 以降)

重要な変更

操作: 作成、更新、または置換
  • [ユーザーがログオンしているかどうかにかかわらず実行する] オプションをオンにした場合、ダイアログ ボックスでは管理者に資格情報の入力を求めるメッセージは表示されなくなります。
  • [パスワードを保存しない] チェック ボックスは無効です。既定では、ボックスはオンでもあります。



操作: 削除

動作に変更なし

回避策

"スケジュールされたタスク (Windows 7 以降)" および "即時タスク (Windows 7 以降)" のタスクの場合、管理者は、特定のユーザーがログオンしている場合は特定のユーザー アカウントを使用できます。または、管理者はそのユーザーとしてローカル リソースにのみアクセスできます。これらのタスクは、依然として、ローカル サービスのコンテキストで実行可能です。



状況 5: スケジュールされたタスクおよび即時タスク (下位レベル)

これは、特定のセキュリティ コンテキストでスケジュールされたタスクを実行するために使用される下位レベル バージョンの基本設定です。当該ユーザーがログオンしていない場合に任意のユーザーとして実行するための、スケジュールされたタスクの資格情報を保存する機能は使用できなくなりました。以下の基本設定が影響を受けます
  • コンピューターの構成 -> コントロール パネルの設定 -> スケジュールされたタスク -> 新規 -> スケジュールされたタスク
  • コンピューターの構成 -> コントロール パネルの設定 -> スケジュールされたタスク -> 新規 -> 即時タスク (Windows XP)
  • ユーザーの構成 -> コントロール パネルの設定 -> スケジュールされたタスク -> 新規 -> スケジュールされたタスク
  • ユーザーの構成 -> コントロール パネルの設定 -> スケジュールされたタスク -> 新規 -> 即時タスク (Windows XP)

重要な変更

操作: 作成、更新、または置換
  • [別のユーザーとして実行] チェック ボックスは無効です。そのため、[ユーザー名]、[パスワード]、および [パスワードの確認] フィールドはすべて無効です。



操作: 削除

動作に変更なし

回避策

"スケジュールされたタスク" および "即時タスク (Windows XP)" に関して、スケジュールされたタスクの実行には、現時点でローカル サービスに使用できるアクセス許可を使用します。


状況 6: データ ソース

データ ソースの基本設定は、データ ソースをコンピューターまたはユーザーに関連付けるために使用します。この機能では、資格情報を保存して、パスワードにより保護されるデータ ソースへのアクセスを実現することはなくなりました。以下の基本設定が影響を受けます。
  • コンピューターの構成 -> コントロール パネルの設定 -> データ ソース
  • ユーザーの構成 -> コントロール パネルの設定 -> データ ソース

重要な変更

操作: 作成、更新、または置換
  • [ユーザー名]、[パスワード]、および [パスワードの確認] フィールドは無効です。



操作: 削除
  • 動作に変更なし

回避策

使用できる回避策はありません。この基本設定では、資格情報を保存して、パスワードにより保護されるデータ ソースへのアクセスを許可することはなくなりました。


CPassword の廃止

CPassword の削除

このサポート技術情報に記載されている Windows PowerShell スクリプトでは、CPassword を使用する可能性があるグループ ポリシー基本設定がドメインに含まれているかどうかを検出します。特定の基本設定で CPassword XML が検出された場合は、このリストに表示されます。


CPassword 基本設定の検出

このスクリプトは、クリーニングするドメイン コントローラー上のローカル ディレクトリから実行する必要があります。内容をコピーして、新しい Windows PowerShell ファイルに保存し、システム ドライブを確認してから、以下の使用法に記載されている方法でスクリプトを実行します。

 <#
.SYNOPSIS
ドメイン内のグループ ポリシー オブジェクトには、次のようなさまざまなタスクに関するパスワードを保存する基本設定が存在する可能性があります。
1. データ ソース
2. ドライブ マップ
3. ローカル ユーザー
4. スケジュールされたタスク (XP と上位レベルの両方)
5. サービス
これらのパスワードは、GP 基本設定の一部として SYSVOL に保存され、また暗号化が弱い (32 バイトの AES) ために安全ではありません。
そのため、ドメイン環境内にはこのような基本設定を展開せず、またこのような既存の基本設定を削除することを推奨
します。このスクリプトは、パスワードが含まれるドメインの SYSVOL で管理者が GP 基本設定を検出できるようにします。

.DESCRIPTION
GPO、基本設定の名前、GPEdit パスなどの情報 (これらの情報の下にこの基本設定が定義されている) が付属するパスワードが含まれるすべての基本設定を出力するには、
RSAT を使用してインストールされている DC またはクライアント コンピューターでこのスクリプトを実行する必要があります。
影響を受ける基本設定のリストを入手した後、グループ ポリシー管理コンソールでエディターを使用すると、これらの基本設定を削除できます。

.SYNTAX
Get-SettingsWithCPassword.ps1 [-Path <String>]
.EXAMPLE
Get-SettingsWithCPassword.ps1 -Path %WinDir%\SYSVOL\domain
Get-SettingsWithCPassword.ps1 -Path <GPO Backup Folder Path>

.NOTES
Group Policy PS モジュールが見つからない場合、出力には GPO 名ではなく GPO の GUID が含まれます。RSAT をインストールし、
Group Policy モジュールを有効にした後、ドメイン コントローラー上でこのスクリプトを実行するか、クライアント上でスクリプトを
再実行することができます。
または、Get-GPO コマンドレットを使用することで、GPO の GUID を使用して GPO 名を取得することができます。

.LINK
http://go.microsoft.com/fwlink/?LinkID=390507

#>
#----------------------------------------------------------------------------------------------------------------
# 入力パラメーター
#--------------------------------------------------------------------------------------------------------------
param(
[string]$Path = $(throw "-Path is required.") # GPP が置かれているディレクトリのパス
)
#---------------------------------------------------------------------------------------------------------------
$isGPModuleAvailable = $false
$impactedPrefs = { "Groups.xml", "ScheduledTasks.xml","Services.xml", "DataSources.xml", "Drives.xml" }
#----------------------------------------------------------------------------------------------------------------
# 使用できる場合はグループ ポリシー モジュールをインポート
#----------------------------------------------------------------------------------------------------------------
if (-not (Get-Module -name "GroupPolicy"))
{
if (Get-Module -ListAvailable |
Where-Object { $_.Name -ieq "GroupPolicy" })
{
$isGPModuleAvailable = $true
Import-Module "GroupPolicy"
}
else
{
Write-Warning "Unable to import Group Policy module for PowerShell.Therefore, GPO guids will be reported.
Run this script on DC to obtain the GPO names, or use the Get-GPO cmdlet (on DC) to obtain the GPO name from GPO guid."
}
}
else
{
$isGPModuleAvailable = $true
}
Function Enum-SettingsWithCpassword ( [string]$sysvolLocation )
{
# GPMC tree paths
$commonPath = " -> Preferences -> Control Panel Settings -> "
$driveMapPath = " -> Preferences -> Windows Settings -> "

# SYVOL の場所内にあるすべての XML ファイルを再帰的に取得する
$impactedXmls = Get-ChildItem $sysvolLocation -Recurse -Filter "*.xml" | Where-Object { $impactedPrefs -cmatch $_.Name }


# 各 XML ファイルには複数の基本設定が含まれる。各基本設定を検索し、それに CPassword 属性が含まれるか
# どうかを調べ、結果を表示する。
foreach ( $file in $impactedXmls )
{
$fileFullPath = $file.FullName

# GPP カテゴリを設定する。ファイルが SYSVOL の Machine フォルダーの下にある場合、
# 設定はコンピューターの構成の下に定義され、それ以外の場合、
# 設定はユーザーの構成である
if ( $fileFullPath.Contains("Machine") )
{
$category = "Computer Configuration"
}
elseif ( $fileFullPath.Contains("User") )
{
$category = "User Configuration"
}
else
{
$category = "Unknown"
}
# XML としてファイルの内容を取得する
try
{
[xml]$xmlFile = get-content $fileFullPath -ErrorAction Continue
}
catch [Exception]{
Write-Host $_.Exception.Message
}
if ($xmlFile -eq $null)
{
continue
}
switch ( $file.BaseName )
{
Groups
{
$gppWithCpassword = $xmlFile.SelectNodes("Groups/User") | where-Object { [String]::IsNullOrEmpty($_.Properties.cpassword) -eq $false }
$preferenceType = "Local Users"
}
ScheduledTasks
{
$gppWithCpassword = $xmlFile.SelectNodes("ScheduledTasks/*") | where-Object { [String]::IsNullOrEmpty($_.Properties.cpassword) -eq $false }
$preferenceType = "Scheduled Tasks"
}
DataSources
{
$gppWithCpassword = $xmlFile.SelectNodes("DataSources/DataSource") | where-Object { [String]::IsNullOrEmpty($_.Properties.cpassword) -eq $false }
$preferenceType = "Data sources"
}
Drives
{
$gppWithCpassword = $xmlFile.SelectNodes("Drives/Drive") | where-Object { [String]::IsNullOrEmpty($_.Properties.cpassword) -eq $false }
$preferenceType = "Drive Maps"
}
Services
{
$gppWithCpassword = $xmlFile.SelectNodes("NTServices/NTService") | where-Object { [String]::IsNullOrEmpty($_.Properties.cpassword) -eq $false }
$preferenceType = "Services"
}
default
{ # 次のアイテムの gppWithCpassword と preferenceType をクリアする。
try
{
Clear-Variable -Name gppWithCpassword -ErrorAction SilentlyContinue
Clear-Variable -Name preferenceType -ErrorAction SilentlyContinue
}
catch [Exception]{}
}
}
if ($gppWithCpassword -ne $null)
{
# filePath から抽出した GUID から GPO 名を作成する
$guidRegex = [regex]"\{(.*)\}"
$match = $guidRegex.match($fileFullPath)
if ($match.Success)
{
$gpoGuid = $match.groups[1].value
$gpoName = $gpoGuid
}
else
{
$gpoName = "Unknown"
}
if($isGPModuleAvailable -eq $true)
{
try
{
$gpoInfo = Get-GPO -Guid $gpoGuid -ErrorAction Continue
$gpoName = $gpoInfo.DisplayName
}
catch [Exception] {
Write-Host $_.Exception.Message
}
}
# CPassword が含まれる基本設定を表示する
foreach ( $gpp in $gppWithCpassword )
{
if ( $preferenceType -eq "Drive Maps" )
{
$prefLocation = $category + $driveMapPath + $preferenceType
}
else
{
$prefLocation = $category + $commonPath + $preferenceType
}
$obj = New-Object -typeName PSObject
$obj | Add-Member –membertype NoteProperty –name GPOName –value ($gpoName) –passthru |
Add-Member -MemberType NoteProperty -name Preference -value ($gpp.Name) -passthru |
Add-Member -MemberType NoteProperty -name Path -value ($prefLocation)
Write-Output $obj
}
} # end if $gppWithCpassword
} # end foreach $file
} # end functions Enum-PoliciesWithCpassword
#-----------------------------------------------------------------------------------
# Path が有効であるかどうかを確認する。CPassword が含まれるすべての設定を列挙する。
#-----------------------------------------------------------------------------------
if (Test-Path $Path )
{
Enum-SettingsWithCpassword $Path
}
else
{
Write-Warning "No such directory: $Path"
}


使用例 (システム ドライブは C であると想定されている)

.\Get-SettingsWithCPassword.ps1 –path “C:\Windows\SYSVOL\domain” | Format-List 

注: ドメインの代わりにパスの任意のバックアップ GPO も対象にすることができることに注意してください

検出スクリプトにより、以下のようなリストが生成されます。



リストが長い場合は、出力をファイルに保存することを検討します。

.\Get-SettingsWithCPassword.ps1 –path "C:\Windows\SYSVOL\domain" | ConvertTo-Html > gpps.html 

CPassword の基本設定の削除

CPassword データが含まれる基本設定を削除するには、ドメイン コントローラー上で、またはリモート サーバー管理ツールがインストールされているクライアントから、グループ ポリシー管理コンソール (GPMC) を使用することを推奨します。これらのコンソールにおいて 5 つの手順で基本設定を削除できます。これを行うには、以下の手順を実行します。
  1. GPMC で、CPassword データが含まれる基本設定を開きます。
  2. 基本設定に応じて、操作を [削除] または [無効化] に変更します。
  3. [OK] をクリックして、変更を保存します。
  4. 変更内容がクライアントに伝達されるように、1 回または 2 回のグループ ポリシーの更新サイクルを待ちます。
  5. すべてのクライアント上で変更が適用された後、基本設定を削除します。
  6. 必要に応じて手順 1. ~ 5. を繰り返し、環境全体をクリーニングします。検出スクリプトで返される結果がゼロになれば、作業は完了していることになります。
ファイル ハッシュ情報
プロパティ

文書番号:2962486 - 最終更新日: 2015/10/02 - リビジョン: 1

フィードバック