Verificador automático para encontrar hosts ativos com Python

Você gostaria de ver quais IPs estão ativos em uma rede? Gostaria de saber como é executado um programa deste estilo? Bem, hoje eu te mostro como fazer um programa em python 3 que varrerá a rede em uma variedade de IPs que o usuário fornece.

Para esta tarefa, vamos automatizar o ping do sistema operacional.

Opção 1 - Scanner simples


Eu coloquei essa primeira opção, porque é mais fácil de entender e realizar, antes de entrar em algo mais complicado.

O programa completo é o seguinte:

 import os import sys import plataforma de datetime import datetime ip = input ("Digite o IP:") dividido ip = ip.split ('.') try: vermelho = dividido ip [0] + '.' + dividido ip [1 ] + '.' + ipDivided [2] + '.' start = int (input ("Digite o número inicial da sub-rede:")) end = int (input ("Digite o número onde você deseja terminar a varredura:")) exceto: print ("[!] Erro") sys.exit (1) if (platform.system () == "Windows"): ping = "ping -n 1" else: ping = "ping -c 1" starttime = datetime.now () print ("[* ] A varredura está sendo feita de ", vermelho + str (início)," para ", vermelho + str (fim)) para a sub-rede no intervalo (início, fim + 1): endereço = vermelho + str (sub-rede) resposta = os .popen (ping + "" + endereço) para a linha em response.readlines (): if ("ttl" em line.lower ()): print (endereço, "está ativo") break endtime = datetime.now () time = endTime - startTime print ("[*] A verificação durou% s"% tempo) 
