Windows PowerShell悪意のあるコードを回避する

Don Jones

思い出してみてください。Windows Vista がまだベータ版だったころ、新しいコマンド ライン シェルのごく初期のバージョンであったコードネーム "Monad" に関するうわさが飛び交っていました (言うまでもなく、このコマンド ライン シェルは後に Windows PowerShell として知られることになります)。その当時、主要メディアによって "初めての Windows Vista ウイルス" に関する多くの報道がなされました。

実際のところ、その "ウイルス" は、"Monad" を標的とした概念実証型のマルウェア スクリプトでした。そのスクリプトを実行するには、"Monad" 自体に特別な構成を行う必要がありました。つまり、既定の構成では実行されなかったということです。また、このような報道がなされる前に、マイクロソフトは Windows Vista® に "Monad" が同梱されないことを既に発表していました。要するに、この一連の事態は (少なくとも、ほぼ) 空騒ぎだったというわけです。

しかし、Windows PowerShellTM の人気は上昇しており、既に 100 万回以上ダウンロードされています。これは、Windows PowerShell を使用して悪意のあるスクリプトが作成される可能性が高まったとも言えます。Windows PowerShell で損害を与える可能性があるスクリプトを記述できるということは既知の事実であり、Windows PowerShell、cmd.exe、VBScript など、すべての管理ツールは悪意のある攻撃に使用される可能性があります。このため、特定の PS1 ファイルが安全であると決めつけることはできません。

幸運にも、Windows PowerShell はスクリプトを実行しないように既定で構成されているため、ユーザーによる操作がなければ、悪意のあるスクリプトは実行されません。今月の記事では、この状況がどのようにして発生することが予想されるかについて説明します。この記事は Windows PowerShell の印象を悪くすることを目的としているわけではありません。マイクロソフトは、多くの危険性が回避されるすばらしいスクリプト シェルを設計したと思います。しかし、今回の内容は、この予想される攻撃を回避するための準備という目的のためだけでも論じる価値があります。

既定で安全

Windows PowerShell が、マイクロソフトが有名な Trustworthy Computing (信頼できるコンピューティング) 構想を発表した後に初めて設計した言語であるということは注目に値します。セキュリティの第一人者である Michael Howard (『Writing Secure Code』の筆者) は、Windows PowerShell チームの "セキュリティ アドバイザ" としての役割を果たしました。彼の支援によって、可能な限り安全なコードが記述されていること、そしてこれが最も重要ですが、シェルの既定の構成が安全であることが保証されました。

まず、セキュリティに関する Windows PowerShell の初期設定を簡単に見ていきましょう。このシェルの既定の設定では、拡張子 PS1 のファイルをダブルクリックしても、そのファイルは実行されません。この拡張子はメモ帳に関連付けられています。実は、このシェルの既定の設定でどのスクリプトも実行されない理由は、実行ポリシーと呼ばれる組み込みの機能が動作するためです。実行ポリシーには、スクリプトの実行条件が記述されています。既定では、この実行ポリシーは Restricted に設定されており、どのスクリプトも実行されません。シェルは対話形式でのみ使用できます。実行ポリシーは、Set-ExecutionPolicy コマンドレットやマイクロソフトから提供されている管理用テンプレート (ADM ファイル) を使用して変更できます (この ADM ファイルは go.microsoft.com/fwlink/?LinkId=102940 からダウンロードできます)。図 1 は、設定可能な実行ポリシーを示しています。

図 1 安全な実行ポリシーの選択

図 1** 安全な実行ポリシーの選択 **(画像を拡大するには、ここをクリックします)

実行ポリシーの例外はごくわずかです。具体的には、実行ポリシーが Restricted に設定されている場合でも、マイクロソフトから提供され、シェルと共にインストールされるいくつかの特定の XML ファイルは、シェルによるインポートを許可されます。これらのファイルは、Microsoft® .NET Framework の型の拡張や、ほとんどの .NET オブジェクト型に使用されるレイアウトの既定の書式設定などの特定の機能を提供するために使用されます。このため、これらのファイルはシェルの起動時に必ず読み込まれる必要があります。

