martes, 5 de julio de 2011

Análisis forense de capturas de red

Para entretenerme un rato se me ocurrió ponerme con el último de los puzzles publicados en la web de SANS y hete que el entretenimiento me ha tenido liado varios dias e incluso algunas noches; como diría mi mujer - si es que tienes unos gustos mas raros.

Sirva como introducción el texto del contest: tenemos al muy malo rodeado de muchos policías, pero con la imperiosa necesidad de comunicarse con otros malos. Como este malo es un tío listo detecta un punto de acceso vecino ideal para sus propósitos. Mientras tanto, el admin de la red donde se ubica este AP empieza a notar que la cosa no va fina y decide obtener una captura del tráfico. Y ahora llegamos nosotros, los buenos, con la tarea de contestar una serie de preguntas partiendo de la captura obtenida por el admin.

En un principio pensé que lo mejor era no complicarme mucho e intentar resolverlo utilizando herramientas ampliamente probadas y de calidad contrastada. Dadas las características del reto la elección era obvia.

Seguro que todos conocemos al famoso Wireshark, network protocol analyzer o sniffer de los de toda la vida. Pues resulta que entre las utilísismas herramientas que incluye la suite nos encontramos al pequeño tshark. Básicamente permite la misma funcionalidad que su hermano mayor pero desde la shell, lo que lo hace idóneo para experimentar junto con otros comandos de linux utilizando pipes y demas artillería.

También se puede utilizar Wireshark en Windows, y por ende tshark, pero dado que la línea de comandos está un poco más limitada en cuanto a funcionalidad y todavía no sé absolutamente nada de PowerShell (que todo se andará) personalmente me he decantado por Linux.

Otra de las suites que he empleado ha sido aircrack-ng, que para el trabajo que le tenía destinado también hubiera podido ejecutarla en Windows. En este caso se trata de la caja de herramientas imprescindible para auditar redes inalámbricas o por el mero hecho de aprender un poco el funcionamiento interno de las mismas (recomiendo un vistazo al código fuente de los binarios y librerías, altamente instructivo aunque, ciertamente, hay que echarle un par de huevos).

Una vez decididas las herramientas y preparado el entorno ya podemos empezar.

Se abre el telón

Descargamos y comprobamos la integridad, que no la confiabilidad, del fichero de captura, utilizando para ello la suma Sha256 proporcionada:

$ wget -q http://forensicscontest.com/contest08/evidence08.pcap
$ echo "969f82205739e4d912f7a4bddf3d22f591bfa8fa09c9690c88117d7477263b8b *evidence08.pcap" \
| sha256sum -c
evidence08.pcap: La suma coincide

La primera pregunta, ¿cual es el SSID y el BSSID de la red inalámbrica vulnerada?

Para resolverla los frames más interesantes son los beacons o balizas. Se trata de un tipo especial de paquetes de administración enviados de forma regular por el AP a la dirección de broadcast para advertir de su presencia, publicando a diestro y siniestro el SSID. Esto, traducido a un comando tshark quedaría:
$ tshark -r evidence08.pcap -R 'wlan.fc.type_subtype eq 8' -T fields -e wlan_mgt.ssid
Ment0rNet

Por ser el primero lo analizaremos en profundidad. Primero el flag -r con el fichero de captura seguido de -R y el filtro que limitará los paquetes de entrada analizados, siendo en este caso los beacons frames encontrados. Para formatear la salida utilizamos el flag -T fields, de forma que sólo se mostrarán los campos indicados por el flag -e seguido del campo adecuado (pueden incluirse varios pares "-e campo"). Sirva como referencia para los campos disponibles el siguiente enlace:

WireShark Display Filter Reference

Y ahora vamos a por el BSSID, utilizando en este caso una doble condición (ya conocemos el SSID que nos interesa) para filtrar los paquetes de entrada:
$ tshark -r evidence08.pcap -R 'wlan.fc.type_subtype eq 8 and wlan_mgt.ssid eq "Ment0rNet"' \
-T fields -e wlan.bssid
00:23:69:61:00:d0

