Criando um Port Scan com Python3
Introdução No artigo de hoje, vamos desenvolver um Port Scan utilizando Python 3, mas, antes de mais nada, é fundamental compreender o que é um port scan e como ele funciona. Entendendo um Port Scan O que é um port scan? Basicamente, trata-se de um programa que envia pacotes de dados para uma determinada porta em um ativo específico. O port scan opera na camada de transporte do protocolo TCP. Ele envia um pacote com a flag SYN para uma porta no servidor e, caso o servidor responda com SYN-ACK, entende-se que a porta está aberta. Se o retorno for uma flag RST, a porta está fechada. Outra resposta possível é o ICMP Destination Unreachable, que indica que a porta está filtrada, ou seja, acessível apenas internamente ou por redes autorizadas. Existem duas abordagens comuns para se realizar um port scan: TCP — baseado em conexão (three-way handshake) UDP — sem garantia de entrega dos pacotes Veja a representação visual abaixo: TCP — baseado em conexão (3-way handshake) UDP — Não garante a entrega Veja abaixo isso de forma mais visual: [Você] --------- SYN ----------> [Servidor Porta 80] [Você] [Servidor Porta 80] (Fecha conexão) Agora que compreendemos melhor o funcionamento do port scan, vamos ao nosso código. Para facilitar o entendimento, o código será apresentado em blocos e, ao final, será exibido de forma completa. Nosso Port Scan import socket import sys from datetime import datetime from colorama import init, Fore init(autoreset=True) Este primeiro bloco importa as bibliotecas necessárias e inicializa o Colorama, que permite o uso de cores no terminal. def scan_port(ip, port): try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(0.5) result = sock.connect_ex((ip, port)) sock.close() if result == 0: print(Fore.GREEN + f"[+] Porta {port} aberta") else: print(Fore.RED + f"[-] Porta {port} fechada") except Exception as e: print(Fore.RED + f"[!] Erro ao escanear a porta {port}: {e}") Esta é nossa primeira função, chamada scan_port. Ela recebe como parâmetros o IP e a porta. O objetivo é tentar uma conexão com a porta especificada no host, retornando se ela está aberta ou fechada. Na função, é criado um socket para realizar a conexão. O bloco try é utilizado para tratamento de exceções, retornando uma mensagem de erro caso a verificação falhe. def main(): print("-" * 50) print("Port Scanner Básico") print("-" * 50) target = input("Digite o IP ou domínio a ser escaneado: ") ports_input = input("Digite as portas separadas por vírgula (ou pressione ENTER para todas as portas): ") if ports_input.strip() == "": ports = range(1, 65536) # Escaneia todas as portas else: try: ports = [int(port.strip()) for port in ports_input.split(",")] except ValueError: print(Fore.RED + "[!] Formato inválido de porta(s). Use apenas números separados por vírgula.") sys.exit(1) print(f"\nIniciando o scan em {target}...\n") start_time = datetime.now() Esta função representa o ponto de entrada principal da aplicação. Ela exibe um banner no terminal e solicita ao usuário que informe o alvo (target), podendo ser um endereço IP ou domínio. Também solicita que o usuário insira as portas a serem escaneadas, separadas por vírgula. Caso nenhuma porta seja informada, o código executará a varredura em todas as 65535 portas TCP. As entradas do usuário são convertidas para inteiros. Se houver algum valor inválido, uma mensagem de erro é exibida e a execução é encerrada com sys.exit(1). # Faz o scan em cada porta for port in ports: scan_port(target, port) end_time = datetime.now() total_time = end_time - start_time print("\nScan finalizado!") print(f"Tempo total: {total_time}") if __name__ == "__main__": main() Por fim, o laço for percorre cada porta informada, invocando a função scan_port para realizar a tentativa de conexão. Ao final do processo, o tempo total de execução do scan é exibido. As saídas do script são coloridas: verde para portas abertas e vermelho para portas fechadas ou erros.

