[Parte 1] Hacking NETGEAR JWNR2010v5 Router - Authentication Bypass

Como ya he dicho en mas de una ocasion uno de los aspectos en los que mas me gusta gastar mi tiempo es en la investigación de sistemas embebidos. Así que como ya hace mas de un año que no actualizo el blog, hoy os traigo el analisis de dos vulnerabilidades que afectan a un gran numero de dispositivos NETGEAR. La explotación de estas dos vulnerabilidades en conjunto llevan al compromiso total del router de manera remota si tienen el acceso WAN activado.

En este caso el firmware a analizar es la versión 1.1.0.31 del modelo JWNR2010v5 publicado el 11/05/2015 y disponible para su descarga en el siguiente enlace http://www.downloads.netgear.com/files/GDC/JNR1010V2/N150_N300_FW_V1.1.0.31_1.0.1.zip

A partir de la lectura de binwalk sabemos que el router tiene una arquitectura MIPS y que el sistema de archivos se encuentra en el offset 0x160000 por lo que lo extraemos usando dd:



DECIMAL         HEX             DESCRIPTION
-------------------------------------------------------------------------------------------------------------------
60352           0xEBC0          U-Boot boot loader reference
[...]
131072          0x20000         uImage header, header size: 64 bytes, header CRC: 0x23F4018D, created: Thu Nov 21 21:18:53 2013, image size: 1266253 bytes, Data Address: 0x80000000, Entry Point: 0x8000C2F0, data CRC: 0xE8A06868, OS: Linux, CPU: MIPS, image type: OS Kernel Image, compression type: lzma, image name: "Linux Kernel Image"
131136          0x20040         LZMA compressed data, properties: 0x5D, dictionary size: 33554432 bytes, uncompressed size: 4632092 bytes
1441792         0x160000        Squashfs filesystem, little endian, version 4.0, compression:lzma (non-standard type definition), size: 2376782 bytes,  1160 inodes, blocksize: 131072 bytes, created: Thu Nov 21 21:18:35 2013
[...]
4028341         0x3D77B5        End of Zip archive


# dd if=N300.bin bs=1 of=N300.squashfs skip=1441792
2752512+0 records in
2752512+0 records out
2752512 bytes (2.8 MB) copied, 2.73591 s, 1.0 MB/s

# file N300.squashfs
N300.squashfs: Squashfs filesystem, little endian, version 4.0, 2376782 bytes, 1160 inodes, blocksize: 131072 bytes, created: Thu Nov 21 21:18:35 2013

# ./unsquashfs_all.sh N300.squashfs
[...]
created 850 files
created 60 directories
created 144 symlinks
created 106 devices
created 0 fifos
File system sucessfully extracted!





Tras el analisis preliminar de accesos a archivos del interfaz web detecté varias cosas interesantes. La primera es que todos los archivos estáticos son accesibles por cualquiera, pero la segunda y mas interesante es que llegado a un punto en el que se accede a una de las páginas todas las webs se volvían accesibles para cualquiera. Para esto utilicé un simple script que devuelve el codigo de error de cada una de las páginas contenidas en el webroot del router:



501http://192.168.1.1:8080/401_access_denied.htm
501http://192.168.1.1:8080/401_recovery.htm
401http://192.168.1.1:8080/Add_WPS_Client.htm
200http://192.168.1.1:8080/advanced.js
401http://192.168.1.1:8080/adv_index.htm
[...]
401http://192.168.1.1:8080/BAS_basictop.htm
200http://192.168.1.1:8080/bas_bpa.js
200http://192.168.1.1:8080/base.gif
401http://192.168.1.1:8080/BAS_ether_h.htm
401http://192.168.1.1:8080/BAS_ether.htm
[...]
401http://192.168.1.1:8080/BRS_05_networkIssue.html
401http://192.168.1.1:8080/BRS_check_manulConfig.html
401http://192.168.1.1:8080/BRS_hijack_index.htm
401http://192.168.1.1:8080/BRS_hijack_success.htm
401http://192.168.1.1:8080/BRS_index.htm
501http://192.168.1.1:8080/BRS_netgear_success.html [A Partir de este acceso todos los errores devueltos a continuación son 501 en lugar de 401]
501http://192.168.1.1:8080/BRS_plzWait.html
501http://192.168.1.1:8080/BRS_RUS_auto_account_input.html
501http://192.168.1.1:8080/BRS_RUS_auto_attention.html
[...]



