Análisis del firmware Belkin F9K1111 V1.04.10

19 de agosto de 2015
Vectra AI Equipo de investigación sobre seguridad
Ciberseguridad
Análisis del firmware Belkin F9K1111 V1.04.10

Introducción

Recientemente, hemos sabido que HP DVLabs ha descubierto al menos diez vulnerabilidades en el extensor de rango Wi-Fi Belkin N300 Dual-Band (F9K1111). En respuesta a ello, Belkin ha publicado la versión de firmware 1.04.10. Dado que se trata de la primera actualización publicada para el F9K1111 y que no se han hecho públicos los desencadenantes de las vulnerabilidades, pensamos que sería interesante echar un vistazo más a fondo.

Desembalaje de la actualización

Para comenzar nuestro análisis, descargamos la actualización del firmware del proveedor. Utilizamos una herramienta de firmware llamada binwalk para descomprimir la actualización:

$ binwalk -Me F9K1111_WW_1.04.10_upg.bin

Nuestro resultado es un sistema de archivos SquashFS extraído de aspecto bastante estándar que representa la raíz del dispositivo, como se ve a continuación.

Captura de pantalla de la extracción del sistema de archivos binwalk SquashFS que representa la raíz del dispositivo

Ahora, para poder realizar el bindiff, necesitaremos interactuar un poco con el hardware para conseguir que los archivos estén en su estado previo al bindiff.

Obtener el firmware base

Para analizar el firmware base, necesitaremos alguna forma de volcar los datos del dispositivo físico. Para ello, primero debemos sacar el dispositivo de su carcasa.

Firmware Belkin F9K1111 extraído de su carcasa

Resaltadas en rojo y azul están las posibles vías para recuperar el firmware, el chip flash SPI y la interfaz UART respectivamente. Aunque hemos visto cierto nivel de actividad en la UART, procederemos analizando la imagen base en el chip flash SPI. El pinout para el chip que estamos tratando, MX25L1606e, está fácilmente disponible en Macronix.

Configuraciones de patillas del Macronix MX25L1606e

Después de coger esta hoja y quitar el chip, estamos listos para cablear nuestro GoodFET con respecto al pinout genérico de 8 pines.

Después de puentear los pines 7 y 8, verificamos que todo está conectado correctamente con

$ python goodfet.spiflash info

A continuación podemos ejecutar goodfet.spiflash dump para obtener el contenido del chip.

$ python goodfet.spiflash dump s

captura de pantalla del volcado de goodfet.spiflash

Por último, podemos hacer un análisis rápido del archivo resultante para asegurarnos de que el volcado parece legítimo (es decir, que contiene al menos algunas cadenas legibles).

captura de pantalla del archivo resultante para asegurarnos de que el volcado parece legítimo

El archivo binario resultante puede descomprimirse cómodamente mediante binwalk como antes.

Difundir la actualización

Trasladando ambos sistemas de archivos descomprimidos a un equipo Windows y soltándolos en WinMerge, podemos ver que en realidad no ha cambiado mucho.

captura de pantalla de WinMerge

Los archivos compiler_data, version, y FUNCTION_SCRIPT no contienen ningún cambio interesante (aparte quizás de algunos datos que podrían ser útiles para el fingerprinting). El cambio en util_system.asp tampoco es demasiado interesante. Así que, más o menos estaremos viendo las modificaciones de Belkin a webs, el GoAhead Webserver.

Análisis de redes

La Iniciativa Zero Day de HP ha nombrado las vulnerabilidades con lo que parecen ser nombres de funciones o entradas afectadas. Son las siguientes:

  • formWpsStart pinCode Vulnerabilidad de ejecución remota de código
  • formWlanSetupWPS wps_enrolee_pin Vulnerabilidad de ejecución remota de código
  • Vulnerabilidad de ejecución remota de código en formWlanMP
  • FormBSSetSitesurvey Vulnerabilidad de ejecución remota de código
  • Vulnerabilidad de ejecución remota de código en formHwSet
  • Vulnerabilidad de ejecución remota de código en formConnectionSetting
  • Vulnerabilidad de ejecución remota de código en formAccept
  • Vulnerabilidad de ejecución remota de código formiNICWpsStart
  • Vulnerabilidad de ejecución remota de código en formUSBStorage