Pero, ¿que pasa cuando el SSID esta oculto (cloaked)? En este caso el AP se configura para que no envíe beacons a la dirección de broadcast, de forma que para que un cliente pueda asociarse deberá conocer el SSID de antemano. Para tratar de descubrirlo utilizaremos los frames Probe Response emitidos por el AP en respuesta a frames Probe Request y que, básicamente, contienen la misma información que los beacons:
$ tshark -r evidence08.pcap -R 'wlan.fc.type_subtype eq 5' -T fields -e wlan_mgt.ssid | uniq
Ment0rNet

La tubería y el comando uniq son necesarios dado que, si no, se mostraría el SSID tantas veces como frames Probe Response contiene la captura (una bonita forma de llenar el buffer de la consola).

Siguiente pregunta: ¿cual es la dirección en segundos de la captura? Para responderla vamos a utilizar dos comandos anidados. Primero obtendremos el numero total de frames que contiene el fichero de captura:
$ tshark -r evidence08.pcap -T fields -e frame.number | tail -1
133068

Ahora obtendremos el valor de tiempo relativo con respecto al primer frame que estará almacenado, elemental querido Watson, en el último frame, cuyo número ya hemos obtenido mediante la consulta anterior. Es más facil verlo que decirlo así que, si lo juntamos todo y lo aderezamos con bash:
$ tshark -r evidence08.pcap -R "frame.number eq $(tshark -r evidence08.pcap \
-T fields -e frame.number | tail -1)" -T fields -e frame.time_relative
413.576954000

Pero dado que la pregunta solicita un número "redondo" de segundos canalizaremos la salida y la maquillaremos utilizando awk:
$ tshark -r evidence08.pcap -R "frame.number eq $(tshark -r evidence08.pcap -T fields \
-e frame.number | tail -1)" -T fields -e frame.time_relative | awk '{printf("%d\n",$1 + 0.5)}'
414

Y ahora que conocemos la forma "difícil" veamos la forma "fácil" de obtener el mismo resultado. El comando capinfos, también contenido en la suite de wireshark, permite obtener información para el fichero pcap de captura que se le pase como argumento. Es más, utilizando el flag -u nos mostrará únicamente la duración en un número "redondo" de segundos; ya podía haberlo probado antes:
$ capinfos -u evidence08.pcap
File name: evidence08.pcap
Capture duration: 414 seconds

Sinceramente, me gusta más la forma "difícil", y aquí tengo que agradecer la inestimable supervisión de mi particular profesor de linux/regexp/awk/python mi compañero Hilario, haciendo que los comandos queden un poco más presentables. ¡Gracias monstruo!

Con las manos en la masa

Aunque no en éste orden otra de las cuestiones planteadas en el contest es la de obtener la clave WEP utilizada por el AP para cifrar las comunicaciones; aquí la herramienta a utilizar es obvia:
$ aircrack-ng -e Ment0rNet -q -b 00:23:69:61:00:d0 evidence08.pcap
KEY FOUND! [ D0:E5:9E:B9:04 ]
Decrypted correctly: 100%

Los parametros son el ESSID, "-e Ment0rNet", el BSSID, "-b 00:23:69:61:00:d0", el flag -q para que no muestre el progreso y sí el resultado y el fichero de captura utilizado como entrada.

Con esta información y utilizando otra de las herramientas de aircrack-ng descifraremos todos los paquetes WEP contenidos en el fichero de captura y volcaremos el resultado en otro fichero que utilizaremos más adelante:
$ airdecap-ng -w D0E59EB904 evidence08.pcap
Total number of packets read 133068
Total number of WEP data packets 56692
Total number of WPA data packets 0
Number of plaintext data packets 0
Number of decrypted WEP packets 56692
Number of corrupted WEP packets 0
Number of decrypted WPA packets 0

