
Outil de surveillance en temps réel pour les sessions PowerShell distantes utilisant ETW pour capturer et décoder le protocole WinRM/PSRP, fournissant des traces d'exécution de commandes et une journalisation pour l'analyse de sécurité.
RemotePSpy assure une surveillance en direct des sessions PowerShell distantes, ce qui est particulièrement utile pour les anciennes versions (antérieures à 5.0) de PowerShell qui ne disposent pas de fonctionnalités complètes de journalisation intégrées.
Il utilise le suivi d'événements pour Windows (ETW) pour obtenir les données de messages du protocole WinRM utilisé comme transport pour PowerShell distant, et décode les différentes couches de protocole afin de fournir une trace des commandes de script exécutées ainsi que leurs entrées/sorties.
Il s'agit actuellement d'un prototype de recherche précoce et il ne prend donc pas en charge tous les aspects du protocole PowerShell distant (PSRP). Il peut néanmoins fournir des informations utiles sur ce qui se passe dans une session PowerShell distante.
Le moyen le plus simple d'installer est d'utiliser pip :
pip install remotepspy
Les dépendances devraient être installées automatiquement lors de l'installation via pip, mais au cas où vous souhaiteriez installer à partir des sources, elles sont listées ici :
La libwim-15.dll n'est requise que si vous utilisez le fournisseur ETW Microsoft-Windows-WinRM (recommandé et par défaut) comme source de données. Elle est utilisée pour décompresser certains objets de flux du protocole WinRM/WSMan qui contiennent des fragments de messages PSRP. Placez-la simplement dans le même répertoire que le script Python principal.
Exécutez simplement RemotePSpy pour démarrer la surveillance et la journalisation, puis appuyez sur Entrée lorsque vous avez terminé. Le journal sera écrit dans le répertoire de travail actuel, nommé RemotePSpy.log.
L'outil affichera également une réplique approximative de ce que l'utilisateur de PowerShell distant verrait à l'écran sur stdout, en plus des informations plus détaillées dans le fichier journal. Une journalisation plus complexe est disponible, voir « Journalisation » ci-dessous.
Si vous avez installé Python pour qu'il soit dans votre PATH, les scripts exécutables RemotePSpy seront également dans votre PATH. Sinon, vous devrez peut-être les chercher dans votre répertoire site-packages Python.
Le RemotePSpy par défaut utilise le fournisseur ETW WinRM (recommandé) comme source de données. Si vous souhaitez utiliser le fournisseur ETW PowerShell à la place, vous pouvez exécuter RemotePSpy_powershell_prov.
Cette version peut produire des avertissements inutiles en raison de la complexité accrue du suivi de certains états selon la manière dont les données sont fournies dans ce fournisseur ETW particulier.
Le code est composé d'un certain nombre de classes assez modulaires qui peuvent accepter des entrées à différentes couches de la pile de protocoles. Cela permet de les connecter de manières légèrement différentes selon l'origine des données et leur forme. La plupart des classes acceptent une fonction de rappel qu'elles utilisent pour transmettre le résultat qu'elles produisent à la couche suivante de la pile.
Une description des principales classes utilisées est donnée ci-dessous, suivie de quelques flux de traitement qui montrent quelle classe alimente laquelle dans différents scénarios.
ETWWinRM – Obtient les événements ETW du fournisseur WinRM.
ETWPowerShell – Obtient les événements ETW du fournisseur PowerShell.
PowerShellETWParser – Identifie le contexte Shell pour les événements ETW PowerShell, transmettant les données de fragments à PSRPDefragmenter. Fournit également la synchronisation des threads.
SoapDefragmenter – Réassemble les messages SOAP WSMan complets à partir des événements ETW WinRM, transmettant le SOAP complet à WSManPS.
WSManPS – Filtre les WinRM non liés à PowerShell, suit le contexte Shell, extrait les données de fragments PSRP du SOAP WSMan et transmet les données de fragments à PSRPDefragmenter.
PSRPDefragmenter – Réassemble les fragments PSRP en messages PRSP complets. Les fragments sont assemblés par ObjectID, et l'unicité de l'ObjectID est garantie en tenant compte du contexte Shell. Transmet les messages PSRP finaux à PSRPParser.
PSRPParser – Décode le message PSRP binaire brut, extrayant les détails d'en-tête comme le RPID, l'ID de pipeline et le MessageType. Transmet les messages décodés à SimpleCommandTracer.
SimpleCommandTracer – Interprète les messages PSRP à l'aide du MessageType, et extrait et imprime/journalise les commandes, les arguments et leurs sorties. Inclut un décodage partiel des objets PowerShell sérialisés. Ce n'est pas une implémentation complète de toutes les fonctionnalités possibles, mais tente de couvrir la plupart des cas courants pour permettre une trace d'exécution.
Flux de traitement lors de l'utilisation du fournisseur ETW Microsoft-Windows-WinRM :
ETWWinRM -> SoapDefragmenter -> WSManPS -> PSRPDefragmenter -> PSRPParser -> SimpleCommandTracer
Flux de traitement lors de l'utilisation du fournisseur ETW Microsoft-Windows-PowerShell :
ETWPowerShell -> PowerShellETWParser -> PSRPDefragmenter -> PSRPParser -> SimpleCommandTracer
Une journalisation complète est disponible à chaque couche de la pile de protocoles. Cela permet le débogage à différents niveaux et a été particulièrement utile pendant le développement. Espérons que cela pourra également être utile à toute personne souhaitant étudier PowerShell distant en action, car il est possible d'obtenir une trace complète du protocole à toutes les couches clés.
Actuellement, le code source à la fin du script où les journaux sont configurés doit être modifié pour changer la journalisation. Les futures versions devraient espérons-le fournir une meilleure méthode pour une telle configuration.
Chaque nom de journal est défini par une constante, LOGGER_NAME, dans la classe qui l'utilise. Chaque journal est défini comme un enfant de « RemotePSpy » (par exemple RemotePSpy.etw). Programmatiquement, les journaux peuvent être configurés en utilisant logging.getLogger() avec le nom de journal approprié.
Pour référence rapide, les journaux et niveaux suivants vous fourniront des traces de protocole à différentes couches du protocole :
| Données de journal clés | Constante de nom de journal | Niveau |
|---|---|---|
| Trace de commande | SimpleCommandTracer.LOGGER_NAME | INFO |
| Trace complète des événements ETW | ETWWinRM.LOGGER_NAME | DEBUG |
| Trace complète des messages SOAP WSMan | SoapDefragmenter.LOGGER_NAME | INFO |
| Trace complète de chaque fragment PSRP | PSRPDefragmenter.LOGGER_NAME | DEBUG |
| Trace complète des messages PSRP | PSRPParser.LOGGER_NAME | DEBUG |
Notez que SimpleCommandTracer affiche également une trace sur stdout, et celle-ci tente de reproduire quelque peu l'affichage tel que l'utilisateur de PowerShell distant le verrait. Cela diffère du journal de trace de commande qui journalise chaque commande, appel de méthode de pipeline et sortie de pipeline de manière plus précise, y compris un contexte supplémentaire tel que le RPID et l'ID de pipeline.
Un résumé plus complet de ce qui apparaît dans chaque journal à quel niveau est donné ci-dessous :
ERROR :
WARNING :
INFO :
DEBUG :
DEBUG :
ERROR :
WARNING :
INFO :
DEBUG :
ERROR :
WARNING :
INFO :
DEBUG :
INFO :
DEBUG :
DEBUG :
ERROR :
DEBUG :
INFO :