Como conectei computadores e usuários a portas de dispositivos de rede no programa de monitoramento Network MACMonitor

Sou desenvolvedor do software de monitoramento de rede Network MACMonitor .


No processo de desenvolvimento do programa, surgiu uma tarefa: determinar quais computadores os usuários estão usando e associar essas informações às portas dos dispositivos de rede. Neste artigo, quero escrever como consegui fazer isso.


imagem


Comecei com considerações simples: para associar um usuário a uma porta em um dispositivo de rede, você deve primeiro conectar o computador com o qual o usuário está trabalhando nessa porta. Como o programa Network MACMonitor permite encontrar endereços mac nas portas dos dispositivos de rede, foi decidido conectar computadores às portas usando endereços mac. Em seguida, você precisa conectar usuários a computadores. Esta informação pode ser obtida interrogando computadores de qualquer maneira.


Vi duas opções para resolver esse problema:


  1. Escreva um agente do Windows e interrogue-o usando o Network MACMonitor;
  2. Use a WMI (Instrumentação de Gerenciamento do Windows).

A versão com o agente do Windows tem várias desvantagens significativas para mim:


  • desenvolvimento de um protocolo seguro para interação em rede de um agente Windows com o Network MACMonitor;
  • a necessidade de pré-instalar o agente nos computadores;
  • usando uma linguagem de programação diferente (escrevo em Java), já que considero o Java inadequado para escrever um agente: devido ao grande consumo de memória virtual e à necessidade de instalar o JRE em todos os computadores.

Por causa de todas as desvantagens acima, decidi me debruçar sobre a opção usando o WMI.


Desenvolvimento de cliente WMI


Como o Network MACMonitor é escrito em Java, tentei encontrar uma biblioteca Java pronta para plataforma que implementa a funcionalidade do cliente WMI. E então fiquei desapontado - não existe tal biblioteca. Todas as bibliotecas existentes são wrappers nos utilitários do Windows ou (biblioteca j-Interop) requerem manipulação adicional do registro (alteração de propriedade e permissões nas ramificações do registro) para ativar o WMI por meio de um registro remoto. Como não havia uma biblioteca totalmente funcional para Java, decidi encontrar uma biblioteca ou um cliente WMI gravado em qualquer outra linguagem de programação. E encontrou um cliente WMI para Linux. Depois de baixar e verificar seu trabalho, percebi que é possível pesquisar computadores com Windows no Linux.


Se isso for possível, decidi escrever minha biblioteca em Java puro, o que me permitiria pesquisar o computador usando o WMI.


Para escrever a biblioteca, era necessária documentação clara sobre a operação do protocolo WMI. Descobriu-se que existe essa documentação e é de domínio público.


Comecei a me preparar para escrever a biblioteca olhando a pilha de rede do protocolo WMI.


ProtocoloEspecificações
Instrumentação de Gerenciamento do Windows (WMI)MS-WMI, MS-WMIO
Modelo de Objeto Distribuído (DCOM)MS-DCOM
Chamada de procedimento remoto (RPC)MS-RPCE
Protocolo de controle de transmissão (TCP)-
Protocolo de Internet (IP)-

Para que o WMI funcione corretamente, todos os níveis de pilha devem ser implementados.


Como o WMI não foi implementado em Java, passei para o próximo protocolo na pilha - DCOM. E aqui eu tive sorte. Embora a biblioteca j-Interop acima mencionada não implemente a funcionalidade WMI, a funcionalidade DCOM é implementada nela. Portanto, resta escrever uma implementação do protocolo WMI, ou seja, gravar uma implementação das especificações MS-WMI e MS-WMIO.


Comecei implementando a especificação MS-WMIO, responsável pelo formato de codificação de dados em pacotes de rede do protocolo WMI. Pela especificação, aprendi que, ao codificar dados, é usada a especificação de sintaxe estendida de Backus-Naur (ABNF, RFC 5234). A especificação MS-WMIO descreve completamente o formato de codificação usando o ABNF. Sabe-se que, se houver uma gramática descrita no ABNF, é possível criar um analisador para essa gramática. Na Internet, encontrei um gerador de analisador ABNF para Java e o inseri com uma gramática extraída da especificação. Como o analisador gerado trabalhava com seqüências de caracteres, e o MS-WMIO descreve um formato de codificação binária, a idéia era simplesmente substituir o analisador gerado por seqüências de caracteres por matrizes e caracteres com bytes. Mas, analisando o número de arquivos em que era necessária uma substituição e também aprendendo com a especificação do MS-WMIO que às vezes seria necessário trabalhar com bits, percebi que seria muito difícil corrigir o analisador gerado e decidi abandonar essa idéia. Eu pensei que escrever um analisador do zero seria mais rápido. E agora o analisador estava pronto.


Mas como verificar se o analisador foi gravado corretamente se a especificação MS-WMI, responsável pela operação do protocolo WMI, ainda não foi implementada? Então o Wireshark, um analisador de tráfego de rede, me ajudou. Depois de fazer solicitações WMI usando as ferramentas padrão do Windows (wbemtest), tendo desabilitado a criptografia anteriormente, recebi pacotes de rede e os salvei em arquivos binários. Já era possível usar esses arquivos como dados de teste para o analisador.


