Varredura de PING Utilizando o Python

Uma varredura de PING, conhecida como varredura ICMP, é uma técnica muito utilizada na TI para o diagnóstico, determinando quais endereços IP estão em uso dentro de uma rede, sendo eles normalmente computadores ou servidores. Neste material, explico melhor o que é uma varredura de PING e disponibilizo um script em Python com essa finalidade.

[ Hits: 812 ]

Por: Diego Mendes Rodrigues em 09/11/2020 | Blog: https://www.linkedin.com/in/diegomendesrodrigues/


Introdução



Embora poucos saibam, a palavra PING originou-se da tecnologia do sonar. Esta é a maneira em que os submarinos trabalham para detectar corpos na água, sendo que, um pacote de som é enviado e, se houver um objeto no caminho, este pacote de som volta e costuma ser captado como um som de 'ping' quando recebido.

Na tecnologia de computadores da atualidade, o PING único é enviado usando uma solicitação de eco ICMP (Internet Control Message Protocol). Desta forma, pacote é enviado para um endereço IP específico e, se esse endereço estiver ativo, ele enviará uma notificação de volta, ou seja, um eco. As solicitações de PING também oferecem outras informações, como por exemplo, quanto tempo o sinal levou para voltar e se houve perda de pacotes. Existem também outras variedades de comandos que podem ser adicionados a uma solicitação de PING, para que também seja possível enviar muitas outras informações.
Linux: Varredura de PING utilizando o Python
Na imagem acima, realizei 03 requisições de PING para o IP 172.67.187.166 do domínio www.vivaolinux.com.br. Observe que não existiram perdas, ou seja, recebi as 3 respostas. O tempo mínimo entre o envio e o retorno foi de 202.321 ms, o máximo foi 220.583 ms, enquanto o médio foi 208.886 ms. Desta forma, fica claro que o IP 172.67.187.166 está ativo e respondendo na internet.

O que é uma varredura de PING

Uma varredura de PING, conhecida como varredura ICMP, é uma técnica muito utilizada na TI para o diagnóstico, determinando quais endereços IP estão em uso dentro de uma rede, sendo eles normalmente computadores ou servidores. Esta técnica costuma ser utilizada para dizer onde as máquinas ativas estão dentro de uma rede e, às muitas vezes, é utilizada por administradores de sistemas para diagnosticar um problema de rede.

As varreduras de PING também são usadas por usuários mal intencionados, que procuram entrar em determinadas redes empresariais, buscando quais servidores estão ativos e expostos na internet, para que eles consigam concentrar seus ataques em possíveis servidores vulneráveis.

Dentro de uma rede local, o administrador poderia separar os IPs da seguinte forma:
  • 192.168.0.0/24: servidores
  • 192.168.1.0/24: clientes

Com essa separação, os servidores estariam nos IPs 192.168.0.1, 192.168.0.2, 192.168.0.3 e assim por diante. Imagine que esse administrador possua 5 servidores em sua rede (192.168.0.1 até 192.168.0.5) e queira, a cada 3 minutos, verificar se todos estão ativos. Uma forma fácil seria realizar uma varredura de PING nesses 5 servidores a cada 3 minutos, sendo que, os servidores que não respondessem ao PING poderiam ser considerados como inativos.

No exemplo abaixo, exponho uma varredura de PING, sendo realizada nessa rede empresarial, onde todos os servidores responderam de maneira adequada.
Linux: Varredura de PING utilizando o Python
Já nesta próxima temos outra situação, onde os IPs 192.168.0.3 e 192.168.0.4 estão inativos ou indisponíveis, sendo que provavelmente estas máquinas estejam desligadas, ou com problemas em suas interfaces de rede. O ideal seria o administrador dessa rede receber um e-mail, ou uma mensagem no Telegram indicando essa falha.
Linux: Varredura de PING utilizando o Python
Agora podemos supor um usuário malicioso, buscando dentro da faixa de IPs da Amazon, quais estão expostos na internet e respondendo às requisições PING. Nesta imagem utilizei a faixa de IPs entre 65.8.213.8 e 65.8.213.12. Observe que o IP 65.8.213.9 está respondendo na internet.
Linux: Varredura de PING utilizando o Python
Neste exemplo malicioso acima, o usuário iniciaria seu ataque no IP 65.8.213.9, buscando as portas abertas nessa máquina, para descobrir quais serviços estão expostos.

