Verifica portas abertas usando sockets.

Contexto

O TCP Port Scanner é utilizado para identificar quais serviços estão "ouvindo" em um host alvo. Após descobrir que um host está ativo (via Ping Sweep, por exemplo), o Pentester precisa saber quais portas estão abertas (como 22 para SSH, 80 para HTTP ou 443 para HTTPS).

Este módulo utiliza o protocolo TCP para tentar estabelecer uma conexão. Se a conexão for aceita, a porta é marcada como "Aberta", revelando uma possível entrada para análise de vulnerabilidades.

Possibilidades de Implementação

  • TCP Connect Scan: O método mais comum, que completa o three-way handshake (SYN, SYN-ACK, ACK). É fácil de programar com a biblioteca nativa socket.
  • Scanner Multi-threaded: Como escanear portas sequencialmente é lento, a implementação de threads permite testar centenas de portas simultaneamente.
  • Escaneamento por Range: O módulo pode ser configurado para varrer portas específicas (conhecidas) ou um intervalo completo (1-65535).

Código

Este código utiliza a biblioteca nativa socket e a estrutura concurrent.futures para garantir alta performance através de multiprocessamento leve (threads).

import socket
from concurrent.futures import ThreadPoolExecutor

# Configurações do Módulo
ALVO = "scanme.nmap.org"  # Host de teste permitido
TIMEOUT = 1.0             # Tempo de espera por resposta (segundos)
THREADS = 50              # Número de conexões simultâneas

def scan_port(ip, port):
    """
    Tenta estabelecer uma conexão TCP com o IP e porta especificados.
    """
    # Cria o objeto socket: AF_INET (IPv4) e SOCK_STREAM (TCP)
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(TIMEOUT)

    try:
        # connect_ex retorna 0 para sucesso (porta aberta)
        result = sock.connect_ex((ip, port))
        if result == 0:
            print(f"[+] Porta {port:5} [ABERTA]")
        sock.close()
    except Exception:
        pass

def main():
    print("-" * 60)
    print(f"Módulo: TCP Port Scanner | Projeto: 30 Lessons in Python")
    print("-" * 60)

    try:
        target_ip = socket.gethostbyname(ALVO)
        print(f"[*] Escaneando: {ALVO} ({target_ip})")
        print(f"[*] Utilizando {THREADS} threads...\n")

        # Lista de portas mais comuns para o exemplo
        common_ports = [21, 22, 23, 25, 53, 80, 110, 135, 139, 443, 445, 3306, 3389, 8080]

        # Execução paralela para otimização de tempo
        with ThreadPoolExecutor(max_workers=THREADS) as executor:
            for port in common_ports:
                executor.submit(scan_port, target_ip, port)

    except socket.gaierror:
        print("[!] Erro: Não foi possível resolver o domínio alvo.")
    except KeyboardInterrupt:
        print("\n[!] Escaneamento interrompido pelo usuário.")

    print("\n[*] Varredura finalizada.")

if __name__ == "__main__":
    main()

Observações

  • Handshake Completo: Este scanner é "barulhento" em termos de logs, pois estabelece a conexão completa, sendo facilmente detectado por Firewalls ou IDSs (Sistemas de Detecção de Intrusão).
  • Performance vs Precisão: Um TIMEOUT muito baixo aumenta a velocidade, mas pode gerar falsos negativos em redes instáveis ou lentas.
  • Socket connect_ex: Diferente do connect(), esta função retorna um código de erro em vez de lançar uma exceção, o que torna o código mais limpo e eficiente para escaneamentos em massa.