
Ferramenta de monitoramento em tempo real para sessões remotas do PowerShell usando ETW para capturar e decodificar o protocolo WinRM/PSRP, fornecendo rastreamentos de execução de comandos e registro de logs para análise de segurança.
O RemotePSpy fornece monitoramento em tempo real de sessões remotas do PowerShell, o que é particularmente útil para versões mais antigas (anteriores à 5.0) do PowerShell que não possuem recursos abrangentes de registro (logging) integrados.
Ele utiliza o Event Tracing for Windows (ETW) para obter dados de mensagens do protocolo WinRM, que é usado como transporte para o PowerShell remoto, e decodifica as várias camadas do protocolo para fornecer um rastreamento dos comandos de script executados e suas entradas/saídas.
Atualmente, este é um protótipo de pesquisa inicial e, portanto, não suporta todos os aspectos do Protocolo Remoto do PowerShell (PSRP). Ele ainda pode fornecer insights úteis sobre o que está acontecendo em uma sessão remota do PowerShell.
A maneira mais fácil de instalar é usando o pip:
pip install remotepspy
As dependências devem ser instaladas automaticamente ao instalar via pip, mas caso você deseje instalar a partir do código-fonte, elas estão listadas aqui:
A libwim-15.dll é necessária apenas se você estiver usando o provedor ETW Microsoft-Windows-WinRM (recomendado e padrão) como fonte de dados. Ela é usada para descomprimir certos objetos de fluxo no protocolo WinRM/WSMan que contêm fragmentos de mensagens PSRP. Basta colocá-la no mesmo diretório do script Python principal.
Basta executar RemotePSpy para iniciar o monitoramento e o registro, e pressionar Return quando terminar. O log será gravado no diretório de trabalho atual, com o nome RemotePSpy.log.
A ferramenta também imprimirá uma réplica aproximada do que o usuário do PowerShell remoto veria em sua tela no stdout, juntamente com as informações mais detalhadas no arquivo de log. Registros mais complexos estão disponíveis; consulte "Registro (Logging)" abaixo.
Se você instalou o Python para estar no seu PATH, os scripts executáveis do RemotePSpy também estarão no seu PATH. Caso contrário, talvez seja necessário procurá-los no diretório de site-packages do seu Python.
O RemotePSpy padrão usa o provedor ETW WinRM (recomendado) como fonte de dados. Se você desejar usar o provedor ETW do PowerShell, pode executar RemotePSpy_powershell_prov.
Esta versão pode produzir alguns avisos desnecessários devido à complexidade adicional de rastrear certos estados com base em como os dados são fornecidos neste provedor ETW específico.
O código consiste em uma série de classes bastante modulares que podem aceitar entrada em diferentes camadas da pilha de protocolo. Isso permite que elas sejam conectadas de maneiras ligeiramente diferentes, dependendo de onde os dados são obtidos e em que formato. A maioria das classes aceita uma função de retorno de chamada (callback) que usam para repassar o resultado que produzem para a próxima camada da pilha.
Uma descrição das principais classes usadas é fornecida abaixo, seguida por alguns fluxos de processamento que mostram qual classe alimenta qual em diferentes cenários.
ETWWinRM – Obtém eventos ETW do provedor WinRM.
ETWPowerShell – Obtém eventos ETW do provedor PowerShell.
PowerShellETWParser – Identifica o contexto de Shell para eventos ETW do PowerShell, repassando os dados de fragmento para o PSRPDefragmenter. Também fornece sincronização de threads.
SoapDefragmenter – Remonta mensagens SOAP WSMan completas a partir de eventos ETW do WinRM, repassando o SOAP completo para o WSManPS.
WSManPS – Filtra o WinRM não relacionado ao PowerShell, rastreia o contexto de Shell, extrai dados de fragmentos PSRP do SOAP WSMan e repassa os dados de fragmento para o PSRPDefragmenter.
PSRPDefragmenter – Remonta fragmentos PSRP em mensagens PSRP completas. Os fragmentos são montados por ObjectID, e a exclusividade do ObjectID é garantida levando-se em conta o contexto de Shell. Repassa as mensagens PSRP finais para o PSRPParser.
PSRPParser – Decodifica a mensagem PSRP binária bruta, extraindo detalhes do cabeçalho como RPID, Pipeline ID e MessageType. Repassa as mensagens decodificadas para o SimpleCommandTracer.
SimpleCommandTracer – Interpreta mensagens PSRP usando o MessageType e extrai e imprime/registra comandos, argumentos e suas saídas. Inclui decodificação parcial de objetos PowerShell serializados. Não é uma implementação completa de todos os recursos possíveis, mas tenta cobrir a maioria dos casos comuns para permitir o rastreamento de execução.
Fluxo de processamento ao usar o provedor ETW Microsoft-Windows-WinRM:
ETWWinRM -> SoapDefragmenter -> WSManPS -> PSRPDefragmenter -> PSRPParser -> SimpleCommandTracer
Fluxo de processamento ao usar o provedor ETW Microsoft-Windows-PowerShell:
ETWPowerShell -> PowerShellETWParser -> PSRPDefragmenter -> PSRPParser -> SimpleCommandTracer
Há um registro abrangente em cada camada da pilha de protocolo. Isso permite a depuração em vários níveis e foi especialmente útil durante o desenvolvimento. Esperamos que também possa ser útil para qualquer pessoa que queira investigar o PowerShell remoto em ação, pois é possível obter um rastreamento completo do protocolo em todas as camadas principais.
Atualmente, o código-fonte no final do script, onde os loggers são configurados, deve ser editado para alterar o registro. Versões futuras devem, esperançosamente, fornecer um método melhor para essa configuração.
Cada nome de logger é definido por uma constante, LOGGER_NAME, na classe que o utiliza. Cada logger é definido como filho de "RemotePSpy" (por exemplo, RemotePSpy.etw). Programaticamente, os loggers podem ser configurados usando logging.getLogger() com o nome de log apropriado.
Para referência rápida, os seguintes loggers e níveis fornecerão rastreamentos de protocolo em diferentes camadas do protocolo:
| Dados-chave do Log | Constante do Nome do Logger | Nível |
|---|---|---|
| Rastreamento de comandos | SimpleCommandTracer.LOGGER_NAME | INFO |
| Rastreamento completo de eventos ETW | ETWWinRM.LOGGER_NAME | DEBUG |
| Rastreamento completo de mensagens SOAP WSMan | SoapDefragmenter.LOGGER_NAME | INFO |
| Rastreamento completo de cada fragmento PSRP | PSRPDefragmenter.LOGGER_NAME | DEBUG |
| Rastreamento completo de mensagens PSRP | PSRPParser.LOGGER_NAME | DEBUG |
Observe que o SimpleCommandTracer também gera um rastreamento no stdout, e isso tenta replicar de certa forma a exibição que o usuário do PowerShell remoto veria. Isso é diferente do log de rastreamento de comandos, que registra cada comando, chamada de método de pipeline e saída de pipeline de uma maneira mais precisa, incluindo contexto adicional, como RPID e Pipeline ID.
Um resumo mais completo do que aparece em cada log e em qual nível é fornecido abaixo:
ERROR:
WARNING:
INFO:
DEBUG:
DEBUG:
ERROR:
WARNING:
INFO:
DEBUG:
ERROR:
WARNING:
INFO:
DEBUG:
INFO:
DEBUG:
DEBUG:
ERROR:
DEBUG:
INFO: