pre { background:#eeeeee; border:1px solid #A6B0BF; font-size:120%; line-height:100%; overflow:auto; padding:10px; color:#000000 } pre:hover { border:1px solid #efefef; } code { font-size:120%; text-align:left; margin:0;padding:0; color: #000000;} .clear { clear:both; overflow:hidden; }

Bienvenido al blog

Bienvenidos al blog de seguridad en sistemas

miércoles, 25 de mayo de 2011

Reconocimiento de activos mediante herramientas pasivas (II)

Tal como vimos en la anterior entada necesitamos de alguna forma poder saber el sistema operativo, los puertos de los servicios y de que servicios se tratan, de aquellos activos que queramos proteger en nuestro IDS. Para ello necesitamos poder reconocerlos mediante herramientas pasivas que sean capaces de obtener dicha información únicamente escuchando el tráfico de red.

Después de buscar un poco sobre que herramientas podían servirme decidí empezar con “P0f”, ya que era una de las herramientas más conocida para esta tarea. P0f lee las cabeceras TCP de los paquetes, analiza su comportamiento y reconoce ciertos sistemas operativos en función de una serie de valores como el valor de inicialización del ack, el comportamiento del host ante ciertos flags tcp, tamaño de ventana, etc. Veamos como funciona.

Para instalarla sobre un entorno Debian solo es necesario usar apt-get:
# apt-get install p0f

Para ejecutarla se puede hacer con la siguiente sentencia:
# p0f -f /etc/p0f/p0f.fp -i eth0 -t -p -i eth0

Al ejecutarla veremos los paquetes TCP que está leyendo p0f mostrando valores de las cabeceras TCP que normalmente usa para el reconocimiento del sistema operativo. Veamos ejemplos que me encontré haciendo las pruebas:

Navegación a SAW:
<Sun May 15 15:34:45 2011> 192.168.XXX.XXXX:58793 - UNKNOWN [S10:64:1:60:M1460,S,T,N,W6:.:?:?] (up: 7 hrs)
-> 62.97.78.24:80 (link: ethernet/modem)
<Sun May 15 15:34:46 2011> 192.168.XXX.XXX:58794 - UNKNOWN [S10:64:1:60:M1460,S,T,N,W6:.:?:?] (up: 7 hrs)
-> 62.97.78.24:80 (link: ethernet/modem)

Conexión a servidor SSH:
<Sun May 15 15:36:05 2011> 192.168.XXX.XXX:42113 - UNKNOWN [S10:64:1:60:M1460,S,T,N,W6:.:?:?] (up: 7 hrs)
-> 147.XXX.XXX.XXX:22 (link: ethernet/modem)

Nmap -O -sS:
<Sun May 15 15:37:24 2011> 192.168.2.101:53536 - UNKNOWN [1024:40:0:44:M1460:.:?:?]
-> 62.97.78.24:1723 (link: ethernet/modem)
<Sun May 15 15:37:24 2011> 192.168.2.101:53536 - SunOS 4.1.x
-> 62.97.78.24:8888 (distance 9, link: ethernet/modem)

Como vemos, solo cuando realizo un reconocimiento activo con nmap despierto a P0f, en los anteriores casos no es capaz de reconocer el sistema operativo. Al probarlo sobre un entorno de 100 mbits/s de ancho de banda durante una hora, observe que no se detectaron apenas sistemas operativos, así como, que se detectaron falsos positivos. 

Personalmente p0f no cumplió con lo que esperaba, entiendo que su comportamiento es complejo pero no cumple los requisitos necesarios para lo que buscamos. Por ello seguí buscando nuevas herramientas y encontré SANCP: Security Analyst Network Connection Profiler.

SANCP permite crear estadísticas de los datos leídos, en función de puertos y IPs, justo lo que necesitamos para tener un buen inventario de la red que estamos leyendo. La aplicación genera tres ficheros, uno es el tráfico pcap leído, el segundo es una estadística de la red (el que principalmente nos interesa) y el último es un resumen en tiempo real del tráfico leído.

Por desgracia SANCP no se encontraba en los repositorios por lo que decidí instalarlo a partir de las fuentes desde el CVS (es una herramienta que se ha dejado de desarrollar):

# apt-get install libpcap0.8-dev cvs
# cvs -d:pserver:anonymous@sancp.cvs.sourceforge.net:/cvsroot/sancp login
# cvs -d:pserver:anonymous@sancp.cvs.sourceforge.net:/cvsroot/sancp co sancp
# make linux
# ./install

 
El siguiente paso consistirá en editar el fichero de configuración del SANCP con unas líneas básicas. Primeramente indicamos el valor, siempre en hexadecimal, del tipo de protocolo soportado en la capa de enlace, y para este caso IPv4 (var ip 8 del valor 0x0800 del Protocol Address Type), seguidamente indicamos que protocolos debe soportar IPv4 (icmp, tcp o udp en sus valores hexadecimales del campo Protocol de la cabecera IPv4), a continuación los servicios, y por tanto los puertos que queremos que escuche, las zonas de red y para finalizar los filtros que nos interese con formato “proto_red ip_src dst_ip proto_transporte puerto_src puerto_dst, acción” (hay filtros realmente complejos):

# vim /etc/sancp/mio.conf
var ip 8
var icmp 1
var tcp 6
var udp 17
var http 80
var https 443
var smtp 25
var dns 53
var HOME_NET 192.168.0.0/16
ip HOME_NET any udp any dns, stats pass


Cuidado con la configuración que creamos porque por ejemplo, indicar dos puertos como “var icmp X, Y” o indicar dos subredes como “var HOME_NET [192.168.0.0/16 10.0.0.0/8]” da lugar a que la aplicación falle mostrando una traza del fallo como el siguiente sin indicar porque falla, hay que ir línea a línea:

sancp: Retrieved last connection ID: 5606918228258572233 8 0
*** glibc detected *** sancp: free(): invalid pointer: 0x082b5294 ***


Para finalizar ejecutaremos la aplicación indicándole el usuario y grupo, la interfaz, donde se encuentra el fichero de configuración, que no guarde ni el volcado pcap del tráfico de red ni las estadísticas en tiempo real y que muestre el valor de la IP en un formato humano (no network):
# sancp -i eth0 -P -R -H -u sancp -g sancp -c /etc/sancp/mio.conf

Si eliminamos la opción “-R” obtendremos las estadísticas en tiempo real con formato “realtime.interfaz.timestamp”, si eliminamos la variable “-P” capturaremos el tráfico de red en el fichero “pcap.interfaz.timestamp”. El fichero que nos interesa es el de estadísticas llamado “stats.interfaz.timestamp”:

# head -1 stats.eth0.1305468039
|192.168.XXX.XXX|48708|62.97.78.24|80|2|300|10|8|1522|5939|1F|1A|05|60|64|89|14600|||||60|53|89|5792|||||8665|1|0|0|0|N|N|Y|3|1067|0|0|0|0|0|N|65:37:XX:XX:0:0|0:1:0:XX:XX:6f

Con un simple script podemos parsear las entradas del fichero y obtener mucha información a nivel de red útil que puede permitirnos detectar nuevos puertos en ciertas IP's, así como, comportamientos anómalos de la red.

Sería una herramienta muy muy útil de no ser por la limitación en las opciones del fichero de configuración, por lo menos, hasta lo que he podido investigar. Creo que estaría muy bien poder añadir al código las funcionalidades para que permita poder indicarle a una misma variable más de una IP o un puerto, así como, la capacidad de depurar los errores del fichero de configuración de una forma más adecuada.

Buscando un poquito más encontré la herramienta PADS o Passive Asset Detection System, la cual lee el payload de los paquetes y comprueba si coincide con una serie de firmas escritas mediante expresiones regulares, que identifican baners de respuesta de una serie de servicios y sistemas operativos.

Para instalar la herramienta es necesario usar “apt-get”:
# apt-get install pads

El fichero de firmas se encuentra en “/etc/pads/pads-signature-list”. Un ejemplo de expresión regular sería el siguiente:

smtp,v/Microsoft Exchange SMTP/$2/$1/,220 ([-.\w]+) Microsoft ESMTP MAIL Service, Version: ([\S]+)

El siguiente paso consistirá en configurar el fichero de configuración “/etc/pads/mio.conf” de la siguiente forma:

# vim /etc/pads/mio.conf
daemon 0
pid_file /var/run/pads.pid
interface eth0
network 192.168.0.0/16,10.0.0.0/8,172.16.0.0/12
output screen
output csv: /var/lib/pads/assets.csv


Para finalizar lo ejecutaremos con la siguiente orden:
# pads -c /etc/pads/mio.conf -i eth0

Ésta escribirá el resultado de los activos descubiertos en el fichero “/var/lib/pads/assets.csv”. Un ejemplo del fichero sería el siguiente:

84.246.212.91,80,6,www,Apache,1306270559
84.246.212.92,80,6,www,lighttpd/1.4.28,1306270561
178.33.42.161,80,6,www,nginx,1306270561
195.158.241.126,80,6,www,Apache,1306270565
149.20.54.15,80,6,www,Debian),1306270567
85.152.32.141,49182,6,unknown,unknown,1306270568
213.27.222.7,80,6,www,lighttpd/1.4.26-devel-109890:109892M,1306270570
208.67.238.238,80,6,www,bit_asic/3.8/r4c1-bitcast-b,1306270572
94.102.156.82,80,6,www,Ubuntu),1306270572