Como resultado obtendremos un nuevo fichero, evidence08-dec.pcap, totalmente descifrado.

En este caso el uso airdecap-ng es de inestimable ayuda ya que con el contenido del sumario de su ejecución podemos contestar otra pregunta, ¿número total de frames cifrados mediante WEP contenidos en el fichero de captura? 56692. Sin embargo, wireshark tambien puede descifrar, y por ende mostrar, todos los paquetes, funcionalidad ésta que, personalmente, no conocía. Para ello a traves del menú Edit de la GUI de Wireshark, Preferences y seleccionando IEE802.11 dentro de la sección Protocols podemos indicar la clave WEP utilizada para el cifrado:


Seguimos adelante y nos toca ahora obtener el número total de IVs que aparecen en la captura, sin contar las veces que estos aparecen repetidos. Primero el comando y luego lo comentamos:
$ tshark -r evidence08.pcap -R 'wlan.fc.protected eq 1' -T fields -e wlan.wep.iv

En este caso utilizamos como filtro el flag protected de los frames IEE802.11 que se asigna a todos los paquetes cifrados, aunque no necesariamente con WEP y mostramos el IV contenido; vale, sirve, pero ahora tenemos que filtrar la salida para obtener sólo lo que buscamos.

El comando de Linux que a priori mejor nos servirá es uniq, pero resulta que para que funcione correctamente las líneas repetidas deben ser consecutivas, por lo que antes tendremos que ordenarlas para, en último lugar, contarlas:
$ tshark -r evidence08.pcap -R 'wlan.fc.protected eq 1' -T fields -e wlan.wep.iv | sort | uniq | wc -l
29719

Puff, demasiadas tuberías, ¿y si utilizáramos awk?
$ tshark -r evidence08.pcap -R 'wlan.fc.protected eq 1' -T fields -e wlan.wep.iv \
| awk '!($0 in a) {a[$0];print}' | wc -l
29719

Más largo pero más compacto :)

Podemos comprobar que el resultado es correcto haciendo uso de otra de las herramientas contenidas en la suite de aircrack-ng, ivstools. Éste comando extrae los IVs de un fichero de captura y juntarlos con otros IVs de otro/s fichero/s de captura permitiendo de esta forma obtener los IVs necesarios para crackear una clave WEP en varias sesiones de sniffing. El comando:
$ ivstools --convert evidence08.pcap evidence08.ivs

Opening evidence08.pcap
Creating evidence08.ivs
Read 133068 packets.
Written 29719 IVs.

Solo un poco de teoria

En el proceso de cracking del cifrado WEP el IV o vector de inicialización es basico: contra mas IVs más probabilidades de obtener la clave. No voy a entrar en detalle acerca de WEP ya que no dispongo de los conocimientos necesarios, así que recomiendo el Taller WiFi publicado en los foros de Wadalbertia por el gran Vic_Thor, que ese sí que sabe de lo que habla. Quedémonos con que, para crackear WEP necesitamos muchos IVs.

Si tenemos en cuenta que todos los paquetes cifrados con WEP contienen un IV único el truco está en capturar muchos IVs diferentes; lo malo es que la mayoría de las veces el tráfico no es todo lo denso que quisiéramos por lo que tendríamos que esperar y esperar hasta obtener el número necesario. Esto sería así si no existiera el ataque conocido como "ARP replay injection" el cual permite acelerar enormemente el proceso.

Resulta que WEP permite reutilizar un mismo IV tantas veces como se quiera así que podemos capturar un paquete de datos y reinyectarlo un número indefinido de veces sin que el paquete sea descartado. Pero claro, si el paquete reinyectado no requiere una respuesta conteniendo un nuevo IV el proceso no servirá de nada.

