Python Network Scanner

A varredura de portas pode ser definida como uma técnica de vigilância, que é usada para localizar as portas abertas disponíveis em um determinado host. O administrador de rede, o testador de penetração ou um hacker podem usar essa técnica. Podemos configurar o scanner de porta de acordo com nossos requisitos para obter o máximo de informações do sistema de destino.

Agora, considere as informações que podemos obter após executar a verificação de porta -

  • Informações sobre portas abertas.

  • Informações sobre os serviços em execução em cada porta.

  • Informações sobre o sistema operacional e o endereço MAC do host de destino.

A varredura de portas é como um ladrão que quer entrar em uma casa verificando todas as portas e janelas para ver quais estão abertas. Conforme discutido anteriormente, o conjunto de protocolos TCP / IP, usado para comunicação pela Internet, é composto de dois protocolos, a saber, TCP e UDP. Ambos os protocolos têm 0 a 65535 portas. Como é sempre aconselhável fechar portas desnecessárias do nosso sistema, portanto, essencialmente, existem mais de 65.000 portas (portas) para travar. Essas 65535 portas podem ser divididas nos três intervalos a seguir -

  • Portas do sistema ou conhecidas: de 0 a 1023

  • Portas do usuário ou registradas: de 1024 a 49151

  • Portas dinâmicas ou privadas: todas> 49151

Port Scanner usando Socket

Em nosso capítulo anterior, discutimos o que é um soquete. Agora, vamos construir um scanner de porta simples usando soquete. A seguir está um script Python para scanner de porta usando soquete -

from socket import *
import time
startTime = time.time()

if __name__ == '__main__':
   target = input('Enter the host to be scanned: ')
   t_IP = gethostbyname(target)
   print ('Starting scan on host: ', t_IP)
   
   for i in range(50, 500):
      s = socket(AF_INET, SOCK_STREAM)
      
      conn = s.connect_ex((t_IP, i))
      if(conn == 0) :
         print ('Port %d: OPEN' % (i,))
      s.close()
print('Time taken:', time.time() - startTime)

Quando executamos o script acima, ele solicitará o nome do host, você pode fornecer qualquer nome de host, como o nome de qualquer site, mas tome cuidado porque a varredura de portas pode ser vista ou interpretada como um crime. Nunca devemos executar um scanner de porta em qualquer site ou endereço IP sem permissão explícita por escrito do proprietário do servidor ou computador que você está almejando. A verificação de portas é semelhante a ir à casa de alguém e verificar suas portas e janelas. É por isso que é aconselhável usar o scanner de porta no host local ou no seu próprio site (se houver).

Resultado

O script acima gera a seguinte saída -

Enter the host to be scanned: localhost
Starting scan on host: 127.0.0.1
Port 135: OPEN
Port 445: OPEN
Time taken: 452.3990001678467

A saída mostra que no intervalo de 50 a 500 (conforme fornecido no script), este scanner de porta encontrou duas portas - porta 135 e 445, abertas. Podemos alterar esse intervalo e verificar outras portas.

Port Scanner usando ICMP (hosts ativos em uma rede)

ICMP não é uma varredura de porta, mas é usado para executar ping no host remoto para verificar se o host está ativo. Essa verificação é útil quando temos que verificar vários hosts ativos em uma rede. Envolve o envio de uma solicitação ICMP ECHO a um host e, se esse host estiver ativo, ele retornará uma resposta ICMP ECHO.

O processo acima de envio de solicitação ICMP também é chamado de varredura de ping, que é fornecido pelo comando ping do sistema operacional.

Conceito de Ping Sweep

Na verdade, em um ou outro sentido, a varredura de ping também é conhecida como varredura de ping. A única diferença é que a varredura de ping é o procedimento para encontrar a disponibilidade de mais de uma máquina em uma faixa de rede específica. Por exemplo, suponha que desejamos testar uma lista completa de endereços IP e, em seguida, usando o ping scan, ou seja, o comando ping do sistema operacional, seria muito demorado fazer a varredura dos endereços IP um por um. É por isso que precisamos usar o script de varredura de ping. A seguir está um script Python para encontrar hosts ativos usando a varredura de ping -

import os
import platform

from datetime import datetime
net = input("Enter the Network Address: ")
net1= net.split('.')
a = '.'

net2 = net1[0] + a + net1[1] + a + net1[2] + a
st1 = int(input("Enter the Starting Number: "))
en1 = int(input("Enter the Last Number: "))
en1 = en1 + 1
oper = platform.system()

if (oper == "Windows"):
   ping1 = "ping -n 1 "
elif (oper == "Linux"):
   ping1 = "ping -c 1 "
else :
   ping1 = "ping -c 1 "
t1 = datetime.now()
print ("Scanning in Progress:")

for ip in range(st1,en1):
   addr = net2 + str(ip)
   comm = ping1 + addr
   response = os.popen(comm)
   
   for line in response.readlines():
      if(line.count("TTL")):
         break
      if (line.count("TTL")):
         print (addr, "--> Live")
         
t2 = datetime.now()
total = t2 - t1
print ("Scanning completed in: ",total)

O script acima funciona em três partes. Primeiro, ele seleciona o intervalo de endereços IP para fazer o ping da varredura, dividindo-o em partes. Em seguida, usa-se a função, que seleciona o comando de varredura do ping de acordo com o sistema operacional e, por último, dá a resposta sobre o host e o tempo gasto para concluir o processo de varredura.

Resultado

O script acima gera a seguinte saída -

Enter the Network Address: 127.0.0.1
Enter the Starting Number: 1
Enter the Last Number: 100