Los resultados han sido bastante mejores que en las anteriores herramientas basadas en protocolos de red y no en firma como PADS. Pero la capacidad de reconocimiento de puertos y equipos que tenia herramientas como SANCP no las tiene PADS.

Creo que la combinación de SANCP y PADS sería una herramienta auxiliar perfecta para los IDS, pero para ello sería necesario juntar los dos códigos y aplicar las mejoras comentadas durante la entrada. ¿Alguien se anima?

Continuar...

sábado, 21 de mayo de 2011

Reconocimiento de activos mediante herramientas pasivas (I)

Uno de los principales problemas que nos encontramos a la hora de implantar sondas de detección de intrusos a nivel de red, es la configuración correcta del entorno para evitar inclusiones o evasiones en nuestras sondas. Por ello nos interesa conocer que tipo de sistema operativo está corriendo en un cierto host así como que servicio está ofreciendo.

El objetivo de conocer que sistema operativo se encuentra en cierta IP, es para saber como el IDS debe tratar los paquetes a nivel de cabeceras del protocolo, y por tanto, de la pila. Ésto es debido a los huecos o distintas interpretaciones del estándar establecido en los RFC por los desarrolladores de los SSOO. Por ello no es lo mismo la implementación de la pila IP en un Windows, que en una Solaris, BSD o en un Linux.

