10 de febrero de 2012

Python script: BssidFromPcap.py paso a paso

En este post quiero explicar paso a paso como crear un script en Python que nos guarde en un archivo de texto las direcciones MAC de los APs disponibles en un archivo de captura PCAP. En este enlace puedes encontrar una pequeña explicación del mismo así como el código fuente del script final.

Versión 0.0

Dado que vamos a utilizar Scapy para manipular los paquetes de red, en primer lugar deberemos importar todos los métodos que ésta libreria nos permite.
from scapy.all import *
Creamos el objeto outfile, con el que creamos y abrimos el archivo de salida para los datos.
outfile = open('./Out.lst', 'w')
Especificamos el archivo de captura, en este caso hardcodeado, y creamos un nuevo objeto (capture) con el método rdpcap para leer el archivo de captura.
capfile = '../out-01.cap' # Change this!
capture = rdpcap(capfile)
Python es un lenguaje altamente secuencial, por lo que un simple for nor permite iterar fácilmente entre los distintos paquetes que contiene nuestro objeto capture.
for pcks in caputre:
   [...]
Hay que tener muy encuenta la identación, tabulaciónes, pues es un factor clave dentro del lenguaje y nos delimita las clases, funciones, estructuras de control, etc. dentro de nuestro código.

En una primera versión, vamos a registrar todas las direcciones físicas de los paquetes capturados en un nuevo objeto llamado bssid.
bssid = pcks.addr2
Realizamos un filtro para direcciones nulas, 00:00:00:00:00:00, a través del objeto blank para pasar a la siguiente iteración.
blank = '00:' * 5 + '00'
if bssid == blank:
    continue
En caso contrario, escribimos la MAC en el archivo de salida, outfile.
outfile.write(bssid + "\n")
Para finalizar, cerramos el archivo de salida.
outfile.close()
El código de esta primera versión sería:
#!/usr/bin/env python

from scapy.all import *

outfile = open('./Out.lst', 'w')
capfile = '../out-01.cap' # Change this!
capture = rdpcap(capfile)
blank = '00:' * 5 + '00'

for pcks in capture:

  bssid = pcks.addr2
  
  if bssid == blank:
    continue
  else:
    outfile.write(bssid + "\n")

outfile.close()
Y una primera prueba del mismo


Versión 0.1

Para mejorar el código anterior, vamos a eliminar los resultados repetidos. Para ello utilizamos un nuevo array, unique, con el que comprobar la existencia del objeto bssid. En caso incorrecto, añadimos dicho valor al array y lo escribimos al archivo de salida.
else:
  unique = []
  if unique.count(bssid) == 0:
    unique.append(bssid)
Si utilizamos el mismo archivo de captura obtenemos el siguiente resultado


Versión 0.2

Una mejora indispensable, es que podamos elegir el archivo de captura a analizar. Para ello deberemos importar el módulo sys que nos permite usar el método argv para acceder a los argumentos del script.
import sys

capfile = sys.argv[1]
Para finalizar, únicamente vamos a analizar los paquetes beacon frame exitentes en los archivos de captura y en caso contrario pasaremos al siguiente paquete.
if pcks.haslayer(Dot11Beacon):
  [...]
else:
  continue
El código final, sin comentar, es el siguiente. Para una versión completa del mismo, visita el siguiente enlace.
import sys
from scapy.all import *

outfile = open('./Out.lst', 'w')
capfile = sys.argv[1]
capture = rdpcap(capfile)
blank = '00:' * 5 + '00'
unique = []

for pcks in capture:

  if pcks.haslayer(Dot11Beacon):
    bssid = pcks.addr2
  
    if bssid == blank:
      continue
    else:
      if unique.count(bssid) == 0:
        unique.append(bssid)
        outfile.write(bssid + "\n")

  else:
    continue

outfile.close()
Realizando algunas pruebas

Utilizando el mismo archivo de captura, obtenemos el siguiente resultado.


Con otro archivo de captura


Si realizamos una captura de varios APs y lanzamos el script al archivo de captura, podemos comprobar que genera una lista con BSSIDs únicos presentes en la red.


Un saludo, Brixton Cat ; )

No hay comentarios:

Publicar un comentario

Bienvenid= si quieres dejar un comentario