GHOST, una vulnerabilidad de Linux superada

Publicado por Diego Córdoba en

Hoy analizaremos las causas y algunos detalles técnicos de Ghost, una vulnerabilidad que afecta a algunas funciones de gestión de sockets y comunicaciones en versiones de la biblioteca estándar de C en Linux (glibc) anteriores a la 2.18.


Las versiones de las bibliotecas glibc (GNU C Library) anteriores a la versión 2.18 están afectadas por la vulnerabilidad GHOST, una vulnerabilidad de ejecución remota de código.

La vulnerabilidad radica en realidad en la función gethostbyname() , que varios hemos utilizado para programar sockets Unix, y de ella también deriva su nombre.ghost infosec vulnerability qualsys sec hac

GHOST fue descubierta por investigadores de Qualys, durante una auditoría descubrieron un buffer overflow en la función interna the_nss_hostname_digits_dots()  de la biblioteca glibc, y es explotable por medio del uso de las funciones gethostbyname*, como la propia gethostbyname(), gethostbyname2(), gethostbyname_r() y gethostbyname2_r(). Podemos ver el post original en el blog de Qualys.

La solución a la vulnerabilidad fue realizada en mayo del 2013 con la actualización a la versión glib-2.18.

Qualys también provee detalles sobre un exploit en el servidor de correos Exim, pero también fueron expuestos MySQL server, Apache, Cups, Dovecot, servidores SSH y varios más, puesto que los servicios de red generalmente hacen uso de gethostbyname() para establecer sus sockets.

La mayoría de las distribuciones liberaron parches para la vulnerabilidad, y hoy en día prácticamente todos los sistemas Linux están protegidos contra GHOST.

Detalles técnicos de Ghost

Analicemos el siguiente código:

Las líneas 85 y 86 calculan el tamaño necesario para almacenar 3 entidades en un buffer: host_addr, h_addr_ptrs y name (el hostname). Laslineas 88-117 verifican la longitud de dicho buffer.
Las líneas 121-125 preparan punteros para almacenar 4 entidades: host_addr, h_addr_ptrs, h_alias_ptr y hostname. Vemos que el tamaño del puntero *h_alias_ptr no estaba incluido en el tamaño del buffer anterior.

La función strcpy() de la línea 157 debería permitirnos escribir pasado el final del buffer, al menos (dependiendo del strlen(name))4 bytes en arquitecturas de 32b, y 64b en arquitecturas de 64b.

Para lograr el buffer overflow en la línea 157, el hostname debe cumplir los siguientes requisitos:

  • Su primer caracter debe ser un dígito (segun la línea 127).
  • Su último caracter no debe ser un punto (segun la línea 135).
  • Solo debe componerse de puntos y números (ver línea 197).
  • Debe ser parseado como una dirección IPv4 válida (ver línea 143, función inet_aton()).
  • No se tienen en cuenta las direcciones IPv6 válidas (ver línea 147, función inet_pton()), puesto que una dirección ipv6 requiere introducir el caracter «:», que no satisface la premisa anterior.

Es por esto que la función inet_aton() es la única que debe verificar un hostname válido como dirección ipv4, y ésta debe ser de la forma «a.b.c.d», o «a.b.c», o «a.b», o «a», donde a, b c y d deben ser de tipo «unsigned int».

Verificando si nuestro sistema es vulnerable

Es muy dificil que nuestro sistema sea vulnerable puesto que la versión vulnerable de glibc data del 2013, pero nunca está de mas verificarlo.

Para ello, basta con descargarse un código C que verifica la vulnerabilidad en nuestro sistema. Descargamos el código, lo compilamos, y lo ejecutamos:

Otro método… como sabemos que la versión de glibc anterior a la 2.18 es vulnerable, solo debemos ejecutar el siguiente comando y verificar la versión de nuestra biblioteca:

Como vemos, en mi caso (Debian testing «Jessie» con kernel 3.16.0-4-amd64) posee la versión 2.19-13.

Conclusiones

A no desesperarse, que hay mucho ruido en la red con cada vulnerabilidad en bibliotecas del kernel Linux, pero no todas representan una gravedad extrema, por lo menos ahora, y no por esto Linux es un mal sistema operativo. Es bueno que las vulnerabilidades se hagan publicas para forzar su corrección, puesto que de lo contrario podría ser descubierta por programadores inescrupulosos que la exploten para beneficio propio.

Fuentes:
http://www.openwall.com/lists/oss-security/2015/01/27/9
http://www.cyberciti.biz/faq/cve-2015-0235-ghost-glibc-buffer-overflow-linux-test-program/


Diego Córdoba

- Ingeniero en Informática - Mg. Teleinformática - Tesis pendiente - Docente universitario - Investigador