Ésto hecho se aprecia cuando recibimos paquetes fragmentados donde en una misma posición puede existir más de un dato, lo que se conoce como overlapping, un entorno Windows siempre se quedará con el fragmento que ha llegado primero, un BSD con el que tenga un offset menor y a igual ofsset se quedará con el primero, por otro lado Linux funciona igual que BSD pero a igual ofsset se quedará con el que ha llegado el último. El IDS debe conocer como ensamblará los paquetes fragmentados el host para poder detectar posibles ataques.

Este hecho se puede aplicar también en paquetes fragmentados donde antes de tener el paquete completo, y por tanto todos los fragmentos, nos llega al menos dos paquetes con un “Not More Fragments” con distinto ofsset o tamaño. Solaris aceptará el último paquete que nos llegue con ese valor, en cambio otros sistemas operativos solo aceptarán el primero que llego. A este fenómeno se conoce como inclusión y evasión en los IDS. Tenéis una explicación más extensa en ésta entrada.


Así mismo, es importante conocer que servicios están corriendo en el servidor para indicar al IDS la existencia de dichos servicios y como debe procesar los paquetes relacionados con dicho servicio.

Por ejemplo, si nos encontramos con un FTP sabemos que por cada carácter introducido por el cliente, éste es enviado al servidor, por ello si se quiere detectar la autenticación del usuario “anonymous” hay que indicar al preprocesador que en cierto puerto hay un servicio tipo FTP o Telnet y que debe juntar el payload del TCP hasta que llegue el “salto de línea”, y ésa suma de caracteres corresponde a un comando, y en este caso, corresponderá al usuario introducido.

Otro ejemplo serían los punteros de los DNS, si nosotros tenemos un puntero de DNS y por tanto si en la zona de petición o respuesta de una consulta DNS detectamos que empieza por el valor hexadecimal “C” (los dos bits del nibble alto a 1), en vez de identificar con un valor de 63 o inferior los caracteres que vamos a leer a continuación, sabemos que se trata de un puntero. Si éste apunta a otro puntero el cual apunta al puntero anterior, estamos ante un bucle recursivo que podría generar una denegación de servicio del servidor DNS. Por ello el IDS debe  ser consciente de como tratar los datos el servicio para detectar un ataque de este tipo.

También es importante conocer exactamente que aplicación está corriendo en ese puerto, y no únicamente saber que en el puerto 80 corre un servidor Web, puesto que dependiendo del servidor Web este acepta una serie de codificaciones y las interpreta de forma distinta.