これらのファイルには実行可能コードが含まれている可能性があり、実際に含まれていますが、マイクロソフトによってデジタル署名されています。ファイルが改ざんされると、この署名は無効になり、シェルの起動時にファイルがインポートされなくなります。この設計によって、悪意のあるコードを挿入しようとするマルウェアから、これらの XML ファイルを強力に保護できます。

もちろん、実行ポリシーを Restricted のままにしておくと、独自に作成した Windows PowerShell プロファイル スクリプトも起動時に実行されません。既定では、Windows PowerShell によってプロファイル スクリプトは作成されませんが、4 つの特定の場所から特定の名前を持つファイルが検索されます。ファイルが検出された場合、Windows PowerShell の起動時に毎回それらのファイルの実行が試行されます (Windows PowerShell と共にインストールされるドキュメントには、プロファイル スクリプトの検索に使用されるフォルダ名とファイル名が詳しく記載されています)。このプロファイルは、これから説明する攻撃にとって重要な役割を果たします。

実行ポリシーを変更する

今月のコマンドレット

Set-AuthenticodeSignature に関連するコマンドレットとして、Get-AuthenticodeSignature があります。このコマンドレットは、デジタル署名されたスクリプトを調べて、署名の詳細情報を提供します。特定のファイルを指定するだけで、ファイルが署名されているかどうかだけでなく、署名が破損しているかどうか、どの証明書がファイルの署名に使用されたかなどの情報を確認できます。このコマンドレットには、Windows PowerShell スクリプトだけでなく、次のような署名付きの実行可能ファイルも指定できます。

PS C:\Program Files\Microsoft Office\Office12>
Get-AuthenticodeSignature excel.exe | Format-List *

このコマンドを実行すると、上記のファイルが Microsoft Corp. によって Microsoft Code Signing CA から発行された証明書を使用して署名されていることがわかります。

コマンドの結果

コマンドの結果  (画像を拡大するには、ここをクリックします)

ここで強調したいのは、既定の状態では、Windows PowerShell でコードを実行することは (不可能ではありませんが) 非常に難しいということです。もちろん、これには悪意のあるコードも含まれます。コードを実行するには、悪意のあるスクリプトも実行できる状態に実行ポリシーを変更する必要があります。もちろんこのコラムの目的は、Windows PowerShell のセキュリティ ホールに警鐘を鳴らすことではなく、システムのセキュリティを強化するためのベスト プラクティスを紹介することです。

最も制限が弱い実行ポリシーは Unrestricted です。この実行ポリシーでは、すべてのスクリプトが何の疑いも持たれずに制約なしで実行されます。これは、皆さんがこれまで経験してきた、VBScript ファイルとバッチ ファイルによって攻撃されるシナリオと実質的に同じ状態です。シェルの実行ポリシーを Unrestricted に設定するということは、悪意のあるスクリプトで攻撃して損害を与えてほしいと言っているようなものです。Unrestricted に設定して、スクリプトによる攻撃を受けてしまった場合は、Unrestricted に設定した正当な理由を用意し、ウイルスによって環境が破壊された状況を説明するときに、自分が下した判断について白状する覚悟をしておきましょう。

とは言うものの、Unrestricted に設定されている場合でも、Windows PowerShell はインターネットからダウンロードされたスクリプトの検出を試行し、それらを実行する前に警告を表示します。しかし、実行ポリシーを Unrestricted に設定することはやはり良い考えではありません。

スクリプトに署名する

スクリプトを実行できる最も安全な実行ポリシーは、AllSigned です。この設定は、名前が示すとおり、信頼された証明書を使用して作成された破損していないデジタル証明書 (どんな証明書でもよいというわけではありません) で署名されたスクリプトのみを実行します。スクリプトに署名するには、クラス 3 のデジタル証明書、もっと具体的に言うと Microsoft Authenticode コード署名証明書が必要です。これらの証明書は、企業に内部公開キー基盤 (PKI) が実装されている場合は、そこから入手できます。また、CyberTrust、Thawte、VeriSign など、証明書を販売する証明機関 (CA) から購入することもできます。

スクリプトへの署名に使用できる証明書がコンピュータにインストールされているかどうかを確認するには、次のコマンドレットを実行します。