Script em Python para uma varredura de PING

Criei um script em Python para realizar varreduras de PING, em faixas de rede, ou em hosts, utilizando seus endereços. Ele pode ser utilizado por administradores de sistemas em suas redes internas, ou para verificar se os sites hospedados externamente estão funcionado corretamente.

Ao executar a verificação na minha rede interna, utilizado:

verificar_rede('192.168.0.%d', 1, 254, True)

Obtive como resposta:

VERIFICAR A REDE 192.168.0.0/24
192.168.0.1 ativo
192.168.0.10 ativo
192.168.0.33 ativo
192.168.0.60 ativo


Ao testar em hosts externos, com:

hosts_para_verificar = ['www.debian.org',
'www.ubuntu.com',
'www.vivaolinux.com.br',
'urlerrada.io']
verificar_hosts(hosts_para_verificar, True)


Obtive como resposta:

VERIFICAR DIVERSOS HOSTS
Erro ao resolver o IP do host 'urlerrada.io': [Errno 11001] getaddrinfo failed
191.252.5.37 ativo
191.252.222.74 ativo
91.189.88.180 ativo
Linux: Varredura de PING utilizando o Python

Script Python

Segue abaixo o script Python, na versão 3.9:

"""
Script para realizar a verificação se IPs, ou Hosts, estão respondendo através do utilitário PING.
O ping é um utilitário que usa o protocolo ICMP para testar a conectividade entre equipamentos, sendo
ele um comando disponível praticamente em todos os sistemas operacionais atuais
-
Diego Mendes Rodrigues
"""
import socket
from subprocess import Popen, DEVNULL

def verificar_rede(ips_da_rede='192.168.0.%d', inicial=1, final=254, exibir_apenas_ativos=True):
    """Verificar uma rede/subrede
    :param ips_da_rede: IPs da rede, no formato '192.168.0.%d'
    :param inicial: Número inicial da rede/subrede, exemplo = 1
    :param final: Número final da rede/subrede, exemplo = 254
    :param exibir_apenas_ativos: True caso sejam impressos no terminal apenas os IPs ativos via PING
    :return: True caso os testes tenham sido realizados, False caso contrário
    """
    # Validação
    if len(ips_da_rede) <= 0 or inicial < 1 or final < 2 or final > 254 or not isinstance(exibir_apenas_ativos, bool):
        print('Todos os parâmetros devem ser informados de forma correta')
        return False

    # ip -> processo
    p = {}

    # Realizando a varredura
    for n in range(inicial, final + 1):
        ip = ips_da_rede % n
        p = Popen(['ping', '-n', '1', '-w', '5', ip], stdout=DEVNULL)

    return __verificar(p, exibir_apenas_ativos)