Quando o analisador foi testado e os erros encontrados foram corrigidos, continuei implementando a especificação MS-WMI, que descreve a operação do protocolo WMI.


A especificação MS-WMI é dividida em servidor e cliente. Implementei parcialmente a parte do cliente, na medida necessária para pesquisar um computador via WMI. Nesta parte, eu também precisava do Wireshark, mas já analisava a sequência de pacotes de rede durante a pesquisa WMI.


Tentando obter os dados necessários usando o WMI


Depois de escrever a biblioteca WMI, tornou-se a tarefa de usá-la no programa Network MACMonitor. Surgiu a pergunta: que dados devem ser obtidos dos computadores? Eu pensei que precisava obter o nome do computador, domínio, sistema operacional, tempo de ativação, endereços mac, endereços IP, usuários ativos que trabalham no computador.


Mas surgiu um problema muito importante: como identificar um computador exclusivamente durante a pesquisa WMI? Eu considerei as seguintes opções:


  • endereço MAC, possível alteração, possível não exclusivo;
  • nome e domínio do computador (grupo de trabalho), alteração possível, não exclusiva (para grupo de trabalho);
  • o número de série do disco rígido em que o sistema operacional está instalado, os direitos de administrador são necessários durante a pesquisa WMI, não verifiquei a exclusividade, mas suspeito que não é possível;
  • o número de série da placa-mãe, não exclusivo, é possível e com bastante frequência;
  • o identificador do sistema de computador (propriedade UUID WMI da classe Win32_ComputerSystemProduct ), a não exclusividade é possível e com bastante frequência;
  • o tempo de instalação do sistema operacional é a melhor de todas as opções, mas a unicidade é possível ao clonar o sistema ou ao implantar a partir de uma imagem.

Nenhuma opção permite que você identifique exclusivamente o computador, então decidi identificá-lo de três maneiras:


  • número de série da placa mãe,
  • identificador do sistema de computador
  • tempo de instalação do sistema operacional.

Obviamente, esses três parâmetros podem coincidir em computadores diferentes, mas com menos frequência que um deles.


Também foi feita uma tentativa de obter usuários ativos usando a classe WMI padrão: Win32_LogonSession . Em seguida, o primeiro problema apareceu: o Win32_LogonSession mostra todas as sessões do usuário, mesmo aquelas que já foram concluídas. Comecei a pensar em como filtrar as sessões ativas daquelas que terminavam. Verificou que isso pode ser feito usando a classe Win32_SessionProcess , que associa instâncias das classes Win32_LogonSession ao Win32_Process . Se o link para a sessão estiver presente na lista de instâncias da classe Win32_SessionProcess (há pelo menos um processo com o identificador desta sessão), ele estará ativo. Em seguida, surgiu a pergunta sobre como associar uma sessão a um usuário. Isso pode ser feito usando a classe Win32_LoggedOnUser , que vincula instâncias das classes Win32_LogonSession e Win32_UserAccount . Resta apenas obter instâncias da classe Win32_UserAccount que fornecem informações detalhadas sobre o usuário.


imagem


Mas aqui fiquei desapontado. Ao usar o WMI remotamente, descobriu-se que, ao tentar obter instâncias da classe Win32_UserAccount , é possível obter apenas usuários de computadores locais. Ou seja, descobriu-se que, usando as ferramentas WMI padrão, é impossível descobrir quais usuários estão ativos no computador.


Desenvolvimento de um provedor WMI.


Devido à impossibilidade de identificação inequívoca de computadores e à impossibilidade de obter informações sobre usuários ativos usando classes WMI padrão, decidiu-se expandir a funcionalidade do WMI. Você pode fazer isso descrevendo suas classes WMI em um arquivo MOF e gravando um provedor WMI para obter instâncias dessas classes.


Duas novas classes WMI foram descritas: NMBY_InstallInfo - para identificar um computador e NMBY_LogonSession - para identificar usuários ativos de um computador.


imagem


Em seguida, um provedor WMI foi escrito com o qual você pode obter instâncias dessas classes.


Requisitos adicionais foram definidos para o provedor:


  • trabalhar em um sistema sem .NET;
  • trabalhar no sistema operacional Windows XP e superior;
  • a capacidade de obter informações usando uma conta não administrativa.

Portanto, o provedor foi gravado em C ++ usando o WinApi.


No processo de escrita do provedor, surgiram dificuldades devido à pequena quantidade e qualidade da documentação sobre esse tópico, mas, apesar disso, o fornecedor foi gravado com êxito.


Um provedor por escrito está disponível na página de download . Pode ser instalado e usado gratuitamente.


Sumário


Como resultado, usando o programa Network MACMonitor, tornou-se possível:


  • Associar usuários a computadores

imagem


  • Associar computadores a portas em dispositivos de rede

imagem


  • Associar portas de dispositivos de rede a computadores e usuários

imagem


  • Exibir o histórico de registro do usuário nos computadores.

imagem


Site do programa

Source: https://habr.com/ru/post/pt416217/


All Articles