Introdução
O Scapy é um poderoso programa e biblioteca interativa de manipulação de pacotes escrito em Python. Ele permite que você forje ou decodifique pacotes de uma ampla gama de protocolos, envie-os pela rede, capture-os e combine solicitações com respostas.
O que torna o Scapy especial é que ele permite trabalhar na camada de construção de pacotes, em vez de apenas na camada de socket ou de aplicação. Isso significa que você pode controlar explicitamente cabeçalhos, flags, campos e combinações de protocolos de uma maneira que as bibliotecas de cliente comuns geralmente ocultam.
Neste laboratório, você aprenderá o básico da criação de pacotes usando o Scapy. Você começará importando os módulos necessários e, em seguida, passará a forjar pacotes ICMP (ping) e TCP camada por camada. Por fim, você enviará esses pacotes personalizados e analisará as respostas da rede. Essa experiência prática lhe dará uma compreensão mais profunda de como os protocolos de rede funcionam "por baixo do capô" e como os profissionais de segurança testam as defesas de rede.
Importar Módulos do Scapy
Nesta etapa, você configurará seu ambiente Python e importará os módulos necessários do Scapy. Embora o Scapy possa ser usado como um console interativo, escrever scripts permite salvar, modificar e reutilizar sua lógica de criação de pacotes facilmente.
Esta é uma mudança de paradigma: em vez de apenas pedir a uma aplicação existente que envie tráfego para você, você mesmo está definindo como esse tráfego deve ser.
Primeiro, certifique-se de estar no seu diretório de trabalho padrão. Você pode usar o comando pwd para verificar, mas você já deve estar em ~/project.
Crie um novo arquivo Python chamado packet_crafter.py usando o editor de texto nano.
nano packet_crafter.py
Dentro deste arquivo, você precisa importar a biblioteca Scapy. A maneira padrão de usar o Scapy em scripts é importar todas as funções do módulo scapy.all. Adicione as seguintes linhas ao seu script:
from scapy.all import *
print("Scapy modules imported successfully.")
Salve o arquivo com Ctrl+O e Enter. Se você quiser continuar construindo o script antes de testá-lo, pode permanecer no nano. Use Ctrl+X quando estiver pronto para retornar ao terminal.
Agora, execute seu script usando Python para garantir que não haja erros de sintaxe e que a biblioteca Scapy seja carregada corretamente. Como a criação de pacotes de rede brutos requer privilégios elevados, você deve executar o script com sudo.
sudo python3 packet_crafter.py
Você deverá ver uma saída semelhante à seguinte, indicando sucesso:
Scapy modules imported successfully.
Em alguns ambientes de laboratório, o Scapy pode imprimir um aviso adicional de pacotes Python opcionais, como o matplotlib, antes da mensagem de sucesso. Se você ainda vir Scapy modules imported successfully., pode prosseguir para a próxima etapa.
Forjar uma Solicitação de Eco ICMP
Nesta etapa, você forjará um pacote de Solicitação de Eco ICMP (ICMP Echo Request), comumente conhecido como "ping". Os pacotes de rede são construídos em camadas, seguindo o modelo OSI. No Scapy, você pode empilhar essas camadas usando o operador /.
A estratificação é um dos conceitos mais importantes a absorver aqui. Cada camada adiciona seus próprios campos e responsabilidades. O Scapy reflete esse modelo diretamente, e é por isso que sua sintaxe torna a estrutura do pacote mais fácil de entender.
Um ping ICMP requer uma camada IP (camada de rede) para especificar os endereços de origem e destino, e uma camada ICMP para definir o tipo de mensagem.
Se o packet_crafter.py ainda estiver aberto no nano, continue editando-o. Caso contrário, reabra-o:
nano packet_crafter.py
Acrescente o seguinte código ao final do seu script. Este código cria um objeto IP direcionado ao servidor DNS público do Google (8.8.8.8), cria um objeto ICMP e os empilha. O método show() imprimirá um detalhamento da estrutura do pacote.
## Create an IP layer targeting Google's DNS
ip_layer = IP(dst="8.8.8.8")
## Create an ICMP layer (Echo Request)
icmp_layer = ICMP()
## Stack the layers to form the final packet
icmp_packet = ip_layer / icmp_layer
print("\n--- ICMP Packet Structure ---")
icmp_packet.show()
Salve o arquivo com Ctrl+O e Enter. Você pode permanecer no nano e continuar para a próxima etapa se quiser terminar mais partes do script antes de executá-lo.
Execute seu script atualizado para visualizar a estrutura do pacote que você acabou de forjar.
sudo python3 packet_crafter.py
Você verá uma saída detalhada mostrando os valores padrão que o Scapy preencheu automaticamente para você, como a versão do protocolo, TTL (Time To Live) e o tipo de ICMP.
--- ICMP Packet Structure ---
###[ IP ]###
version = 4
ihl = None
tos = 0x0
len = None
id = 1
flags =
frag = 0
ttl = 64
proto = icmp
chksum = None
src = 10.0.2.15
dst = 8.8.8.8
\options \
###[ ICMP ]###
type = echo-request
code = 0
chksum = None
id = 0x0
seq = 0x0
unused = ''
Criar um Pacote TCP SYN Personalizado
Nesta etapa, você criará um pacote TCP SYN. Esse tipo específico de pacote é frequentemente usado em varreduras de rede (como a varredura furtiva do Nmap) para verificar se uma porta específica está aberta em uma máquina de destino sem estabelecer uma conexão completa.
Este é um bom exemplo de como pequenas alterações no cabeçalho produzem comportamentos de rede muito diferentes. Você não está alterando o host ou a porta de destino, apenas as flags e os campos de protocolo, mas esses detalhes definem o significado do pacote e como o destino o interpretará.
Semelhante ao pacote ICMP, um pacote TCP requer uma camada IP subjacente. Sobre ela, você adicionará uma camada TCP onde poderá especificar a porta de destino e as flags TCP. A flag S significa SYN (Synchronize).
Se você ainda estiver na mesma sessão do nano, continue editando o packet_crafter.py. Caso contrário, reabra-o:
nano packet_crafter.py
Acrescente o seguinte código ao seu script. Reutilizaremos o ip_layer criado na etapa anterior e empilharemos uma nova camada TCP sobre ele, direcionada à porta 80 (HTTP).
## Create a TCP layer targeting port 80 with the SYN flag
tcp_layer = TCP(dport=80, flags="S")
## Stack the IP and TCP layers
tcp_packet = ip_layer / tcp_layer
print("\n--- TCP SYN Packet Structure ---")
tcp_packet.show()
Salve o arquivo com Ctrl+O e Enter. Saia com Ctrl+X apenas quando quiser executar o script a partir do terminal, ou continue editando para a etapa final.
Execute o script novamente para inspecionar a estrutura do seu novo pacote TCP SYN.
sudo python3 packet_crafter.py
A saída agora incluirá os detalhes da camada TCP, mostrando a porta de destino definida como http (porta 80) e as flags definidas como S.
--- TCP SYN Packet Structure ---
###[ IP ]###
version = 4
ihl = None
tos = 0x0
len = None
id = 1
flags =
frag = 0
ttl = 64
proto = tcp
chksum = None
src = 10.0.2.15
dst = 8.8.8.8
\options \
###[ TCP ]###
sport = ftp_data
dport = http
seq = 0
ack = 0
dataofs = None
reserved = 0
flags = S
window = 8192
chksum = None
urgptr = 0
options = []
Enviar e Analisar a Resposta da Rede
Nesta etapa final, você enviará o pacote ICMP que forjou pela rede e capturará a resposta.
O envio do pacote completa o modelo mental: definir camadas, construir o pacote, transmitir e, em seguida, interpretar a resposta. Esse é o mesmo ciclo de alto nível por trás de muitas ferramentas personalizadas de teste de rede.
O Scapy fornece várias funções para enviar pacotes. A função sr1() é particularmente útil porque envia um pacote e aguarda a primeira resposta recebida. O "s" significa send (enviar), "r" significa receive (receber) e "1" significa um pacote.
Se você manteve o arquivo aberto, continue editando-o. Caso contrário, reabra o packet_crafter.py:
nano packet_crafter.py
Acrescente o seguinte código para enviar o icmp_packet e analisar a resposta. Incluímos um parâmetro timeout para que o script não fique travado indefinidamente caso o pacote seja descartado ou bloqueado.
print("\n--- Sending ICMP Packet ---")
## Send the packet and wait for 1 response, with a timeout of 2 seconds
## verbose=0 hides the default Scapy sending output for cleaner results
response = sr1(icmp_packet, timeout=2, verbose=0)
if response:
print(f"Response received from: {response[IP].src}")
print("\n--- Response Packet Structure ---")
response.show()
else:
print("No response received. The packet might have been dropped.")
Salve o arquivo e saia do editor.
Execute seu script para enviar o pacote para a internet e aguardar a resposta do servidor DNS do Google.
sudo python3 packet_crafter.py
Se a rede permitir a solicitação ICMP, você verá a estrutura do pacote de resposta. Observe que o tipo de ICMP na resposta é echo-reply.
--- Sending ICMP Packet ---
Response received from: 8.8.8.8
--- Response Packet Structure ---
###[ IP ]###
version = 4
ihl = 5
tos = 0x0
len = 28
id = 0
flags =
frag = 0
ttl = 114
proto = icmp
chksum = 0x67d8
src = 8.8.8.8
dst = 10.0.2.15
\options \
###[ ICMP ]###
type = echo-reply
code = 0
chksum = 0xffff
id = 0x0
seq = 0x0
unused = ''
###[ Padding ]###
load = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
Resumo
Você aprendeu a configurar um script Python com Scapy, forjar manualmente pacotes ICMP e TCP camada por camada usando o operador / e enviar esses pacotes pela rede para analisar as respostas brutas. Esse conhecimento fundamental é crucial para entender como os protocolos de rede operam, realizar avaliações de segurança e desenvolver ferramentas personalizadas de análise de rede.



