サイト内の現在位置

PowerShellのログを理解する

NECセキュリティブログ

2024年3月1日

サイバーセキュリティ戦略統括部の松本康平です。本稿では、PowerShellのログについて紹介します。

はじめに

PowerShellは最近のWindowsが標準で備えているコマンドシェルであり、利用者にとって便利なツールである反面、攻撃者にもよく利用されてしまっているのが現状です。PowerShellに関するログについて理解を深めることは、ログ設定やインシデント調査において役に立ちます。本稿では、PowerShellのログについて、実機検証を交えて紹介していきます。

以下の検証は、筆者の検証環境での調査結果です。実環境に設定する際には、必ず検証してから設定するようにしてください。

検証環境

検証環境のOSバージョンおよびPowerShellバージョンは以下のようになっています。

Windowsのバージョン情報

PowerShellのバージョン情報

PowerShellの主要なログ

PowerShellの主要なログには以下の3つがあります。

  • モジュールログ
  • PowerShellスクリプトブロックログ
  • PowerShellトランスクリプションログ

「モジュールログ」と「PowerShellスクリプトブロックログ」はイベントログ「Microsoft-Windows-PowerShell/Operational」上に、それぞれイベントID : 4103、イベントID: 4104として記録されます。また、「PowerShellトランスクリプションログ」は任意のディレクトリにテキストファイルとして出力されます。

それでは、順を追って各ログについて、見ていきましょう。

モジュールログ

Microsoftはモジュールログについて、以下のように説明しています。

指定されたモジュールのメンバーのパイプライン実行イベントを記録します。new window[1]

モジュールログの説明に入る前に、まずPowerShellにおける「モジュール」とは何かを簡単に説明します。モジュールとは、コマンドレット、プロバイダー、関数、変数、エイリアスをパッケージ化したものですnew window[2]。例えば引数に受け取った文字列を標準出力に表示させる「Write-Host」コマンドレットは、「Microsoft.PowerShell.Utility」モジュールに含まれていますnew window[3]。このモジュールは、標準モジュールとして自動的に読み込まれるため、PowerShellを起動すると、特別な設定なしに利用することができます。

また、PowerShell Gallerynew window[4]というMicrosoft公式のサイトでは様々なモジュールが配布されています。これらはImport-Moduleなどでインポートして使うことができるモジュールです。

このようにPowerShellは必要に応じてモジュールを追加することで、機能を拡張していくことができるように設計されています。

話をモジュールログに戻しましょう。モジュールログとは、その名の通りモジュールを記録するログです。なお、全てのモジュールについて記録するのではなく、モジュール名で指定されたもののみを記録対象としています。

それでは、実際に見てみましょう。

Write-Hostを実行した後、イベントログを確認します。左側のウィンドウでWrite-Hostを実行し、右側のウィンドウでイベントID : 4103のレコードを出力しています。イベントログには何も記録されていないことが分かります。これはモジュールログが、Write-Hostコマンドレットを含むMicrosoft.PowerShell.Utilityモジュールを記録対象としていないためです。

次に、Microsoft.PowerShell.Utilityモジュールを記録対象として設定してみましょう。以下を実行しモジュールログを有効化してみます。なお、この設定方法は当該PowerShellセッションのみで有効化するためのものです。永続的な設定はグループポリシーから行ってください(後述します。)。

もう一度Write-Hostを実行してみます。

今度はログが記録されていることがわかります。もう少し詳しく見ていきます。

モジュールログの表示

Get-WinEvent -LogName "Microsoft-Windows-PowerShell/Operational" | Where-Object Id -eq 4103 | Select-Object Message | Format-Table -AutoSize –Wrap

Write-Hostが記録されており、「Hello ModuleLog !!」という文字列が渡されていることも確認できます。(Get-Moduleを実行したログも記録に残っていました。これはMicrosoft.PowerShell.Coreモジュールに含まれているコマンドレットで、記録対象として設定していないため、予想外の動作でした。)

以上、モジュールログについて見てきました。モジュールログはインシデント調査の文脈において、特定のモジュールを監視するために使うことができます。一方で、攻撃者の振る舞いを網羅的に監視するのには向いていないでしょう。

モジュールログをグループポリシーから設定する場合には、以下のような設定画面から行えます。ラジオボタンを有効に設定し、「表示…」というボタンから、モジュール名を指定します。

スクリプトブロックログ

Microsoftはスクリプトブロックログについて、以下のように説明しています。

対話形式で呼び出された場合でも、自動化を介して呼び出された場合でも、コマンド、スクリプト ブロック、関数、スクリプトの処理を記録します。new window[1]

実際にイベントログを見てみましょう。検証環境のWindowsバージョンではスクリプトブロックログはデフォルトで機能するため、特に事前設定は不要でした。無効になっている場合、グループポリシーから設定を有効にすることができます。

