24 de enero de 2012

Python Script: Obteniendo BSSIDs de un archivo pcap

Buenas a tod@s! Se que tengo varias series por terminar, como configurar el servidor MySQL y el CMS Drupal para nuestro cluster web de alta disponibilidad o la instalación de la red VoIP utilizando Cisco Call Manager Express de nuestra simulación de una red corporativa. Pero en el primer caso haciendo pruebas me carge la configuración de DRBD y en el segundo caso tengo que tomar las capturas para escribirlo. Todo a su tiempo, todo a su tiempo...

De todas maneras, no solo de administración podemos vivir y la programación es una tarea fundamental para cualquier geek/freak/nerd/hacker/hack0r, o como mejor querais llamaros... Aprovechando que hace poco he terminado el curso Introduction to PenTest Scripting impartido por Roberto Martinez, gran maestro y persona, que ha montado un programa de cursos de lo más interesante utilizando webinars para crear clases virtuales a través de Internet y una posible futura aula virtal donde se añadirá la modalidad E-learning.

http://commons.wikimedia.org/
Volviendo con la entrada... El script nos va a generar un archivo lista con BSSIDs únicos presentes en un archivo de captura PCAP que le pasaremos como argumento. Voy a hacer uso del modulo Scapy para Python que se incluye en la instalación de BackTrack 5, pero si es necesario añadirlo a vuestras librerias lo podeis encontrar en la Web del desarrollo.

En esta entrada voy a resumir los pasos fundamentales del script y las pruebas realizadas, podeis encontrar el código completo en la siguiente entrada (BssidFromPcap.py) y una descripción del proceso de creación para los novatos como yo (aqui).

Explicación

En primer lugar declaramos algunas variables y objetos que serán utilizados a lo largo del script, en este paso especificamos el archivo de captura y de salida al igual que los abrimos para asociarlos a sus respectivos objetos.
# Open output file
outfile = open('./Out.lst', 'w')
# Obtain pcap capture file from first arguments
capfile = sys.argv[1]
# Open pcap capture file with scapy
capture = rdpcap(capfile)
# Filter for blank MAC address: 00:00:00:00:00:00
blank = '00:' * 5 + '00'
# Blank array for unique bssids
unique = []
Recorremos el archivo de captura para comprobar que el paquete se trata de un  Beacon Frame (Dot11Beacon) del que obtenemos la dirección física origen, BSSID, y comprobamos que no es un valor nulo: 00:00:00:00:00:00.
# Read pcap capture file
for pcks in capture:

  # If pcks is Dot11 (802.11) package
  if pcks.haslayer(Dot11Beacon):
    # Obtain MAC address from package
    bssid = pcks.addr2
  
    # If bssid is blank go to next iteration
    if bssid == blank:
      continue
La explicación que he encontrado sobre esta dirección (1)(2)(3), es que se utiliza como dirección destino en algunos ARP Request y en paquetes ARP Gratuitous, pero en las capturas aparecen valores nulos como origen de algunos paquetes. En los paquetes Beacon no he encontrado ninguno pero manteniendo el filtro nos aseguramos que se obvien en caso que se cuele alguno.


Si no existe el BSSID en el array unique, se añade a la lista y se escribe en el archivo de salida. En caso que el condicional sea falso, no guardará el BSSID en el array ni en el archivo de salida asegurando así que no se repiten resultados.
    # Check if exist bssid in unique array and append it
    else:
      if unique.count(bssid) == 0:
        unique.append(bssid)
        # Write bssid in outfile
        outfile.write(bssid + "\n")
Para finalizar cerramos el archivo de salida antes de salir del script.
# Close output file
outfile.close()
Pruebas

Auditando una red

Este es el archivo con el que estuve realizando la creación del script, corresponde con una captura realizada con airodump-ng sobre un AP específico en el que hay conectado un cliente. En entradas posteriores intentaré detallar la creación del script donde se entenderá mejor.


Auditando varias redes

Este otro caso, correponde con una captura realizada también con airodump-ng pero sin filtrar por una red concreta. Obtendremos múltiples direcciones MAC que serán filtradas para evitar duplicados en el archivo de salida. Igualmente, en la explicación detallada se verá más en detalle este proceso y el resultado.


Comentario final

Ya para finalizar, solo quiero decir que el script ya estaba inventado... Para crearlo me he basado en información de blogs y páginas de Internet (4)(5) y únicamente lo he ordenado a mi manera así como he personalizado las variables y nombres de los objetos.

La realización del script me ha resultado francamente simple dada la posibilidad que nos brinda Scapy para utilizar su nomenclatura y métodos, que junto a la facilidad de escriptura de Python nos permite crear herramientas complejas y altamente potentes. Sobra decir que esto solo es un pequeño programa que puede ser utilizado en un script más complejo o con más opciones a través de funciones, clases, etc.

En los enlaces anteriores podeis encontrar explicaciones en las que me he basado así como ejemplos y métodos de Python que podemos aplicar en nuestros desarrollos. Yo tengo alguna que otra idea en mente, aunque solo sea por enreadar y aprender el lenguaje...

Enlaces de referencia

1 - http://wiki.wireshark.org/Gratuitous_ARP
2 - http://cauew.blogspot.com/2008/08/arp-rarp-proxy-arp-gratuitous-arp-and.html
3 - http://www.certforums.co.uk/forums/networks/43139-help-wireshark-newbie.html
4 - http://www.packetstan.com/2011/03/extracting-ap-names-from-packet.html
5 - http://www.devx.com/security/Article/34741/1954

Un saludo, Brixton Cat.

No hay comentarios:

Publicar un comentario

Bienvenid= si quieres dejar un comentario