D-Link DIR-859 — Unauthenticated Information Disclosure (CVE-2019–20213) [ES]

Miguel Méndez Z.
4 min readDec 23, 2019

--

Investigadores

  • Miguel Mendez Z. — (s1kr10s)
  • Pablo Pollanco — (secenv)

Detalle Técnico

  • Modelo : DIR-859
  • Versión de Firmware: 1.06b01 Beta01, 1.05
  • Arquitectura: MIPS 32 bit

Vulnerabilidad

  • Remote Unauthenticated Information Disclosure via WAN and LAN

Productos Afectados

Análisis de la vulnerabilidad

La función phpcgi_main() se ejecuta como punto de entrada del binario phpcgi (el que, en realidad, es un enlace simbólico al binario /htdocs/cgibin). Mediante esta función se procesan todas las solicitudes HTTP de tipo HEAD, GET o POST, cuya extensión de archivo solicitado sean php, asp, etc. Además, obtiene y procesa los parámetros enviados en la URL, creando cadenas de llaves y valores (Key=Value) para luego ser enviadas al intérprete de PHP.

Debido a una falla en el procesamiento del cuerpo de la petición, es posible omitir la autenticación requerida por el dispositivo al acceder a ciertos archivos PHP, mediante una solicitud HTTP modificada como se muestra a continuación:

Key puede ser HEAD, GET o POST
Value es un valor terminado con salto de línea "\n"
Ruta de la URL modificada: /vpnconfig.php?pwnd=%0a
función principal

La imagen muestra la estructura en modo flowgraph de la función phpcgi_main(), donde los cuadros coloreados en verde son la ruta a seguir para llegar al código vulnerable (cuadro morado).

función phpcgi_main()

Para iniciar el análisis, debemos depurar el binario “/htdocs/cgibin”. Para ello utilizamos qemu para virtualización, y un descompilador a gusto. En nuestro caso utilizamos IDA.

Arrancamos el siguiente script con los valores definidos como se muestra, con lo que iniciamos el proceso bajo el depurador.

método de debug

Ponemos un punto de quiebre en phpcgi_main(), como se ve en la siguiente imagen. Nos enfocamos en la función cgibin_parse_request(), que comprueba la existencia de valores de la cabecera como el CONTENT_LENGTH y CONTENT_TYPE, además de hacer una llamada a parse_uri().

validación de url

La función parse_uri() se encarga de validar la existencia del carácter “?” y ordena la estructura de la url enviada. En este punto podemos encontrar el valor que controlamos (AUTHORIZED_GROUP=1%0a).

valor controlado

Al retornar la ejecución desde cgibin_parse_request() a phpcgi_main(), algunas variables son inicializadas. Luego se ejecuta la función sess_validate(), la cual retorna un valor negativo 0xffffffff (-1 en decimal), quedando así el parámetro “AUTHORIZED_GROUP” con el valor -1.

copia de datos con sprintf()
valor de retorno 0xffffffff

Siguiendo con el análisis de la rutina, podemos observar como la información que enviamos es ordenada mediante funciones (sobj_add_string, sobj_add_char, sobj_get_string) usando el registro $a0, el cual se utiliza como puntero ptr_buffer formateando variables, quedando $a0 como argumento de xmldbc_ephp() para la validación final.

copia y envío de estructura

Después de la última copia con sobj_get_string, se puede observar en memoria como queda la variable AUTHORIZED_GROUP con el valor que nosotros controlamos.

memoria

Con esto, el código PHP será ejecutado, quedando la variable AUTHORIZED_GROUP con valor 1, con lo que tenemos autorización sobre la lectura de la configuración de la VPN (cuadro inferior de la siguiente imagen).

archivo vpnconfig.php

Después de ejecutar un simple curl con un payload valido, obtenemos la configuración almacenada del archivo vpnconfig.php.

resultado de configuración

Exploit PoC

import requests
# Miguel Mendez Z.
FILES = ["vpnconfig.php"]
IP = "192.168.0.1"
PORT = "80"
headers = {'content-type': 'application/x-www-form-urlencoded'}print "\n-----------VPN-------------\n"
url_vpn = 'http://{ip}:{port}/{file1}?pwnd=%0a'.format(ip=IP, port=PORT, file1=FILES[0])
print(requests.get(url_vpn).text)

Video

Versión en Ingles: https://medium.com/@s1kr10s/d-link-dir-859-unauthenticated-information-disclosure-en-faf1a9a13f3f

Dlink: https://supportannouncement.us.dlink.com/announcement/publication.aspx?name=SAP10147

By3…

--

--