まず以下のコマンドで、簡単なスクリプトブロックを実行してみます。

Invoke-Command -ScriptBlock { Write-Host "Hello ScriptBlock Log !!" }

残念ながら、イベントログには記録されませんでした。その後も、自作の短いスクリプトをいくつか試しましたが、ログに出力させることはできませんでした。有効化しても、スクリプトブロックやスクリプトをすべて記録するわけではないようです。

次に攻撃者がよく使うクレデンシャルの収集ツールである、Invoke-Mimikatznew window[5] new window[6]を実行して、ログを確認してみます。左側のウィンドウでInvoke-Mimikatzを実行し、右側でイベントログを表示しています。Invoke-Mimikatzの実行は失敗してしまいましたが、一度に165レコードものイベントログが記録されました。

イベントログの詳細をみて行きましょう。最初のレコードには、Invoke-Mimikatzを起動した際のコマンドライン入力が記録されていました。

次のレコードも見てみましょう。下図では、2行目に「function Invoke-Mimikatz」と記録されており、Invoke-Mimikatz.ps1というスクリプトの中身が丸ごと記録されていることがわかります。イベントログには1レコードあたりの最大容量が決まっているため、複数のレコードに分割されて記録されていることが分かりました。

スクリプトブロックログは、インシデント調査の文脈において、実行されたスクリプトの内容を含めた詳細なログを残すことができる可能性があります。なお、どんな条件でログが記録されるのか、明確なリファレンスを確認することはできませんでしたが、必ずしも全ての活動が記録されているわけではないことに注意が必要です。また、比較的大量のログが記録されるため、ログ容量やログのローテーションに気を付ける必要があります。

PowerShellトランスクリプションログ

MicrosoftはPowerShellトランスクリプションログについて、以下のように説明しています。

トランスクリプトには、ユーザーが入力したすべてのコマンドと、コンソールに表示されたすべての出力が含まれます。new window[7]

実際にログを見てみましょう。Start-Transcriptを使うことで、当該セッションでトランスクリプションログを有効にできます。永続的な設定を行う場合は、グループポリシーから行うことができます。左側でトランスクリプションログを有効にし、Write-Hostを実行しています。右側でトランスクリプションログがファイル出力されていることが分かります。

ファイルを開き、ログの中身を見てみましょう。

PowerShellの入出力がそのまま、テキストに出力されていることがわかります。それでは、出力がないスクリプトを実行するとどうなるでしょうか。ここでは、変数に文字列を代入しているだけで、標準出力のないスクリプトを実行してみます。

新しく出力されたログの中身を見てみましょう。

スクリプトを実行したことだけが記録されており、どんなスクリプトが内部で実行されているのか分かりません。トランスクリプションログは、あくまでも標準入出力について記録するということに注意が必要です。

インシデント調査の文脈において、PowerShellへの標準入出力が確認できることから、攻撃者の実行したコマンドやその出力結果を残すことができる可能性があります。ただし、スクリプトの中身までは追跡できないため、出力を表示しないような振る舞いを追うことはできません。

また、イベントログではなくテキストファイルとして出力されるため、配置場所によっては攻撃者が容易に中身を見たり、消したりすることが可能なため注意が必要です。さらに、ログローテーションするような機能は無いため、有効にしたまま長い時間が経つと、環境によってはディスクを圧迫する可能性があります。このため、ログ収集用のサーバ等に書き込むようにするなどの工夫が必要になるでしょう。

具体例として、各ホストのログを共有フォルダで集中管理することが考えられます。この場合、共有フォルダの権限設定を正しく行う必要があります。権限設定方法については、参考となるPowerShellスクリプトも記載された形で、Microsoftのブログに紹介されていました。リンクのページ中程に記載がありますので、ご参考にしていただければと思います。new window[8]

まとめ

以上、PowerShellの主要な3つのログについて、実機検証を交えて説明してきました。本稿を通して、各ログがどんな時に、どんな情報を残すのか簡単にでもイメージできるようになっていただけたら幸いです。

参考資料

執筆者プロフィール

松本 康平(まつもと こうへい)
セキュリティ技術センター リスクハンティングチーム

所属:
サイバーセキュリティ戦略統括部
セキュリティ技術センター リスクハンティングチーム
経歴:
2017年に新卒入社、セキュア開発運用に関するドキュメント整備、リスクアセスメントに従事
2018年にIPA 中核人材育成プログラムにて制御システムセキュリティについて知見を獲得
2019年から現在まで、ペネトレーションテスト、脆弱性診断、インシデントレスポンス対応、セキュリティ関連のツール調査に従事
その他:
趣味は、愛犬・キャンプ・料理。一児の父。

執筆者の他の記事を読む

アクセスランキング