
リモートPowerShellセッションのライブ監視ツール。ETWを使用してWinRM/PSRPプロトコルをキャプチャおよびデコードし、セキュリティ分析のためのコマンド実行トレースとロギングを提供します。
RemotePSpyは、リモートPowerShellセッションのライブ監視を提供します。これは、包括的なログ機能が組み込まれていない古い(5.0より前の)バージョンのPowerShellで特に役立ちます。
これは、リモートPowerShellのトランスポートとして使用されるWinRMプロトコルからメッセージデータを取得するためにWindowsイベントトレーシング(ETW)を使用し、さまざまなプロトコル層をデコードして、実行されたスクリプトコマンドとその入出力のトレースを提供します。
これは現在、初期の研究用プロトタイプであり、PowerShellリモートプロトコル(PSRP)のすべての側面をサポートしているわけではありません。それでも、リモートPowerShellセッションで何が起こっているかについて有用な洞察を提供できます。
最も簡単なインストール方法はpipを使用することです:
pip install remotepspy
依存関係はpipでインストールする際に自動的にインストールされるはずですが、ソースからインストールしたい場合に備えて、ここにリストされています:
libwim-15.dllは、データソースとして(推奨され、デフォルトの)Microsoft-Windows-WinRM ETWプロバイダーを使用する場合にのみ必要です。これは、PSRPメッセージフラグメントを含むWinRM/WSManプロトコル内の特定のストリームオブジェクトを解凍するために使用されます。メインのPythonスクリプトと同じディレクトリに配置するだけです。
RemotePSpyを実行して監視とログ記録を開始し、終了したらReturnキーを押すだけです。ログは現在の作業ディレクトリにRemotePSpy.logという名前で書き込まれます。
このツールはまた、リモートPowerShellのユーザーが画面で見るであろうもののおおよその複製を、ログファイル内のより詳細な情報とともにstdoutに出力します。より複雑なログ記録が利用可能です。以下の「ログ記録」を参照してください。
PythonをPATHにインストールした場合、RemotePSpy実行可能スクリプトもPATHに含まれます。それ以外の場合は、Pythonのsite-packagesディレクトリで探す必要があるかもしれません。
デフォルトのRemotePSpyは、(推奨される)WinRM ETWプロバイダーをデータソースとして使用します。代わりにPowerShell ETWプロバイダーを使用したい場合は、RemotePSpy_powershell_provを実行できます。
このバージョンは、この特定のETWプロバイダーでデータが提供される方法に基づいて特定の状態を追跡する複雑さが追加されているため、不要な警告がいくつか生成される場合があります。
コードは、プロトコルスタックのさまざまな層で入力を受け入れることができる、かなりモジュール化された多数のクラスで構成されています。これにより、データが取得される場所と形式に応じて、それらを少し異なる方法で接続できます。ほとんどのクラスはコールバック関数を受け入れ、それを使用して生成した結果をスタックの次の層に渡します。
使用される主要なクラスの説明を以下に示し、その後に、さまざまなシナリオでどのクラスがどのクラスに供給されるかを示すいくつかの処理フローを示します。
ETWWinRM – WinRMプロバイダーからETWイベントを取得します。
ETWPowerShell – PowerShellプロバイダーからETWイベントを取得します。
PowerShellETWParser – PowerShell ETWイベントのShellコンテキストを識別し、フラグメントデータをPSRPDefragmenterに渡します。また、スレッド同期も提供します。
SoapDefragmenter – WinRM ETWイベントから完全なWSMan SOAPメッセージを再構築し、完全なSOAPをWSManPSに渡します。
WSManPS – PowerShellに関連しないWinRMをフィルタリングし、Shellコンテキストを追跡し、WSMan SOAPからPSRPフラグメントデータを解析して抽出し、フラグメントデータをPSRPDefragmenterに渡します。
PSRPDefragmenter – PSRPフラグメントを完全なPSRPメッセージに再構築します。フラグメントはObjectIDによって組み立てられ、ObjectIDの一意性はShellコンテキストを考慮することで保証されます。最終的なPSRPメッセージをPSRPParserに渡します。
PSRPParser – 生のバイナリPSRPメッセージをデコードし、RPID、Pipeline ID、MessageTypeなどのヘッダー詳細を抽出します。デコードされたメッセージをSimpleCommandTracerに渡します。
SimpleCommandTracer – MessageTypeを使用してPSRPメッセージを解釈し、コマンド、引数、およびその出力を抽出して出力/ログ記録します。シリアル化されたPowerShellオブジェクトの部分的なデコードが含まれます。考えられるすべての機能の完全な実装ではありませんが、実行トレースを可能にするために最も一般的なケースをカバーしようとします。
Microsoft-Windows-WinRM ETWプロバイダーを使用する場合の処理フロー:
ETWWinRM -> SoapDefragmenter -> WSManPS -> PSRPDefragmenter -> PSRPParser -> SimpleCommandTracer
Microsoft-Windows-PowerShell ETWプロバイダーを使用する場合の処理フロー:
ETWPowerShell -> PowerShellETWParser -> PSRPDefragmenter -> PSRPParser -> SimpleCommandTracer
プロトコルスタックの各層に包括的なログ記録があります。これにより、さまざまなレベルでのデバッグが可能になり、開発中に特に役立ちました。主要なすべての層でプロトコルの完全なトレースを取得できるため、動作中のリモートPowerShellを調査したい人にも役立つことを願っています。
現在、ロガーが設定されているスクリプトの最後にあるソースコードを編集して、ログ記録を変更する必要があります。将来のリリースでは、このような設定のためのより良い方法が提供されることを願っています。
各ロガー名は、それを使用するクラスの定数LOGGER_NAMEによって定義されます。すべてのロガーは「RemotePSpy」の子として定義されています(例: RemotePSpy.etw)。プログラム的には、適切なログ名でlogging.getLogger()を使用してロガーを設定できます。
簡単な参照として、次のロガーとレベルは、プロトコルのさまざまな層でプロトコルトレースを提供します:
SimpleCommandTracerはstdoutにもトレースを出力し、これはリモートPowerShellユーザーが見るであろう表示をいくらか再現しようとすることに注意してください。これは、各コマンド、パイプラインメソッド呼び出し、およびパイプライン出力を、RPIDやPipeline IDなどの追加コンテキストを含めて、より正確な方法でログ記録するコマンドトレースログとは異なります。
各ログにどのレベルで何が表示されるかのより完全な要約を以下に示します:
ERROR:
WARNING:
INFO:
DEBUG:
DEBUG:
ERROR:
WARNING:
INFO:
DEBUG:
ERROR:
WARNING:
INFO:
DEBUG:
INFO:
DEBUG:
DEBUG:
ERROR:
DEBUG:
INFO:
| 主要なログデータ | ロガー名定数 | レベル |
|---|
| コマンドトレース | SimpleCommandTracer.LOGGER_NAME | INFO |
| 完全なETWイベントトレース | ETWWinRM.LOGGER_NAME | DEBUG |
| 完全なWSMan SOAPメッセージトレース | SoapDefragmenter.LOGGER_NAME | INFO |
| 各PSRPフラグメントの完全なトレース | PSRPDefragmenter.LOGGER_NAME | DEBUG |
| 完全なPSRPメッセージトレース | PSRPParser.LOGGER_NAME | DEBUG |