Así que necesitamos reinyectar un paquete de datos que provoque algún tipo de respuesta por alguno de los dispositivos conectados a la red de forma que incrementemos rápidamente el número de IVs únicos capturados; y el mejor candidato para ello es una solicitud ARP la cual provocará la emisión de una respuesta ARP. Éste ataque está implementado, entre otros, en la suite aircrack mediante el comando aireplay-ng y un flag específico. Básicamente el proceso de cracking WEP constaria de los siguientes pasos:

Lanzar un proceso de captura de tramas IEE802.11 en el canal adecuado y dejarlo a la escucha:
$ airodump-ng -c [CANAL] --bssid [BSSID] -w [FICHERO PCAP] [INTERFAZ]

Asociarnos a la red ya que si no todos los paquetes seran descartados:
$ aireplay-ng -e [SSID] -a [BSSID] -h [MAC FALSA] -1 0 [INTERFAZ]

Si el comando anterior devolvió "Authentication successful" comenzar con la reinyección de paquetes:
$ aireplay-ng -e [SSID] -a [BSSID] -h [MAC FALSA] -3 [INTERFAZ]

Y por último lanzar el proceso de cracking en tiempo real:
$ aircrack-ng -b [BSSID] [FICHERO PCAP]

Como consecuencia, y en el caso de que estuvieramos analizando el tráfico de nuestra WLAN detectaríamos gran cantidad de paquetes con IVs repetidos lo que indicaría casi con total seguridad que estamos siendo victimas de un ataque de reinyección de solicitudes ARP.

¿Y a que viene todo esto? Pues sólo es una introducción para resolver la siguiente pregunta, ¿cual es la MAC del dispostivo que está ejecutando un ataque de capa 2? Y esta es la forma de resolverla que se me ocurrió.

Primero obtengo un fichero con todos los IVs contenidos en la captura:
$ tshark -r evidence08.pcap -R 'wlan.fc.protected eq 1' -T fields -e wlan.wep.iv > ivs

Ahora me curro un script con python que obtenga el número de veces que aparece repetido cada uno de los IVs únicos y sólo muestre aquellos que se repiten digamos ... al menos 100 veces:
$ cat << EOF >> repeatedIVs.py
> #! /usr/bin/python
>
> ivs = [line.strip() for line in open("ivs")]
>
> d = {}
> for x in ivs: d[x] = x
> uniqueIVs = d.values()
>
> for element in uniqueIVs:
> c = ivs.count(element)
> if c >= 100:
> print element
>
> EOF

Y lo ejecuto, redirigiendo la salida a un nuevo fichero:
$ python repeatedIVs.py > countIVs

El script es un poco lento, pero funciona. Si ahora utilizamos cualquiera de los IVs que aparecen en countIVs para obtener la MAC origen contenida en el frame en el que aparezca:
$ tshark -r evidence08.pcap -T fields -e wlan.sa 'wlan.wep.iv eq 0x1591fd' \
| awk '!($0 in a) {a[$0];print}'
1c:4b:d6:69:cd:07

De hecho si analizamos los paquetes generados por dicha dirección MAC utilizando como origen la captura pcap descifrada anteriomente comprobaremos como se trata de paquetes de tipo ARP:
$ tshark -r evidence08-dec.pcap -R 'eth.addr eq 1c:4b:d6:69:cd:07' -T fields -e eth.type \
| awk '!($0 in a) {a[$0];print}'
0x0806

Podemos consultar el siguiente enlace para confirmar que el opcode anterior se corresponde con el protocolo ARP. Ahora averiguaremos si se trata de respuestas o peticiones (nuevamente nos será muy útil el enlace anterior):
$ tshark -r evidence08-dec.pcap -R 'eth.addr eq 1c:4b:d6:69:cd:07' -T fields -e arp.opcode \
| awk '!($0 in a) {a[$0];print}'
0x0001

Continuamos: ¿cuantos IVs únicos han sido generados por la estación atacante?
$ tshark -R 'wlan.sa eq 1c:4b:d6:69:cd:07 && wlan.fc.protected eq 1 && wlan.bssid \
eq 00:23:69:61:00:d0' -r evidence08.pcap -T fields -e wlan.wep.iv \
| awk '!($0 in a) {a[$0];print}' | wc -l
14133