Si vuelvo a lanzar el script no se devuelve ningun error 401 por lo que el router ya no pide autenticación para acceder a ninguna web así que centraremos la investigación en saber por que sucede esto.

Tras un vistazo inicial al comportamiento del router vemos que el acceso es gestionado por el propio webserver así que deducimos que en algun punto del proceso tiene que existir una falla.

Abrimos el binario del servidor web en nuestro decompilador de preferencia, en mi caso IDA y buscamos por alguna referencia al string BRS_netgear_success.html, lo que nos devuelve una funcion intermedia entre el main y otra función que llamaremos auth_req_check ya que vemos una referencia a .htpasswd en ella.



Esta funcion intermedia se encarga de procesar las URL recibida por el webserver validando mediante la funcion strstr() si una cadena existe en la URL y realizando diferentes acciones en base a esto. Esta funcion la llamaremos url_handle.

Volviendo a nuestra cadena de interes ( BRS_netgear_success.html ) llegamos al punto donde comprueba su existencia, donde si el resultado de strstr es distinto de 0, salta a una porción de código mas que interesante. En la que setea dos parametros de la nvram a 0 (need_not_login y start_in_blankstate)



Con esto en mente es facil entender cual es su función. Cuando se accede a BRS_netgear_success.html se redirecciona a la web de NETGEAR para validar el acceso a internet. Esto es un comportamiento habitual al finalizar la configuración de algunos routers ya que se permite el acceso sin credenciales de forma temporal para que el usuario configure sus propios credenciales, esto en cierto modo evita que el fabricante configure unos credenciales por defecto pero en casos mal gestionados como este supone un gravísimo problema de seguridad.

A lo largo de la función url_handle se puede observar como se da acceso a todos los ficheros estáticos (css, js, xml...) sin solicitar login ademas del comportamiento de dos urls que nos dan libre acceso BRS_netgear_success.html y BRS_top.html por lo que la presencia del .htpasswd no tiene efecto sobre estas páginas.

Por último vamos a confirmar que nuestras suposiciones son ciertas buscando donde se efectua el login y como intervienen estas dos variables en el proceso. Para ello volvemos a la funcion que mencionamos antes, auth_req_check (En el offset 00403858 por si lo quereis ver por vosotros mismos). En el inicio de esta funcion vemos que se comprueba si el directorio tiene el archivo .htpasswd y en caso afirmativo siguiendo el flujo encontramos una referencia a start_in_blankspace donde compara el valor de la variable de la siguiente manera:


if start_in_blankspace != 1:

    No se pide login

else:

    Lógica de login





Con esto confirmamos que si el valor de start_in_blankspace es 0 el comportamiento de .htpasswd queda invalidado y tenemos libre acceso al panel de administación del router. Por lo que en resumidas cuentas accediendo a http://[IP_ROUTER]:[PUERTO]/BRS_netgear_success.html el login queda invalidado de manera temporal dando a un atacante la capacidad de realizar ataques desde el interior del router.

He podido confirmar que los siguientes modelos son vulnerables:
NETGEAR_JNR1010v2, NETGEAR_JNR3000, NETGEAR_JWNR2000v5, NETGEAR_JWNR2010v5, NETGEAR_N300, NETGEAR_R3250, NETGEAR_WNR2020, NETGEAR_WNR614, NETGEAR_WNR618

En la siguiente entrada analizaré la segunda vulnerabilidad encontrada en el firmware que afecta a los modelos JWNR2010v5 y JWNR2000v5 con la que conseguiremos el compromiso total del dispositivo ademas de publicar una POC .

1 comentarios:

Anónimo 15 de septiembre de 2015, 15:13  

Muy bueno el articulo.

Un saludo.

Publicar un comentario en la entrada

ShellShock Labs es un blog dedicado a seguridad y hacking en general, un lugar donde buscamos que la gente participe con sus opiniones.

Síguenos




Posts Populares