[color = # a9a9a9] Código completo [/ color]

Passo 1
Precisamos importar algumas bibliotecas, para nosso programa:

 import os import sys import platform from datetime import datetime
[color = # a9a9a9] Bibliotecas [/ color]

Explicação das bibliotecas

  • vocês: Precisamos fazer ping por meio do sistema operacional.
  • sys: Eu o utilizo para encerrar o programa devido a um erro na entrada do usuário.
  • plataforma: Permite-nos conhecer o sistema operativo onde rodamos o programa, a sua utilização torna-nos independentes de plataforma.
  • data hora: Eu uso para saber o tempo que leva para fazer a varredura, se você não quiser saber, você pode salvá-lo.

Passo 2
No código a seguir, pedimos ao usuário os dados necessários, como o host e o intervalo da sub-rede. También tenemos un bloque try, catch que lo uso básicamente para terminar el programa de una manera controlada, si la IP que inserta el usuario no es correcta la primera instrucción del bloque dará error, y si al pedirle el comienzo y fin no inserta números saltará um erro.

 ip = entrada ("Digite o IP:") ip dividido = ip.split ('.') try: rede = ip dividido [0] + '.' + ip dividido [1] + '.' + ip dividido [2 ] + '.' start = int (input ("Digite o número inicial da sub-rede:")) end = int (input ("Digite o número onde você deseja terminar a varredura:")) exceto: print ("[!] Erro") sys.exit (1)
Eu uso a primeira instrução no bloco try para criar um prefixo de rede, que será útil mais tarde.

Por exemplo, na imagem a seguir com os dados que insiro, faríamos uma varredura para ver se os endereços de 192.168.0.190 a 192.168.0.199 estão ativos.

etapa 3
Na próxima parte do código, a única coisa que verifico é qual sistema operacional está sendo usado por meio da função platform.system ().

 if (platform.system () == "Windows"): ping = "ping -n 1" else: ping = "ping -c 1"
Isso é necessário porque queremos enviar um único pacote, e no Windows a instrução é feita com -n e no unix com -c.

Passo 4
Em seguida, analisarei o seguinte snippet de código:

 starttime = datetime.now () print ("[*] A verificação está sendo executada de", red + str (start), "to", red + str (end)) para a sub-rede no intervalo (início, fim + 1) : endereço = rede + str (sub-rede) resposta = os.popen (ping + "" + endereço) para a linha em response.readlines (): if ("ttl" em line.lower ()): print (endereço, "é active ") break endtime = datetime.now () time = endtime - starttime print (" [*] A verificação durou% s "% time)
Esta etapa é onde realizamos a verdadeira funcionalidade, portanto, antes de começar, obtenho o tempo correspondente:
 starttime = datetime.now ()
E nós pintamos uma linha por tela para que o usuário saiba que a varredura está sendo feita (e o intervalo):
 print ("[*] A digitalização está sendo feita de", vermelho + str (início), "para", vermelho + str (final))
Então vemos um for, que percorrerá a faixa de endereços IP desejados, sua primeira instrução concatena os números que faltam ao prefixo da rede, ou seja, se tivermos 192.168.0. então, se o loop for for de 190 para 199, a primeira vez que você inserir o endereço, ele será 192.168.0.190 e, à medida que avança, o 190 será alterado, o resto nós mantemos. Em seguida, obtemos a resposta do ping, que é realizada pela instrução:
 os.popen (ping + "" + endereço)
Para saber se o IP está ativo, verificaremos se a resposta que temos contém a palavra ttl, Eu uso line.lower () porque parece que no Linux sai em minúsculas e no Windows em maiúsculas, então não temos problemas.

Na parte final, tudo que faço é pegar o tempo novamente, e eu descanso esse novo tempo com o anterior para pintar o tempo que levou para o meu programa.

A seguir mostro uma imagem da execução do programa, como podemos ver que é um tanto lento (52 segundos para 19 endereços), também depende da potência do PC, mas desta vez pode ser melhorado se usarmos threads, então agora Vou fazer o programa usando os "threads do Python".

Opção 2 - Scanner Threaded Python


Agora vamos iniciar um programa semelhante, mas algo mais complexo, pois agora o trabalho será dividido entre vários threads e não ficará apenas uma carga, no final veremos que o tempo é bastante reduzido, então podemos dizer que é uma versão mais ideal.

O programa é o seguinte:

 import os import sys import platform import threading, subprocesso from datetime import datetime IPXHILOS = 4 ip = input ("Digite o IP:") dividido ip = ip.split ('.') try: vermelho = ip dividido [0] + ' . '+ IP dividido [1] +'. '+ IP dividido [2] +'. ' start = int (input ("Digite o número inicial da sub-rede:")) end = int (input ("Digite o número onde você deseja terminar a varredura:")) exceto: print ("[!] Erro") sys.exit (1) if (platform.system () == "Windows"): ping = "ping -n 1" else: ping = "ping -c 1" class Thread (threading.Thread): def __init __ ( self, start, end): threading.Thread .__ init __ (self) self.start = start self.fin = end def run (self): para sub-rede no intervalo (self.start, self.fin): endereço = rede + str (sub-rede) resposta = os.popen (ping + "" + endereço) para a linha em response.readlines (): if ("ttl" em line.lower ()): print (endereço, "está ativo") break startTime = datetime .now () print ("[*] A verificação está sendo executada de", rede + str (início), "para", rede + str (fim)) NumberIPs = fim-início numberThreads = int ((NumberIPs / IPXHILOS)) threads = [] try: for i in range (numberThreads): endAux = start + IPXTHREADS if (endAux> end): endAux = end thread = Thread (início, endAux) thread.start () threads.append ( thread) começando = finAux exceto Exceptio n so e: print ("[!] Erro ao criar threads:", e) sys.exit (2) para thread em threads: thread.join () endtime = datetime.now () time = endtime - starttime print ("[ *] A verificação demorou% s "% tempo) 
[color = # a9a9a9] Programa completo [/ color]

Aqui vou falar sobre instruções que mudam e são adicionadas (vou ignorar as partes iguais ao programa anterior):

As importações que usamos no programa anterior são válidas para nós, só precisamos adicionar o seguinte, que será usado para os threads do Python.

 importar threading, subprocesso
Eu uso uma variável para o número de IPs que desejo que cada thread verifique, então ela é adicionada no início do programa:
 IPXTHREADS = 4
A solicitação de dados do usuário e a verificação do sistema operacional permanecem intactas. Neste show Eu crio uma classe chamada Thread que se estende de threading., essa classe recebe como parâmetros o início e o fim dos endereços com os quais cada thread terá que trabalhar, então eu tenho uma função run, que é necessária e tem que ser chamada assim, ela cuidará de fazer o trabalho quando a gente inicie o tópico mais tarde, o for não muda:
 class Thread (threading.Thread): def __init __ (self, start, end): threading.Thread .__ init __ (self) self.start = start self.fin = end def run (self): para sub-rede no intervalo ( self.start, self.fin): endereço = rede + str (sub-rede) resposta = os.popen (ping + "" + endereço) para a linha em response.readlines (): if ("ttl" em line.lower () ): impressão (endereço, "está ativo") quebra
Agora vamos explicar a parte que tenho fora da aula Fio.

Utilizo a seguinte instrução para saber a quantidade de IPs que tenho no total, de acordo com o início e o fim que o usuário me passa:

 NumberIPs = end-start
Agora que sabemos disso, podemos calcular o número de threads que vou precisar para trabalhar:
 numberThreads = int ((NumberIPs / IPXTHREADS))
Vou precisar de uma lista onde armazenar cada thread, para que mais tarde eu possa fazer o thread principal aguardar a conclusão do trabalho:
 threads = []
O fragmento de código a seguir irá criar as threads e passar a elas sua seção de trabalho, para isso temos que “brincar” com o início e o final de cada thread, por isso criei a variável finAux. Uma vez que o tópico é criado, ele começa com começar () e é adicionado à lista de tópicos.
 try: for i in range (numberThreads): endAux = start + IPXTHREADS if (endAux> end): endAux = end thread = Thread (início, endAux) thread.start () threads.append (thread) start = endAux exceto Exceção como e: print ("[!] Erro ao criar tópicos:", e) sys.exit (2)
Em seguida, crio um loop cujo objetivo é esperar que os threads terminem
 para discussão em tópicos: thread.join () 
E por último, o tempo é levado, seria subtraído do que eu tirei antes de começar e é mostrado na tela, assim como no programa anterior.

Se fizermos o mesmo teste de antes com este programa, veremos que leva 6 segundos para fazer o mesmo trabalho, que diferença.

ObservaçãoO tempo pode variar dependendo da potência do seu PC e da variável IPXHILOS, eu atribuo um 4, se você atribuir mais trabalho a cada thread vai demorar mais, se tiver menos trabalho será mais rápido, mas tome cuidado para que haja é um limite para o número de threads que podemos criar.

Podemos confiar que este programa nos fornece 100% dos hosts ativos?A resposta é não, já que você pode bloquear o ping em um host bloqueando solicitações e / ou respostas ICMP, o que você pode ter certeza é que se ele disser que está ativo, está. Existem outros tipos de scanner, como o TCP, que você pode fazer com as portas que um sistema operacional normalmente deixa abertas, e a combinação dos scanners TCP e ping será mais confiável.

Deixo-vos um código postal com os 2 códigos:

codigos_ping_python.zip 1,38K 270 downloads

Gostou e ajudou este tutorial?Você pode recompensar o autor pressionando este botão para dar a ele um ponto positivo
wave wave wave wave wave