def verificar_hosts(hosts_verificados, exibir_apenas_ativos=True):
    """Verificar os hosts ao invés de IPs, sendo que os hosts serão convertidos para IPs
    :param hosts_verificados: Lista com os hosts que serão verificados, exemplo = ['www.debian.org', 'www.ubuntu.com']
    :param exibir_apenas_ativos: True caso sejam impressos no terminal apenas os IPs dos hosts ativos via PING
    :return: True caso os testes tenham sido realizados, False caso contrário
    """
    # Validação
    if len(hosts_verificados) <= 0 or not isinstance(exibir_apenas_ativos, bool):
        print('Todos os parâmetros devem ser informados de forma correta')
        return False

    ips =
    for host in hosts_verificados:
        try:
            ip_do_host = socket.gethostbyname(host)
            ips.append(ip_do_host)
        except Exception as e:
            ips.append(f'Erro ao resolver o IP do host &#92;'{host}&#92;': {e}')
            pass

    # ip -> processo
    p = {}

    for ip in ips:
        if ip != 'Erro':
            p = Popen(['ping', '-n', '1', '-w', '5', ip], stdout=DEVNULL)
        else:
            print(f'{ip}')

    return __verificar(p, exibir_apenas_ativos)

def __verificar(p_itens, exibir_apenas_ativos=True):
    """Função Interna que realiza a verificação dos IPs utilizando o PING
    :param p_itens: Itens que serão verificados
    :param exibir_apenas_ativos: exibir_apenas_ativos: True caso sejam impressos no terminal apenas os IPs ativos
    :return: True caso os testes tenham sido realizados, False caso contrário
    """
    # Validação
    if len(p_itens) <= 0 or not isinstance(exibir_apenas_ativos, bool):
        print('Todos os parâmetros devem ser informados de forma correta')
        return False

    while p_itens:
        for ip, proc in p_itens.items():
            if proc.poll() is not None:
                del p_itens
                if proc.returncode == 0:
                    print('%s ativo' % ip)
                elif proc.returncode == 1:
                    if not exibir_apenas_ativos:
                        print('%s sem resposta' % ip)
                else:
                    print('%s erro' % ip)
                break
    return True

def main():
    """Função principal da aplicação que realiza a verificação dos IPs/Hosts utilizando o PING
    """
    # Verificar a rede 192.168.0.0/24
    print('VERIFICAR A REDE 192.168.0.0/24')
    if not verificar_rede('192.168.0.%d', 1, 254, True):
        print('Falha ao verificar a rede 192.168.0.0/24')

    # Verificar diversos hosts
    print('&#92;nVERIFICAR DIVERSOS HOSTS')
    hosts_para_verificar = ['www.debian.org',
                            'www.ubuntu.com',
                            'www.vivaolinux.com.br',
                            'urlerrada.io']
    if not verificar_hosts(hosts_para_verificar, True):
        print('Falha ao verificar os hosts')

if __name__ == "__main__":
    """Execução automática pelo terminal
    """
    main()
 

Conclusão

Você utiliza esse tipo de varredura em sua rede?

Caso positivo, utiliza uma ferramenta pronta ou criou um script (Python, Go, Bash, etc)?

   

Páginas do artigo
   1. Introdução
Outros artigos deste autor

Instalando Adicionais para Convidados para VirtualBox no Debian, Linux Mint e Ubuntu

Principais novidades do Linux Mint 20 Ulyana

Pop!_OS Linux - Uma boa distribuição baseada no Ubuntu

Bloqueio de usuários com o chroot

Linuxfx OS - Distribuição para quem deseja o visual do Windows 10

Leitura recomendada

RapidScan - Multi-Tool WEB Vulnerability Scanner

Python + ADB

Introdução ao clib (Command Line Book)

Interagindo com servidores HTTP com Python

Python - Threads

  
Comentários
[1] Comentário enviado por mauricio123 em 10/11/2020 - 12:35h


Legal esse Script.

___________________________________________________________
[code]Conhecimento não se Leva para o Túmulo.
https://github.com/MauricioFerrari-NovaTrento [/code]

[2] Comentário enviado por cytron em 20/11/2020 - 15:23h

Muito bom isso. E pra eu que gosto de Python, é melhor ainda.
Dá pra evoluir isso aí e fazer muitas peripécias kkk

Existe também uma forma alternativa para essa varredura. O nmap, basta usar o parâmetro -sP .... exemplo:

nmap -sP 10.0.0.5-200

Isso vai retornar todos os hosts ativos (configurados para responder) que usam IP com final de 5 até 200. O nmap aceita expressões até complexas no parâmetro de IP.

[3] Comentário enviado por ElmiroDuarte em 22/11/2020 - 17:05h

Muito bacana, show, conteúdo muito bom.

[4] Comentário enviado por mauricio123 em 27/11/2020 - 22:26h


[2] Comentário enviado por cytron em 20/11/2020 - 15:23h

Muito bom isso. E pra eu que gosto de Python, é melhor ainda.
Dá pra evoluir isso aí e fazer muitas peripécias kkk

Existe também uma forma alternativa para essa varredura. O nmap, basta usar o parâmetro -sP .... exemplo:

nmap -sP 10.0.0.5-200

Isso vai retornar todos os hosts ativos (configurados para responder) que usam IP com final de 5 até 200. O nmap aceita expressões até complexas no parâmetro de IP.


boa.


Contribuir com comentário