Get-ChildItem CERT: -recurse –codeSigningCert

証明書を Windows® コンピュータにインストールしたら、Set-AuthenticodeSignature コマンドレットを使用してデジタル証明書を作成および適用します。この証明書は、外見上は意味のない一連のコメント行としてスクリプトの末尾に記述されます。一部のスクリプト エディタでは、スクリプトを保存したときに自動的に署名する機能など、スクリプト ファイルに署名を適用する便利なオプションが提供されている場合もあります。

AllSigned は、運用環境での使用に最適な実行ポリシーです。この実行ポリシーによって悪意のあるスクリプトの実行を完全に回避できるわけではありませんが、悪意のあるスクリプトが確実に署名されるため、スクリプトの作成者を確認できます (信頼できる CA のみを信頼するように Windows コンピュータが構成されていることを前提としていますが、コラムの内容から少しそれるため、これに関する説明は割愛します)。興味深いことに、Windows Script Host (WSH) 5.6 以降の TrustPolicy を設定して、同じようにデジタル署名を要求することもできますが、実際にこの設定を使用している管理者にはほとんど出会ったことがありません。

では、ここまで説明した内容を簡単にまとめてみましょう。実行ポリシーを Restricted に設定すると、悪意のあるスクリプトの攻撃を受けずに済みますが、有用なスクリプトを実行することもできません。実行ポリシーを AllSigned に設定すると、シェルでは署名されたスクリプトのみが実行されます。悪意のあるスクリプトの作成者が、身元を突き止めることができる検証済みの身分証明をスクリプトに含めることはほとんどないため、この設定は非常に安全です。一方、Unrestricted は非常に安全性が低い設定です。この設定を使用した場合、最終的に悪意のあるスクリプトの攻撃を受ける可能性があります (Unrestricted は安全ではありませんが何かを偽った設定ではなく、おそらく何の目的もなく使用されることはないため、特定の脆弱性であるとは考えていません)。

裏口から忍び込む

実行ポリシーには、RemoteSigned というもう 1 つの設定があります。これは最近ほとんどの管理者が使用している設定だと思います。理由は単純であり、Unrestricted よりも安全で、AllSigned よりも厄介な設定ではないためです。RemoteSigned では、ローカル スクリプトに署名が要求されません。このため、ローカル ドライブ上にある PS1 ファイルは、署名されていなくても実行されます。リモート スクリプトは署名されていなければ実行されません。主なリモート スクリプトには、Internet Explorer® や Outlook® (これらのアプリケーションはダウンロードされたファイルを特別なフラグでマークします) を使用してインターネットからダウンロードされたスクリプトなどがあります。

しかし、RemoteSigned を設定した場合、安全であるという誤った認識が生まれる可能性があります。まず、特別なフラグを適用せずにリモート スクリプトをダウンロードすることは簡単です。たとえば、マイクロソフト製以外のブラウザ、およびマイクロソフト製以外のほとんどの電子メール クライアントではこのフラグが設定されません。注意する必要があるのは、このフラグが設定されていない場合、ダウンロードされたスクリプトは Windows PowerShell によってローカル スクリプトと見なされ、署名されていなくても実行されるということです。それでもまだ、これが深刻な脆弱性であるとは考えられません。スクリプトを実行するには、そのスクリプトを実際にダウンロードし、Windows PowerShell を起動して手動で実行する必要があるためです。だれかをだましてこれらの手順をすべて実行させるのは困難であり、管理者 (通常はネットワーク上で Windows PowerShell をインストールしている唯一のユーザー) が自ら実行するはずもありません。

ただし、RemoteSigned にはマルウェアが忍び込むことができる "裏口" があります。Windows PowerShell プロファイル スクリプトのことを覚えているでしょうか。これらのスクリプトが (自分で作成したかマルウェアによって作成されたかにかかわらず) 存在する場合、Windows PowerShell が起動するたびに実行されます。また、RemoteSigned 実行ポリシーでは、ローカルのプロファイル スクリプトに署名が要求されません。