Introdução
No artigo de hoje, vamos desenvolver um Port Scan utilizando Python 3, mas, antes de mais nada, é fundamental compreender o que é um port scan e como ele funciona.
Entendendo um Port Scan
O que é um port scan?
Basicamente, trata-se de um programa que envia pacotes de dados para uma determinada porta em um ativo específico. O port scan opera na camada de transporte do protocolo TCP. Ele envia um pacote com a flag SYN para uma porta no servidor e, caso o servidor responda com SYN-ACK, entende-se que a porta está aberta.
Se o retorno for uma flag RST, a porta está fechada. Outra resposta possível é o ICMP Destination Unreachable, que indica que a porta está filtrada, ou seja, acessível apenas internamente ou por redes autorizadas.
Existem duas abordagens comuns para se realizar um port scan:
TCP — baseado em conexão (three-way handshake)
UDP — sem garantia de entrega dos pacotes
Veja a representação visual abaixo:
- TCP — baseado em conexão (3-way handshake)
- UDP — Não garante a entrega Veja abaixo isso de forma mais visual:
[Você] --------- SYN ----------> [Servidor Porta 80]
[Você] <------ SYN-ACK ---------- [Servidor Porta 80] (Porta aberta!)
[Você] -------- RST ------------> [Servidor Porta 80] (Fecha conexão)
Agora que compreendemos melhor o funcionamento do port scan, vamos ao nosso código. Para facilitar o entendimento, o código será apresentado em blocos e, ao final, será exibido de forma completa.
Nosso Port Scan
import socket
import sys
from datetime import datetime
from colorama import init, Fore
init(autoreset=True)
Este primeiro bloco importa as bibliotecas necessárias e inicializa o Colorama, que permite o uso de cores no terminal.
def scan_port(ip, port):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(0.5)
result = sock.connect_ex((ip, port))
sock.close()
if result == 0:
print(Fore.GREEN + f"[+] Porta {port} aberta")
else:
print(Fore.RED + f"[-] Porta {port} fechada")
except Exception as e:
print(Fore.RED + f"[!] Erro ao escanear a porta {port}: {e}")
Esta é nossa primeira função, chamada scan_port
. Ela recebe como parâmetros o IP e a porta. O objetivo é tentar uma conexão com a porta especificada no host, retornando se ela está aberta ou fechada.
Na função, é criado um socket
para realizar a conexão. O bloco try
é utilizado para tratamento de exceções, retornando uma mensagem de erro caso a verificação falhe.
def main():
print("-" * 50)
print("Port Scanner Básico")
print("-" * 50)
target = input("Digite o IP ou domínio a ser escaneado: ")
ports_input = input("Digite as portas separadas por vírgula (ou pressione ENTER para todas as portas): ")
if ports_input.strip() == "":
ports = range(1, 65536) # Escaneia todas as portas
else:
try:
ports = [int(port.strip()) for port in ports_input.split(",")]
except ValueError:
print(Fore.RED + "[!] Formato inválido de porta(s). Use apenas números separados por vírgula.")
sys.exit(1)
print(f"\nIniciando o scan em {target}...\n")
start_time = datetime.now()
Esta função representa o ponto de entrada principal da aplicação. Ela exibe um banner no terminal e solicita ao usuário que informe o alvo (target), podendo ser um endereço IP ou domínio.
Também solicita que o usuário insira as portas a serem escaneadas, separadas por vírgula. Caso nenhuma porta seja informada, o código executará a varredura em todas as 65535 portas TCP.
As entradas do usuário são convertidas para inteiros. Se houver algum valor inválido, uma mensagem de erro é exibida e a execução é encerrada com sys.exit(1)
.
# Faz o scan em cada porta
for port in ports:
scan_port(target, port)
end_time = datetime.now()
total_time = end_time - start_time
print("\nScan finalizado!")
print(f"Tempo total: {total_time}")
if __name__ == "__main__":
main()
Por fim, o laço for
percorre cada porta informada, invocando a função scan_port
para realizar a tentativa de conexão.
Ao final do processo, o tempo total de execução do scan é exibido.
As saídas do script são coloridas: verde para portas abertas e vermelho para portas fechadas ou erros.