Para que se entienda el problema veremos un ejemplo que leí hace poco en Twitter donde se indicaba que “Nintendo.com” fue atacada por un path transversal. Los atacantes codificaron el “..” como “%252e%252e”, es decir que el “.” fue codificado como “%252e”, ¿y que es esto? Pues fue un double decoding de ASCII a hexadecimal, es decir, cuando pasamos un valor ASCII a hexadecimal se traduce con %XX donde X corresponde al valor hexadecimal del carácter. En este caso “.” es “%2e”. A continuación se vuelve a realizar esa conversión (por eso el double) del valor hexadecimal “%2e” de forma parcial (como fue el caso de Nintendo) o total. En el ejemplo que estamos viendo se paso de ASCII a Hexadecimal el carácter “%” cuyo valor era “%25” dando lugar al “%252e”. Un entrada más detallada sobre lo expuesto en este párrafo lo podéis leer aquí.

Por tanto es necesario configurar el IDS indicándole el sistema operativo y los servicios de los paquetes que leen las sondas. Para ello se debe disponer de una CMDB actualizada donde se aporte toda esta información, algo prácticamente imposible en entornos grandes. La otra posibilidad sería mediante reconocimiento activo de la red, lo que implicaría tener que abrir todos los puertos a cierto host o una serie de hosts, algo que va en contra de cualquier política de seguridad. Por ello la única solución viable es el reconocimiento mediante herramientas pasivas, que leyendo el trafico de red sean capaces de obtener dicha información.

Pero esto en la próxima entrada.



Continuar...

jueves, 5 de mayo de 2011

Preprocesador de Snort para la geolocalización

Antes de empezar pedir perdón por estar más 20 días sin publicar nada pero las certificaciones y el trabajo me impiden tener casi tiempo para el blog. Pero no me olvido de vosotros ni de la entrada de DNS prometida.

Ahora ya sí, en la siguiente entrada vamos a tratar la herramienta de seguridad Snort, la cual es una aplicación de detección de intrusos a nivel de red (IDS). Su función es leer el tráfico de red, normalizarlo, catalogarlo y analizarlo mediante un motor de reglas en busca de una serie de patrones en el tráfico que identifiquen un posible ataque; por tanto se trata de un IDS basado en firmas. Así, dada una amenaza previamente conocida se crea una firma que permita la detección del tráfico malintencionado. Es por ello que la herramienta no dispone de la capacidad de detectar anomalías en el tráfico que permitan identificar vulnerabilidades no conocidas o malware dirigido.

Veamos lo expuesto con anterioridad en el siguiente ejemplo: se realiza una conexión saliente desde el equipo del gerente hacia China empleando el protocolo cifrado SSL a las tres de la madrugada. Es posible que este hecho requiera la intervención del equipo de gestión de incidentes, aunque implique inicialmente la actuación del primer nivel, para comprobar el motivo de esta conexión. ¿Pero cómo alertamos de esta conexión? Snort lo único que ve es una conexión desde un equipo a un servidor de Internet que emplea el protocolo SSL, es decir, una navegación web con protocolo HTTPS. Un IDS basado en reglas no entiende ni conoce los siguientes puntos:


  • Geolocalización: todas las IPs de Internet son iguales para él, no entiende de países.
  • Horarios: para él una conexión a las 12:00 es lo mismo que a las 3:00.
  • Patrones de conexión: desconoce el comportamiento de la red y por tanto no puede detectar anomalías.

Ante esta situación el equipo de seguridad analiza cómo poder añadir estas funcionalidades al motor de Snort, permitiendo detectar amenazas como las expuestas con anterioridad. Así, se decide crear una serie de preprocesadores dinámicos empleando para ello el lenguaje de programación C y la API proporcionada por Snort. Cierto es que nos encontramos con el escollo de que la documentación es escasa, por lo que hay que recurrir al estudio del código fuente de la herramienta para comprender el funcionamiento de estos.

Dentro de estos preprocesadores quiero mostrarles el funcionamiento del preprocesador de geolocalización, el cual permite marcar el país de procedencia y destino de los paquetes que son tratados por Snort, permitiendo aplicar ciertas reglas dependiendo del origen o destino del país mediante los tag “CountryS” para el origen y “CountryD” para el destino.

Veamos un ejemplo para entender el comportamiento de este preprocesador. Para ello crearemos dos reglas de Snort, donde la primera, con identificador “10000001”, generará alerta si detecta paquetes ICMP hacia Rusia (codificado como RUS) y la segunda regla,“10000002”, detectará paquetes ICMP que vengan de Rusia:

# cat /etc/snort/rules/local.rules
alert icmp any any -> any any (msg:"Destino de Rusia";
countryD: RUS; sid:10000001; rev:2;)
alert icmp any any -> any any (msg:"Origen de Rusia"; countryS: RUS; sid:10000002; rev:2;)
#