Así que, después de cargar la versión parcheada de webs en IDA, buscamos formHwSet en la lista de funciones y no encontramos nada. De hecho muchas de estas funciones no fueron encontradas. Sacando Bindiff, podemos ver que 7 funciones fueron removidas durante la actualización:

captura de pantalla de la lista de funciones

Estos se corresponden bien con los datos del boletín de ZDI. De hecho, todas las funciones listadas en los avisos de ZDI han sido eliminadas excepto formWlanSetupWPS y formBSSetSitesurvey. Dediquemos algo de tiempo a ver las funciones eliminadas.

formUsbStorage

La primera función que consideramos es formUsbStorage. Después de darle a la función una rápida lectura, es bastante obvio cuál es el problema aquí. La variable POST sub_dir a la que se accede a través de la función websGetVar de la API de GoAhead se utiliza en una llamada a system, lo que permite la inyección de comandos.

Captura de pantalla de formUsbStorage

Este código podría activarse a través de:

wget --post-data="sub_dir=vectra;reboot" http://belkin.range/goform/formUSBStorage

formWlanMP

Se puede encontrar un error similar en el formulario actionformWlanMP. Rastreando las llamadas a websGetVar, vemos algunas posibilidades.

Captura de pantalla de un error encontrado en actionformWlanMP

Siguiendo con forwared, vemos que estas pocas posibilidades funcionarán todas como vías de inyección en la llamada al sistema -- elegimos ateFunc.

Captura de pantalla de un error encontrado en ateFunc

Este código podría activarse a través de:

wget --post-data="ateFunc=;reboot;" http://belkin.range/goform/formWlanMP

formHwSet

Hay más inyección de comandos aquí, esta vez estamos usando la variable [sic] Anntena.

Captura de pantalla de la inyección de la variable anntena en el comando

Este código podría activarse a través de:

wget --post-data="Anntena=;reboot;" http://belkin.range/goform/formHwSet

formConnectionSetting

Aquí, tenemos inyección de comandos en el parámetro timeOut en la función formConnectionSetting.

captura de pantalla de la inyección de comandos en el parámetro timeOut en la función formConnectionSetting

Este código podría activarse a través de:

wget --post-data="timeOut=1;reboot;" http://belkin.range/goform/formConnectionSetting

formBSSetSitesurvey

En este punto, hemos golpeado el caballo de la función eliminada hasta la muerte. Echemos un vistazo a la más significativa de las funciones que Belkin decidió no eliminar - formBSSetSitesurvey. He aquí un resumen:

formBSSetSitesurvey descripción general

Después de retroceder horrorizados, podemos ampliar la imagen y ver que el principal cambio es que Belkin ha añadido una función llamada strcat_escape que se utiliza a lo largo de esta función en las fuentes que se originan del formulario websGetVar.

Belkin ha añadido una función llamada strcat_escape

This strcat_escape function takes 3 buffers - dst, src, and tokens. The function uses nested loops to search the src string for existence of any of the tokens to be escaped, if found they are escaped before being copied into dst. In the pictured case token_of_none_quotation is passed as tokens which is defined as"\\\"'$()<>` #&*

Hemos reimplementado esta función en C a partir del binario de webs y podemos ver la salida esperada:

salida de función en webs binario

Esta cadena escapada (presumiblemente de forma correcta) se pasa de forma normal al sistema a través de sprintf como antes.

captura de pantalla función sprintf

La eficacia de este parche depende de varios factores:

  • La función strcat_escape funciona completamente según lo previsto
  • strcat_escape no provoca involuntariamente desbordamientos de búfer ;-)
  • strcat_escape se utiliza en todas las entradas del usuario que terminan en el sistema
  • Nos hemos puesto en contacto con Belkin para tratar algunos de estos puntos.

Conclusión

Todos sabemos ya que la madurez de la seguridad del código de los dispositivos embebidos es un problema. Aquí vemos que incluso en los dispositivos lanzados en 2014, sigue siendo un problema.

Preguntas frecuentes