Neste tutorial scapy - parte 3, iremos começar a entender como utilizar a ferramenta Scapy, analisar suas principais funcionalidades e nos aventurar no modo interativo.

Scapy - Modo Interativo

O Scapy pode ser executado em dois modos diferentes, interativamente a partir de uma janela de terminal e como um módulo a partir de um script Python.

Vamos começar a nos familiarizar com o Scapy usando o modo interativo.

Para que o Scapy possa realizar algumas tarefas como envio e recebimento de pacotes na rede, é preciso executá-lo como usuário root.

Importante lembrarmos que instalamos o Scapy dentro do ambiente (tutorial-scapy), portanto para iniciar a ferramenta precisaremos ir até este ambiente virtual.

thepacketwizards@ubuntu:~$ sudo ./PythonEnviroments/tutorial-scapy/bin/scapy
Scapy no modo interativo
Scapy no modo interativo

Comandos Básicos

Para obtermos a lista de comandos básicos do Scapy, basta utilizarmos a função lsc(), conforme abaixo:

>>> lsc()
...
bind_layers         : Bind 2 layers on some specific fields' values
bridge_and_sniff    : Forward traffic between interfaces if1 and if2, sniff and return
hexdump             :  Build a tcpdump like hexadecimal view
ls                  : List  available layers, or infos on a given layer class or name
rdpcap              : Read a pcap or pcapng file and return a packet list
report_ports        : portscan a target and output a LaTeX table
send                : Send packets at layer 3
sendp               : Send packets at layer 2
sendpfast           : Send packets at layer 2 using tcpreplay for performance
sniff               : 
split_layers        : Split 2 layers previously bound
sr                  : Send and receive packets at layer 3
sr1                 : Send packets at layer 3 and return only the first answer
sr1flood            : Flood and receive packets at layer 3 and return only the first answer
srbt                : send and receive using a bluetooth socket
srbt1               : send and receive 1 packet using a bluetooth socket
srflood             : Flood and receive packets at layer 3
srloop              : Send a packet at layer 3 in loop and print the answer each time
srp                 : Send and receive packets at layer 2
srp1                : Send and receive packets at layer 2 and return only the first answer
srp1flood           : Flood and receive packets at layer 2 and return only the first answer
srpflood            : Flood and receive packets at layer 2
srploop             : Send a packet at layer 2 in loop and print the answer each time
tcpdump             : Run tcpdump or tshark on a list of packets
traceroute          : Instant TCP traceroute
traceroute6         : Instant TCP traceroute using IPv6
wrpcap              : Write a list of packets to a pcap file
...
>>>
Nota: Eu trunquei esta lista, e tentei deixar apenas as funções que mais iremos utilizar durante o tutorial.

É uma incrível lista de comandos! Vamos pelo menos apresentar a maioria desses comandos, e há alguns que usaremos extensivamente. Para os próximos tópicos, abordaremos especificamente: ls (), send (), sniff (), sr*() e wrpcap().

Na verdade, vamos em frente e usar um desses agora para mostrar alguns dos incríveis recursos internos do Scapy! Vamos utilizar a função sniff() para capturar um único pacote em nossa rede e depois vamos analisar o pacote que coletamos.

Utilizando a função sniff()

A função sniff traz diversas funcionalidades interessantes, e podemos descobri-las utilizando a função help.

>>> help(sniff)

Neste primeiro uso, quero coletar um pacote ICMP(), o famoso ping, e mostrar cada camada dele. Para isso, utilizaremos os seguintes parâmetros:

  • [count]: número de pacotes que serão capturados, este valor será igual à 1, pois queremos capturar apenas um pacote
  • [prn]: uma função para ser aplicada em cada pacote, este parâmetro receberá o valor Packet.show, pois queremos ver cada camada do pacote assim que ele for capturado.
  • [filter]: um filtro BPF, este parâmetro receberá o valor "icmp", pois queremos capturar um pacote do tipo ICMP
>>> sniff(1, filter='icmp', prn=Packet.show)

###[ Ethernet ]### 
  dst= 00:01:28:28:a7:a4
  src= 00:56:56:c1:00:08
  type= 0x800
###[ IP ]### 
     version= 4
     ihl= 5
     tos= 0x0
     len= 60
     id= 21652
     flags= 
     frag= 0
     ttl= 128
     proto= icmp
     chksum= 0x1e56
     src= 192.168.163.1
     dst= 192.168.163.132
     \options  
###[ ICMP ]### 
        type= echo-request
        code= 0
        chksum= 0x4d4a
        id= 0x1
        seq= 0x11
###[ Raw ]### 
           load= 'abcdefghijklmnopqrstuvwabcdefghi'

<Sniffed: TCP:0 UDP:0 ICMP:1 Other:0>

Uau, olha que incrível! Conseguimos capturar um pacote ICMP e imprimir na tela todas as camadas deste pacote com seus respectivos campos.

Vamos olhar a camada ###[ IP ]### para vermos cada informação que o Scapy nos traz.

###[ IP ]### 
     version= 4
     ihl= 5
     tos= 0x0
     len= 60
     id= 21652
     flags= 
     frag= 0
     ttl= 128
     proto= icmp
     chksum= 0x1e56
     src= 192.168.163.1
     dst= 192.168.163.132
     \options  

Conseguimos saber a versão do protoclo IP, que neste caso é a versão 4 (IPv4), também sabemos que o TTL é 128, o protocolo de camada superior é o ICMP e ainda temos a informação de IP de origem e destino deste pacote.

É como olharmos para um pacote no Wireshark, a diferença é que temos todo o poder de manipulação que o Scapy nos proporciona!

Mas espere, como o Scapy sabe que este pacote contém camadas Ethernet, IP e ICMP?

Pois bem, o Scapy tem uma ampla gama de suporte a protocolos. A lista é muito longa para eu imprimir aqui, portanto deixarei que você execute este próximo comando sozinho.

Utilizando a função ls()

No modo interativo do Scapy, execute o comando ls() e observe todos os protocolos suportados.

>>> ls()
AH         : AH
ARP        : ARP
ASN1P_INTEGER : None
ASN1P_OID  : None
ASN1P_PRIVSEQ : None
ASN1_Packet : None
...

Utilizamos a função ls() para ver a lista de protocolos suportados pelo Scapy. Se utilizarmos a função ls(), e passarmos como argumento um protocolo específico, como o IP, também poderemos ter a descrição de cada campo contido neste protocolo.

>>> ls(IP)
version    : BitField (4 bits)                   = (4)
ihl        : BitField (4 bits)                   = (None)
tos        : XByteField                          = (0)
len        : ShortField                          = (None)
id         : ShortField                          = (1)
flags      : FlagsField (3 bits)                 = (<Flag 0 ()>)
frag       : BitField (13 bits)                  = (0)
ttl        : ByteField                           = (64)
proto      : ByteEnumField                       = (0)
chksum     : XShortField                         = (None)
src        : SourceIPField                       = (None)
dst        : DestIPField                         = (None)
options    : PacketListField                     = ([])

Agora que já temos uma boa noção de como o modo interativo do Scapy funciona, que tal aprendermos à ler e acessar os parâmetros de cada camada dos pacotes?