Si se fijan, hemos indicado en la primera regla que genere alerta si el país destino es Rusia (countryD: RUS;) y en la segunda regla si el país origen es Rusia (countryS: RUS;). El siguiente paso consistirá en compilar nuestro preprocesador y tenerlo en el directorio de preprocesadores dinámicos indicados en el fichero de configuración de Snort:

# cd /usr/src/snort-2.9.0.1/src/dynamic-preprocessors/geolocalizacion/
# make clean
# make
# make install
# ls /usr/local/lib/snort_dynamicpreprocessor/ | grep geolocalizacion 

lib_sfdynamic_geolocalizacion.a
lib_sfdynamic_geolocalizacion.la
lib_sfdynamic_geolocalizacion.so
lib_sfdynamic_geolocalizacion.so.0
lib_sfdynamic_geolocalizacion.so.0.0.0
#


A continuación se debe incluir el preprocesador en el fichero de configuración de Snort para que sea cargado por éste en su arranque; tengan en cuenta que el orden de los preprocesadores importa, por lo que se recomienda que esté después de “frag3”. En nuestro caso vamos a indicar que queremos que únicamente marque aquellos paquetes con origen o destino de Rusia, China, Iraq y Irán (con el tag ALL marcaría todos los paquetes):

preprocessor Geolocalizacion: country RUS CHN IRN IRQ

De esta forma ya podremos ejecutar Snort con su preprocesador:

# /usr/local/bin/snort -A console -u snort -g snort -c /etc/snort/snort.conf -i eth0 
...
Configuración del preprocesador Geolocalizacion
Listado de paises: IRQ IRN CHN RUS
BBDD GeoIP cargada en memoria

...
+++++++++++++++++++++++++++++++++++++++++++++++++++
Initializing rule chains...
2 Snort rules read 
2 detection rules
0 decoder rules
0 preprocessor rules
2 Option Chains linked into 1 Chain Headers
0 Dynamic rules
+++++++++++++++++++++++++++++++++++++++++++++++++++
...
--== Initialization Complete ==--



,,_ -*> Snort! < *-
o" )~ Version 2.9.0.1 IPv6 (Build 82)
'''' By Martin Roesch & The Snort Team: http://www.snort.org/snort/snort-team
Copyright (C) 1998-2010 Sourcefire, Inc., et al.
Using libpcap version 1.1.1
Using PCRE version: 8.02 2010-03-19
Using ZLIB version: 1.2.3.4
Rules Engine: SF_SNORT_DETECTION_ENGINE Version 1.12 <Build 18>
Preprocessor Object: SF_SMTP (IPV6) Version 1.1 <Build 9>
Preprocessor Object: SF_FTPTELNET (IPV6) Version 1.2 <Build 13>
Preprocessor Object: SF_DNS (IPV6) Version 1.1 <Build 4>
Preprocessor Object: SF_SSLPP (IPV6) Version 1.1 <Build 4>
Preprocessor Object: SF_DCERPC2 (IPV6) Version 1.0 <Build 3>
Preprocessor Object: SF_SDF (IPV6) Version 1.1 <Build 1>
Preprocessor Object: Geolocalizacion Version 1.1 <Build 1> 
Preprocessor Object: SF_SSH (IPV6) Version 1.1 <Build 13>
Commencing packet processing (pid=17271)
#


Para finalizar vamos a comprobar que el preprocesador funciona correctamente, y para ello emplearemos Scapy o Hping3 para el envío de paquetes ICMP con IP’s orígenes falsificadas de distintos países hasta que finalmente enviamos una trama con IP rusa (62.5.128.1), generando así la alerta del paquete ICMP procedente de Rusia y seguidamente en del paquete ICMP de respuesta:

04/29-19:33:22.973577 [**] [1:10000002:2] Origen de Rusia [**] [Priority: 0] {ICMP} 62.5.128.1 -> 10.10.0.8
04/29-19:33:22.973648 [**] [1:10000001:2] Destino de Rusia [**] [Priority: 0] {ICMP} 10.10.0.8 -> 62.5.128.1


Como vemos, con preprocesadores de estas características podemos aportar lógica a Snort para detectar patrones anómalos que permitan descubrir posible malware dirigido, fugas de información y 0 days, permitiendo de esta forma que Snort no sea un simple IDS basado en la detección de patrones. Esperamos que les haya parecido interesante la entrada.

PD: entrada publicada también para securityartwork. 

Continuar...