このシナリオを次に示します。

  1. マルウェアがシステムに侵入し、シェル用のプロファイル スクリプトを作成するか、既存のプロファイル スクリプトに悪意のあるコードを挿入します。通常、マルウェアはログオン ユーザー アカウントを使用して実行されます。一般的に、このアカウントにはプロファイル スクリプトを変更するためのアクセス許可が与えられています。
  2. プロファイル スクリプトが作成されたか、悪意のあるコードが含まれるように変更されたことに気付かないまま、ユーザーが Windows PowerShell を起動します。コードが実行され、システムは攻撃を受けます。常に管理者の資格情報を使用して Windows PowerShell を起動している場合、被害の規模は大きくなりますが、Windows PowerShell を使用してなんらかの操作を実行するには必ず管理者特権が必要であるため、通常はこの規模の被害を受けます。

RemoteSigned 実行ポリシーが設定されている場合、上記のようにプロファイルを利用すれば、悪意のあるコードを含むどのようなコードでも、ユーザーが気付かないうちに実行することができます。

プロファイルを保護する

プロファイルを保護するには、AllSigned 実行ポリシーを使用するしかありません。AllSigned では、プロファイル スクリプトもデジタル署名されている必要があります。デジタル署名されていない場合、それらのスクリプトは Windows PowerShell の起動時に実行されません。プロファイル スクリプトが署名されていて、悪意のある変更が加えられた場合、デジタル署名も破損するため、プロファイル スクリプトは実行されません。この問題は Windows PowerShell の起動時に通知されます。スクリプトを実行する必要がある運用環境では、AllSigned のみが安全な実行ポリシーの設定であることは間違いありません。

別の方法もありますが、より複雑で信頼性も低下します。この方法では、Windows PowerShell が検索する 4 つのファイルそれぞれに対して、空のプロファイル スクリプト ファイルを作成します。新しいユーザー アカウント (ここではプロファイル編集者と呼びます) を使用してこれらのファイルを作成し、プロファイル編集者アカウントのみがファイルを変更できるように、ファイルの NTFS アクセス許可を設定します。他のアカウントには読み取り専用アクセス許可を与えます。

プロファイルを編集するとき以外は、プロファイル編集者アカウントでログオンしないようにしてください。この方法を使用すると、通常のユーザー アカウントはプロファイル スクリプトを変更できなくなります。また、通常のアカウントでログオンしたときにマルウェアが実行されても、プロファイル スクリプトは変更されません。では、プロファイル編集者としてログオンしたときにマルウェアが実行されたらどうなるでしょうか。いずれにしろ、プロファイル編集者としてログオンしたときはプロファイルを編集するため、プロファイルが変更されていれば気付くはずです。

すべてのユーザー用のプロファイル スクリプトを作成し、上記で説明したような厳密なアクセス許可で制御することによって、セキュリティを強化することもできます。このスクリプトには、Get-AuthenticodeSignature コマンドレットを使用するコードを記述し、シェルが検索するその他のプロファイル上のデジタル署名が確認されるようにします。これにより、実質的にはプロファイル スクリプトに署名が要求され、他のスクリプトには署名が要求されないことになります。

しかし、より徹底的にプロファイルを保護するには AllSigned 実行ポリシーが適しています。ネットワークに接続されているすべてのコンピュータには、可能であればグループ ポリシーを使用して Restricted 実行ポリシーを適用することをお勧めします。この設定はローカルの設定よりも優先されるため、ドメインに新しいコンピュータを追加した場合、そのコンピュータでスクリプトの実行が拒否されるように自動的に設定することができます。スクリプトの実行を許可する必要があるコンピュータには、AllSigned 実行ポリシーを設定する別のグループ ポリシーを適用します。すべてのスクリプトにデジタル署名する必要はありますが、身元を確認できる開発者が作成した信頼できるスクリプトのみが環境内で実行されるため、攻撃について心配する必要はなくなります。

Don Jones は SAPIEN Technologies のリード スクリプト グルであり、『Windows PowerShell: TFM』(SAPIEN Press、2007年) の共著者でもあります。連絡先については、www.ScriptingAnswers.com にアクセスしてください。

© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; 許可なしに一部または全体を複製することは禁止されています.