Scanning in Progress:
Scanning completed in: 0:00:02.711155

A saída acima não está mostrando nenhuma porta ativa porque o firewall está ativado e as configurações de entrada ICMP também estão desabilitadas. Depois de alterar essas configurações, podemos obter a lista de portas ativas no intervalo de 1 a 100 fornecida na saída.

Scanner de porta usando varredura TCP

Para estabelecer uma conexão TCP, o host deve realizar um handshake de três vias. Siga estas etapas para realizar a ação -

Step 1 − Packet with SYN flag set

Nesta etapa, o sistema que está tentando iniciar uma conexão começa com um pacote que tem o sinalizador SYN definido.

Step 2 − Packet with SYN-ACK flag set

Nesta etapa, o sistema de destino retorna um pacote com conjuntos de sinalizadores SYN e ACK.

Step 3 − Packet with ACK flag set

Por fim, o sistema inicial retornará um pacote ao sistema de destino original com o sinalizador ACK definido.

No entanto, a questão que surge aqui é se podemos fazer a varredura de portas usando o método de solicitação e resposta de eco ICMP (varredura de varredura de ping), então por que precisamos da varredura de TCP? A principal razão por trás disso é que suponha que se desligarmos o recurso de resposta ICMP ECHO ou usar um firewall para pacotes ICMP, o scanner de varredura de ping não funcionará e precisamos de varredura TCP.

import socket
from datetime import datetime
net = input("Enter the IP address: ")
net1 = net.split('.')
a = '.'

net2 = net1[0] + a + net1[1] + a + net1[2] + a
st1 = int(input("Enter the Starting Number: "))
en1 = int(input("Enter the Last Number: "))
en1 = en1 + 1
t1 = datetime.now()

def scan(addr):
   s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
   socket.setdefaulttimeout(1)
   result = s.connect_ex((addr,135))
   if result == 0:
      return 1
   else :
      return 0

def run1():
   for ip in range(st1,en1):
      addr = net2 + str(ip)
      if (scan(addr)):
         print (addr , "is live")
         
run1()
t2 = datetime.now()
total = t2 - t1
print ("Scanning completed in: " , total)

O script acima funciona em três partes. Ele seleciona o intervalo de endereços IP para fazer o ping da varredura, dividindo-o em partes. Isso é seguido pelo uso de uma função para escanear o endereço, que usa ainda mais o soquete. Posteriormente, ele fornece a resposta sobre o host e o tempo gasto para concluir o processo de digitalização. O resultado = s. A instrução connect_ex ((addr, 135)) retorna um indicador de erro. O indicador de erro é 0 se a operação for bem-sucedida; caso contrário, é o valor da variável errno. Aqui, usamos a porta 135; este scanner funciona para o sistema Windows. Outra porta que funcionará aqui é a 445 (Microsoft-DSActive Directory) e normalmente está aberta.

Resultado

O script acima gera a seguinte saída -

Enter the IP address: 127.0.0.1
Enter the Starting Number: 1
Enter the Last Number: 10

127.0.0.1 is live
127.0.0.2 is live
127.0.0.3 is live
127.0.0.4 is live
127.0.0.5 is live
127.0.0.6 is live
127.0.0.7 is live
127.0.0.8 is live
127.0.0.9 is live
127.0.0.10 is live
Scanning completed in: 0:00:00.230025

Scanner de portas rosqueadas para aumentar a eficiência

Como vimos nos casos acima, a varredura de portas pode ser muito lenta. Por exemplo, você pode ver que o tempo gasto para escanear portas de 50 a 500, ao usar o scanner de porta de soquete, é 452.3990001678467. Para melhorar a velocidade, podemos usar threading. A seguir está um exemplo de scanner de porta usando threading -

import socket
import time
import threading

from queue import Queue
socket.setdefaulttimeout(0.25)
print_lock = threading.Lock()

target = input('Enter the host to be scanned: ')
t_IP = socket.gethostbyname(target)
print ('Starting scan on host: ', t_IP)

def portscan(port):
   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   try:
      con = s.connect((t_IP, port))
      with print_lock:
         print(port, 'is open')
      con.close()
   except:
      pass

def threader():
   while True:
      worker = q.get()
      portscan(worker)
      q.task_done()
      
q = Queue()
   startTime = time.time()
   
for x in range(100):
   t = threading.Thread(target = threader)
   t.daemon = True
   t.start()
   
for worker in range(1, 500):
   q.put(worker)
   
q.join()
print('Time taken:', time.time() - startTime)

No script acima, precisamos importar o módulo de threading, que está embutido no pacote Python. Estamos usando o conceito de bloqueio de thread,thread_lock = threading.Lock()para evitar várias modificações de uma vez. Basicamente, threading.Lock () permitirá que uma única thread acesse a variável por vez. Conseqüentemente, nenhuma modificação dupla ocorre.

Posteriormente, definimos uma função threader () que buscará o trabalho (porta) do trabalhador para o loop. Em seguida, o método portscan () é chamado para se conectar à porta e imprimir o resultado. O número da porta é passado como parâmetro. Assim que a tarefa for concluída, o método q.task_done () é chamado.

Agora, depois de executar o script acima, podemos ver a diferença na velocidade de digitalização de 50 a 500 portas. Demorou apenas 1.3589999675750732 segundos, que é muito menos do que 452.3990001678467, tempo gasto pelo scanner de porta de soquete para verificar o mesmo número de portas do host local.

Resultado

O script acima gera a seguinte saída -

Enter the host to be scanned: localhost
Starting scan on host: 127.0.0.1
135 is open
445 is open
Time taken: 1.3589999675750732