¿y por el resto de estaciones combinadas?
$ tshark -R 'wlan.sa != 1c:4b:d6:69:cd:07 && wlan.fc.protected eq 1 && wlan.bssid \
eq 00:23:69:61:00:d0' -r evidence08.pcap -T fields -e wlan.wep.iv \
| awk '!($0 in a) {a[$0];print}' | wc -l
15587

Lo malo después de analizar la solución es que sumando el total de IVs, 14133 + 15587, salen 29720 en lugar de los 29719 obtenidos hace un rato. Seguramente sea un pregunta trampa y si así es me han pillado, porque aparte de un posible DoS cuya MAC origen es la del AP (seguramente spofeada) no veo otro ataque. Si tu lo ves haz el favor de indicármelo, te estaré muy agradecido.

¿Terminando?

Sólo nos quedan dos preguntas y para resolverlas utilizaremos el fichero de captura descifrado. La primera: ¿cual es el usuario y contraseña de acceso a la configuración del AP?

Primero obtendremos los flujos de conexiones HTTP para obtener la IP del punto de acceso:
$ tshark -r evidence08-dec.pcap -R 'http.connection' -T fields -e ip.src -e ip.dst \
| awk '!($0 in a) {a[$0];print}'
192.168.1.100 192.168.1.1
192.168.1.1 192.168.1.100
192.168.1.109 192.168.1.1
192.168.1.1 192.168.1.109

La lógica nos inclina a pensar que la ip correspondiente es la 192.168.1.1. Teniendo en cuenta que la autentificación para este tipo de dispositivos suele ser http auth basic filtraremos los paquetes dirigidos al router con este tipo de campo:
$ tshark -r evidence08-dec.pcap -R 'http && ip.dst eq 192.168.1.1' -T fields\
-e http.authbasic | awk '!($0 in a) {a[$0];print}'
admin:admin

Lo mejor de todo es que tshark nos descifra él solito la contraseña de base64 a texto plano :)

La última: ¿cual es la passphrase una vez modificada (por el intruso, supongo)? Que piense un poco tshark por nosotros, indicaremos el texto passphrase como filtro:
$ tshark -V -r evidence08-dec.pcap -R 'http contains PassPhrase'
| grep -i passphrase
SecurityMode=3&CipherType=1&PassPhrase=hahp0wnedJ00&GkuInterval=3600&layout=en

Una vez obtenidas las respuestas y como no había tenido bastante decidí intentar programar algo, pero eso lo dejo para la próxima entrada ;)

Referencias

SANS Forensic Contest #8 (Solución)

How to Crack a Wi-Fi Network’s WEP Password with BackTrack

[PDF] Understanding Wireless Attacks and Detection

[PDF] Wireless Attacks from an Intrusion Detection Perspective

[PDF] A Technical Tutorial on the IEEE 802.11 Protocol

[PDF] Detecting and Responding to Data Link Layer Attacks

PRACTICAL PACKET ANALYSIS: Using Wireshark to Solve Real-World Network Problems
by Chris Sanders
No Starch Press

4 comentarios:

Anónimo dijo...

Muy bueno, felicidades. Mira este: http://www.pentester.es/2011/06/sans-forensic-contest-8-solucion.html

neofito dijo...

Me alegro de que te haya gustado. Por cierto, si te fijas en las referencias veras como uno de los enlaces que aparece es precisamente ese ;)

Aetsu dijo...

Acabo de leerolo y muy bueno, todo muy explicado y entendible. Sigue así, un saludo.

LWG Consulting dijo...

Buen artículo todo bien explicado y buena forma de mostrar parte del código para una mejor compresión, esto demuestra que tienes mucho conocimiento sobre el tema, sigue así te felicito.