Capítulo 4: Sistema de detección de intrusos -...

35
Proyecto Fin de Carrera 58 Capítulo 4: Sistema de detección de intrusos

Transcript of Capítulo 4: Sistema de detección de intrusos -...

Proyecto Fin de Carrera

58

Capítulo 4: Sistema de detección de intrusos

Inventario de una red IP orientado en CMSI

59

Introducción

Un sistema de detección de intrusos o IDS (Intrusion Detection System) es un programa usado para detectar accesos a un ordenador o a una red. El sistema de detección de intrusos suele tener sensores como por ejemplo un snnifer de red con lo que el núcleo del IDS puede obtener datos externos. Un sniffer es un programa que captura tramas en una red compartida.

El sistema de detección de intrusos detecta, gracias a dichos sensores, anomalías que

puede ser indicio de la presencia de ataques o falsas alarmas.

Un sistema de detección de intrusos muy utilizado es Prelude. Tiene una versión propietaria mucho más avanzada y otra Open Source. Prelude genera eventos basado en el estándar IDMEF (Intrusion Detection Message Exchange Format), es un estándar del IETF para el intercambio de mensajes de detección de intrusos.

Prelude-IDS es una aplicación que recopila toda la información relacionada con la seguridad y la reporta a un sistema centralizado, conocido como colector de alerta.

El objetivo es utilizar la plataforma de Prelude para insertar en la base de datos de inventario toda la información de alertas que detecta Prelude. Es una gran fuente de información que podemos aprovechar ya que nos proporciona de información muy diversa del estado de la red.

Arquitectura de Prelude

La arquitectura interna se describe perfectamente en la siguiente gráfica:

Imagen 32: Arquitectura interna de Prelude-IDS

Vamos a explicar paso por paso la arquitectura de Prelude. Las aplicaciones relacionadas con la seguridad tienen tres formas de enviar información de alertas al sistema centralizado.

Proyecto Fin de Carrera

60

1. Directamente a través de una aplicación de seguridad, para ello dicha aplicación debe hacer uso de las librería que pone Prelude a disposición, tanto en lenguaje C, Perl, Python. Nosotros desarrollaremos en este proyecto una aplicación que haciendo uso de las librerías de Prelude en C envíe la información directamente al servidor centralizado.

2. A través de los ficheros de logs, se inserta la información que se desee en los

logs de sistema, existirá un programa que extraiga estos datos de los ficheros de logs utilizando las librerías de syslog o logfile y lo enviará al sistema centralizado. Desarrollaremos varias sondas de este tipo.

3. A través de un fichero de datos, con un cierto formato, que contiene información

sobre alguna alerta, Esto se envía con algún programa al servidor centralizado.

En cuanto a la arquitectura de los componentes que conforma el sistema centralizado de Prelude, dependería del modo de funcionamiento del servidor central:

Modo simple: En este modo existe un único servidor centralizado.

Imagen 33: Modo simple, existe un único servidor centralizado

Modo relaying: Para el caso de que existan varios servidores. Uno de ellos le enviaría la información recibida al servidor de alerta y la registraría también en su base de datos.

Inventario de una red IP orientado en CMSI

61

Base de datos

Manager

Sensor A

Sensor B

Sensor C

Base de datos

Manager

Sensor A

Sensor B

Sensor C

Seguridad Central

Departamento de seguridad

Imagen 34: Modo relaying, existen más servidores centralizados

Componentes de Prelude

Los componentes básicos que conforman el sistema Prelude son:

Sensores

Son los programas que analizan, interpreta y envía la información de alerta. Genera eventos cuando se detecta actividad maliciosa o sospechosa. En Prelude los eventos son descritos usando el estándar IDMEF. Los sensores que podemos encontrar ya desarrollado para prelude son:

» Prelude-LML: Es un analizador de logs, esta aplicación lee los ficheros de

logs, los interpreta y envía la información al sistema centralizado. Hablaremos más tarde de este sensor.

» Snort: Es un sniffer de paquetes y un detector de intrusos basado en red.

Implementa un motor de detección de ataques y barrido de puertos que permite registrar, alertar y responder ante cualquier anomalía previamente definida.

» Mwcollect, Samhain, Sancp, etc. Para más información sobre estos sensores

diríjase a la Web oficial de Prelude, que se pasa en la bibliografía.

NOTA: Hay que destacar que un sensor y una sonda es diferente, una sonda es el dispositivo físico en cambio el sensor es la aplicación que está dentro de la sonda, una sonda puede estar compuesta de varios sensores.

Proyecto Fin de Carrera

62

Colector Conocido como Prelude-Manager, es un servidor en alta disponibilidad que

recopila toda la información que le distribuye los sensores y la almacena en una base de datos, en nuestro caso utilizaremos una base de datos PostgreSQL. La comunicación entre el manager y los clientes están encriptada usando el protocolo SSL, por tanto el cliente debe estar previamente registrado y autenticado. Cuando definamos nuestro propio sensor explicaremos el método para registrarse y autenticarse con el Prelude-Manager.

Interfaz gráfica Prelude pone una interfaz gráfica gratuita en formato html, conocida como Prewikka.

Imagen 35: Interfaz gráfica para monitorización de alertas de Prelude-IDS

Inventario de una red IP orientado en CMSI

63

Imagen 36: Tartas estadísticas que muestra los porcentajes de alertas

Imagen 37: Gráfica temporal del número de alertas

Nosotros vamos a utilizar una interfaz propietaria conocida como MarteAlert. Dicha interfaz está basada en Java y no en php coma Prewikka. A continuación se muestra algunas capturas de la interfaz de MarteAlert.

Proyecto Fin de Carrera

64

Imagen 38: Dashboard de MarteAlert

Imagen 39: Top de MarteAlert

Inventario de una red IP orientado en CMSI

65

Imagen 40: Temporal de MarteAlert

Imagen 41: Tiempo real de MarteAlert

Instalación

Vamos a comentar ahora la instalación de cada uno de los componentes:

� Colector: Está formado por los siguientes paquetes.

o Libprelude: Librería principal, usada en todos los programas de Prelude, por tanto hay que instalarlo en todos los ordenadores. Para la instalación realizaremos los siguientes pasos:

Proyecto Fin de Carrera

66

1. Nos descargamos la última versión de dicha librería de la Web oficial, en nuestro caso es la versión 0.9.15.

2. Descomprimimos el fichero.

3. Entramos en el directorio que hemos descomprimido.

4. Configuramos los parámetros de instalación, en nuestro caso le indicamos que no tenga soporte para Perl y Python ya que los sensores que desarrollaremos posteriormente están realizado en C.

5. Una vez que se haya configurado compilamos el programa ejecutando.

6. Una vez terminado de compilar lo instalamos en nuestro sistema.

o Libpreludedb: Librería que inserta los datos IDMEF en una base de datos SQL. Destacar que la versión que vamos a instalar es la 0.9.13 y los argumentos del configure es añadiéndole las librerías de PostgreSQL y no incluir las de MySQL.

1. Nos descargamos las fuentes.

2. Descomprimimos el fichero.

$ wget http://www.prelude-ids.org/download/releases/libpreludedb-0.9.13.tar.gz

$ make install

$ make

$ ./configure - -prefix=/usr - -sysconfdir=/etc - -localstatedir=/var - -datadir=/usr/share - -without-perl - -without-python

$ cd libprelude-0.9.15

$ tar xzvf libprelude-0.9.15.tar.gz

$ wget http://www.prelude-ids.org/download/releases/libprelude-0.9.15.tar.gz

Inventario de una red IP orientado en CMSI

67

3. Entramos en el directorio descomprimido.

4. Configuramos el programa con argumentos que hemos dicho anteriormente, con soporte para PostgreSQL. También quitamos las librerías de Python y Perl para desarrollar sensores, ya que usaremos exclusivamente C.

5. Compilamos las fuentes.

6. Lo instalamos en nuestro sistema.

o Prelude-Manager: Programa al cual se conecta los sensores, a quien va dirigido todas las alertas. La última versión que vamos a utilizar será 0.9.9.1. Los pasos para su instalación son:

1. Nos descargamos las fuentes de la Web oficial de Prelude.

2. Descomprimimos el fichero.

3. Entramos en el directorio descomprimido.

4. Configuramos los parámetros de instalación.

$ cd prelude-manager-0.9.9.1

$ tar xzvf prelude-manager-0.9.9.1.tar.gz

$ wget http://www.prelude-ids.org/download/releases/prelude-manager-0.9.9.1.tar.gz

$ make install

$ make

$ ./configure --prefix =/usr –with-pgsql - -without-perl –without-python - -without-mysql –localstatedir=/var –sysconfdir=/etc

$ cd libpreludedb-0.9.13

$ tar xzvf libpreludedb-0.9.13.tar.gz

Proyecto Fin de Carrera

68

5. Compilamos el programa.

6. Lo instalamos en nuestro sistema.

� Sensor: Vamos a describir como instalar los sensores en prelude. Instalaremos solo Prelude-LML es un sensor que monitoriza los ficheros de logs usando reglas predefinidas. Para la instalación seguimos el mismo método de antes, nos descargamos las fuentes con la versión 0.9.10.1.

1. Nos descargamos la fuente de la Web oficial de Prelude.

2. Descomprimimos el fichero fuente.

3. Entramos en el directorio descomprimido.

4. Configuramos los parámetros de instalación.

5. Compilamos el programa.

6. Lo instalamos en nuestro sistema.

$ make

$ /configure –prefix=/usr –with-pgsql –without-perl –without-python –without-mysql –localstatedir=/var –sysconfdir=/etc –with-libprelude-prefix=/usr –with-libpreludedb-prefix=/usr

$ cd prelude-lml-0.9.10.1

$ tar xzvf prelude-lml-0.9.10.1.tar.gz

$ wget http://www.prelude-ids.org/download/releases/prelude-lml-0.9.10.1.tar.gz

$ make install

$ make

$ ./configure –prefix=/usr –with-pgsql –without-perl –without-python –without-mysql –localstatedir=/var –sysconfdir=/etc –with-libprelude-prefix=/usr –with-libpreludedb-prefix=/usr

Inventario de una red IP orientado en CMSI

69

Una vez que hemos instalados en el sistemas las librerías y aplicaciones de Prelude es necesario ponerlo a funcionar. En primer lugar hay que crear la base de datos. Usamos por tanto el fichero .sql que se nos proporciona en Prelude para PostgreSQL con todas las actualizaciones.

Por últimos reiniciamos los servicios para que el sistema se ponga a funcionar.

En esta sección no se explica como instalar la interfaz gráfica de Prelude, conocida como Prewikka, ya que no es necesaria para el software de inventario que pretendemos explicar en este proyecto.

Desarrollo de nuevos sensores

Vamos a desarrollar diferentes sensores que sea capaz de enviar alertas a nuestro servidor de eventos. Usaremos estos sensores para registrar datos en nuestra base de datos de inventario.

Desarrollaremos dos tipos diferentes de sensores, atendiendo a la arquitectura que

dispone Prelude:

• Unos sensores que envía la información de alerta a través de un sensor genérico que proporciona Prelude. Este sensor es conocido como Prelude-LML y hay que configurar algunos parámetros. Estos sensores dependientes necesita de otro sensor para poder enviar sus alertas. La técnica de utilización es que escribimos los datos de nuestro sensor en los ficheros de logs haciendo uso de la librería syslog.

• Un sensor que envíe la información de alertas directamente como un mensaje IDMEF a nuestro servidor de eventos. Los sensores independientes no necesita de ningún otro sensor para enviar su alerta. El sensor es totalmente capaz de enviar los mensajes de alertas usando directamente las librerías que proporciona Prelude.

Sensores dependientes

Como hemos dicho anteriormente, este tipo de sensor requiere de otro sensor para poder enviar su alerta. El sensor que vamos a utilizar para enviar las alertas es Prelude-LML.

La información de alerta que se quiere enviar se obtiene a partir de los logs del sistema. Esos ficheros se encuentra normalmente en el directorio /var/log/. El programa Prelude-LML lo que realiza es un parseo de estos ficheros de logs. Por tanto los nuevos sensores se definirán como expresiones regulares que Prelude-LML utiliza para enviar alertas al leerlo de los ficheros de logs.

$ /etc/init.d/prelude-manager start $ /etc/init.d/prelude-lml start

$ make install

Proyecto Fin de Carrera

70

Expliquemos con un ejemplo sencillo como se definiría un nuevo sensor que

emitiera alertas al sensor genérico Prelude-LML.

En primer lugar hay que tener claro como es la sintaxis de la alerta en el fichero de log.

# fecha nombre_equipo nombre_sensor: texto Ej. # 21-08-2003 localhost arpwatch: new host detect with ip 192.168.1.1

Tendríamos que definir una regla de tal forma que clasificara ese log y lo enviara como una alerta a través del sensor de Prelude. Esa regla se define en un fichero especial con extensión .rules y se guarda en el directorio /etc/prelude-lml/ruleset/. Y se le indica al programa Prelude-LML que lo incluya para la detección de alerta a través de los ficheros de logs. Más tarde se definirá ficheros .rules para los nuevos sensores que vayamos desarrollando.

Para el desarrollo de los sensores tenemos que conseguir que dichos sensores

escriban en un fichero de log, eso se consigue con la siguiente función que hemos definido.

Por tanto los sensores que vayamos desarrollando tienen que invocar a la función anterior para escribir en los ficheros de logs.

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <errno.h> #include <stdarg.h> #include <syslog.h> extern int logLevel; void dosyslog(int debug, int level, int pri, char *fmt, ...) {

if (level<=logLevel && 0!=level) { va_list ap; va_start(ap, fmt); if (debug) { if (LOG_ERR==pri) { vfprintf (stderr, fmt, ap); } else { vfprintf (stdout, fmt, ap); }

} else if (level < 8) { vsyslog(pri, fmt, ap); }

va_end(ap); } }

Inventario de una red IP orientado en CMSI

71

A continuación vamos a ir explicando cada uno de los sensores dependientes que hemos desarrollado en este proyecto.

Mcheck

1. Introducción

Mcheck es un programa realizado en lenguaje C cuyo objetivo es comprobar si un servicio Web esta corriendo en un equipo y además si ese comportamiento es correcto o no lo es. Por ejemplo, podemos tener abierto el puerto ssh en nuestro equipo y no lo sabemos o no lo deseamos.

El programa devuelve un número entero que indica lo siguiente:

0: Está escuchando por un determinado puerto y debería estar escuchando, por lo tanto es un comportamiento aparentemente correcto.

1: No está escuchando un determinado servicio y no debería estar escuchando, a igual que antes es un comportamiento correcto.

2: Está escuchando y no debería estar escuchando, esto indica que hay un servicio en tu sistema que esta abierto y que tu crees tenerlo desactivado.

3: No escucha por un determinado puerto y debería estar escuchando, indica que un servicio tiene problema a la hora de iniciarse.

4: Hay un error del programa mcheck, como por ejemplo puede ser que no pueda leer de un fichero por que no exista, o que el servicio no esté definido.

2. Uso Los argumentos de la línea de comando del programa mcheck son los siguientes: mcheck [-d] [-i ip] [-t protocol] [-p port] [-s service] [-m file_mode] [-l input_mode]

[-d]: Indica si quieres ejecutar mcheck en modo depuración, en caso de que no se indique la información se mostrará en los logs del sistema /var/log/messages.

[-i ip]: IP del equipo al cual queremos hacer el escaneo de puertos.

[-t protocol]: Protocolo del servicio escaneado. Ej. TCP

[-p port]: Puerto del servicio. Ej. Puerto 80.

Proyecto Fin de Carrera

72

[-s service]: Si en lugar de especificar un puerto queremos especificar el servicio, por ejemplo ssh en lugar del puerto 22, el programa hará una traducción a partir del fichero de /etc/hosts.

[-m file_mode]: Fichero en el cual se indica si el servicio debería estar activado o no. Ej. Fichero /usr/local/mcheck/ssh cuyo contenido es ENABLED, entonces el servicio debe estar activado en el equipo en cambio si indica DISABLED entonces debe estar desactivado.

[-l input_mode]: Si en lugar de indicarle que el servicio debe estar activo o no mediante un fichero. Se lo podemos pasar a través de la línea de argumentos. Ej. -l ENABLED.

3. Código fuente Vamos a presentar ahora parte del código del programa mcheck. Empezamos en primer lugar por el fichero Makefile.

Podemos observar en el fichero Makefile que tenemos 6 ficheros fuentes:

mcheck.c: Función principal del programa mcheck.

mcheck.h: Fichero de cabecera.

temporal.c: Función que espera a que cambien un determinado socket.

temporal.h: Fichero de cabecera.

dosyslog.c: Función presentada anteriormente que necesitamos para escribir en los ficheros de logs.

COMPILE=gcc -g -Wall -c PROGRAM=mcheck TEMPORAL=temporal DOSYSLOG=dosyslog $(PROGRAM): $(PROGRAM).o $(TEMPORAL).o $(DOSYSLOG).o gcc -g -Wall -o $(PROGRAM) $(PROGRAM).o $(TEMPORAL).o $(DOSYSLOG).o $(PROGRAM).o: $(PROGRAM).c $(COMPILE) $(PROGRAM).c $(TEMPORAL).o: $(TEMPORAL).c $(COMPILE) $(TEMPORAL).c $(DOSYSLOG).o: $(DOSYSLOG).c $(COMPILE) $(DOSYSLOG).c clean: rm -f *.o rm -f $(PROGRAM) rm -f *.gch rm -f *~

Inventario de una red IP orientado en CMSI

73

dosyslog.h: Fichero de cabecera de dosyslog.

Vamos a ir presentado el código para cada fichero. Vamos a empezar por la función receive_interval, perteneciente al fichero temporal.c. Esta función devuelve un valor si ha cambiado el socket en un determinado intervalo.

El código del fichero de cabecera sería:

El código de fichero mcheck.h es

#include <stdio.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> int recive_interval(int , int );

#include "temporal.h" int recive_interval(int descript, int seconds){

struct timeval interval; fd_set readfds;

interval.tv_sec = seconds; interval.tv_usec = 0;

FD_ZERO(&readfds); FD_SET(descript, &readfds);

return select(descript+1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &interval) != 0;

}

Proyecto Fin de Carrera

74

El código de la función principal del programa mcheck es bastante extenso por lo que no la vamos a presentar, en su lugar vamos a comentar las funciones más importantes que utilizamos.

Lo que se hace es crear una conexión mediante un socket a un determinado host y puerto que se pasa a través de la línea de argumento. Dependiendo de si la conexión es UDP o TCP creamos distinto socket.

Para puertos UDP. sockfd = socket(AF_INET, SOCK_DGRAM, 0);

Para puertos TCP.

sockfd = socket(AF_INET, SOCK_STREAM, 0);

Una vez que creamos el socket intentamos conectarnos a ese puerto, hacemos un eco y si nos responde es que el puerto está abierto y si supera el intervalo entonces el puerto o está cerrado o está pasando a través de un cortafuegos.

#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <errno.h> #include <sys/un.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include "dosyslog.h" #define OUTPUT_LISTEN_OK 0 #define OUTPUT_NO_LISTEN_OK 1 #define OUTPUT_LISTEN_KO 2 #define OUTPUT_NO_LISTEN_KO 3 #define OUTPUT_ERR 4 #define DEBUG_OFF 0 #define DEBUG_ON 1 #define DISABLED 0 #define ENABLED 1 #define NONE 2 #define PROTOCOL "none" #define IP "0.0.0.0" #define MODEFILE "none" #define MODEINPUT "none" #define PORT -1 #define SERVICE "none"

#define INTERVAL 2 #define USAGE "Usage: mcheck [-d] [-i ip] [-m file_mode] [-t protocol] [-p port] [-s service] [-l input_mode]\n" #define VIEW " 0\tEscucha y deberia estar escuchando\n 1\tNo escucha y no deberia estar escuchando\n 2\tEscucha y no deberia estar escuchando\n 3\tNo escucha y deberia estar escuchando\n 4\tError en mcheck\n"

Inventario de una red IP orientado en CMSI

75

4. Log

El fichero de log que se escribe, sería por ejemplo como el siguiente: # Mar 30 09:59:22 draco mcheck: ip=192.168.100.2 port= 80 yes listen yes rightly # Mar 30 09:59:22 draco mcheck: ip=192.168.100.2 port= 22 yes listen no rightly

El fichero /etc/prelude-lml/ruleset/mcheck.rules que definimos tiene dos expresiones regulares para crear alertas con distinta gravedad, ya que si un servicio no se está ejecutando correctamente la gravedad es superior. El fichero mcheck.rules sería:

Msupervise

1. Introducción. Msupervise es un programa realizado en lenguaje C cuyo objetivo es comprobar

si un programa esta ejecutándose en tu equipo o si no lo está. A diferencia del mcheck, lo que comprueba es un proceso del sistema y no una comunicación o conexión.

Además te indica si el comportamiento es correcto o no, esto es útil para comprobar programas que se ejecutan en tu equipo. Por ejemplo, el servidor ssh,

#LOG:Mar 30 09:59:22 draco mcheck: ip=192.168.100.2 port= 80 listen, ok regex=ip= ([0-9.]+) port= ([\d]+) ([ yes listen | no listen]+) (yes rightly);\ classification.text=check service; \ id=4200; \ revision=1; \ analyzer(0).name=mcheck; \ analyzer(0).manufacturer=http://www.eneotecnologia.com; \ analyzer(0).class=NIDS; \ assessment.impact.severity=low; \ assessment.impact.completion=succeeded; \ assessment.impact.type=other; \ assessment.impact.description=status: $3 execute: $4.; \ source(0).node.address(0).category=ipv4-addr; \ source(0).node.address(0).address=$1; \ source(0).service.name=status: $3 execute: $4.; \ source(0).service.port=$2; \ last; regex= ip= ([0-9.]+) port= ([\d]+) ([ yes listen | no listen]+) (no rightly);\ classification.text=check service; \ id=4200; \ revision=1; \ analyzer(0).name=mcheck; \ analyzer(0).manufacturer=http://www.eneotecnologia.com; \ analyzer(0).class=NIDS; \ assessment.impact.severity=high; \ assessment.impact.completion=succeeded; \ assessment.impact.type=other; \ assessment.impact.description=status: $3 execute: $4.; \ source(0).node.address(0).category=ipv4-addr; \ source(0).node.address(0).address=$1; \ source(0).service.name=status: $3 execute: $4.; \ source(0).service.port=$2; \ last;

Proyecto Fin de Carrera

76

distinto a una conexión ssh, esta ejecutándose a la espera de conexiones sin que esa sea la intención del administrador (a diferencia del mcheck comprueba la ejecución de un programa, y no comprueba que el sistema acepta conexiones ssh).

El programa devuelve un número entero que indica lo siguiente:

0: El programa que se le ha pasado por la línea de comando se está ejecutando y debería estar ejecutándose, por lo tanto el comportamiento es correcto.

1: El programa no se está ejecutando y según el administrador no se debe ejecutar por lo tanto el comportamiento es a igual que ante aparentemente correcto.

2: El programa se está ejecutando y según el administrador no se debería ejecutar por lo tanto hay una posible vulnerabilidad del sistema.

3: El programa no se está ejecutando y según el administrador debería estar corriendo, por lo tanto el programa no se puede poner en ejecución por algún motivo.

4: Existe un error interno del msupervise, como por ejemplo puede ser que no pueda leer de un fichero por que no exista, o por que el programa no exista.

2. Uso.

Los argumentos de la línea de comando de mcheck son los siguientes: msupervise [-d] [-s program] [-m file_mode] [-d]: Indica si quieres ejecutar msupervise en modo depuración. En caso de que no se active esta opción la información se mostrará en los logs del sistema “/var/log/messages”.

[-s]: programa que se pretende monitorizar. Por ejemplo /usr/bin/amule.

[-m]: fichero que indica el modo de funcionamiento del programa, si este fichero contiene lo siguiente:

ENABLED: el programa debería estar ejecutándose. DISABLED: el programa debería estar desactivado

3. Código fuente.

Vamos a presentar en primer lugar el fichero Makefile.

Inventario de una red IP orientado en CMSI

77

Podemos observar en el fichero Makefile que existen como código fuente los siguientes ficheros:

msupervise.h: Fichero de cabecera.

msupervise.c: Función principal del programa msupervise.

dosyslog.c: Función presentada anteriormente para escribir en los ficheros de logs.

dosyslog.h: Fichero de cabecera de dosyslog que incluye las librerías necesarias.

El código del fichero msupervise.h es el siguiente.

COMPILE=gcc -g -Wall -c PROGRAM=msupervise DOSYSLOG=dosyslog $(PROGRAM): $(PROGRAM).o $(DOSYSLOG).o gcc -g -Wall -o $(PROGRAM) $(PROGRAM).o $(DOSYSLOG).o $(PROGRAM).o: $(PROGRAM).c $(COMPILE) $(PROGRAM).c $(DOSYSLOG).o: $(DOSYSLOG).c $(COMPILE) $(DOSYSLOG).c clean: rm -f *.o rm -f $(PROGRAM) rm -f *.gch rm -f *~

Proyecto Fin de Carrera

78

El código de la función principal no lo presentamos ya que es un código bastante extenso para insertarlo en la memoria. Solo decir utilizamos la función system para ejecutar el comando pidof para ver si un programa se está ejecutando.

4. Log.

En el fichero de log se insertaría líneas como las siguientes: # Mar 30 12:44:32 drako msupervise: sshd run ko # Mar 31 10:33:23 drako msupervise: ftp run ok A igual que antes definimos dos tipos de alertas, con distinta gravedad,

según si el funcionamiento es correcto o incorrecto. El contenido del fichero /etc/prelude-lml/ruleset/msupervise.rules sería el siguiente.

#define _GNU_SOURCE #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include "dosyslog.h" #define DEBUG_OFF 0 #define DEBUG_ON 1 //Funciona y deberia estar funcionando #define ON_OK 0 //No funciona y no deberia estar funcionando #define OFF_OK 1 //Funciona y no deberia estar funcionando #define ON_KO 2 //No funciona y deberia estar funcionando #define OFF_KO 3 //Error en msupervise #define ERROR 4 #define DISABLED 0 #define ENABLED 1 #define SERVICE "none" #define MODEFILE "none" #define USAGE "Usage: msupervise [-d] [-s service] [-m file_mode]\n" #define OUTPUT " 0\tFunciona y deberia estar funcionando\n 1\tNo funciona y no deberia estar funcionando\n 2\tFunciona y no deberia estar funcionando\n 3\tNo funciona y deberia estar funcionando\n 4\tError en msupervise\n"

Inventario de una red IP orientado en CMSI

79

Mflowalert

1. Introducción. Mflowalert es un programa realizado en C, que se conecta a una base de datos especial,

se explicará en el siguiente capítulo, y hace operaciones de monitorización. Esta base de datos contiene información sobre los flujos de red. El tráfico de red e

información detallada, tales como IP origen, IP destino, puerto origen, puerto destino, flujo de entrada o de salida, protocolo, instante de tiempo en el que se produjo, etc. Hora Source

Ip Dest Ip

Proto Sourceport

Dest port

bytes pkts dir

2007-10-23 19:45:00

3232261331 3403172284

17 0 80 3328 31 IN

2007-10-23 13:50:00

3403172284 3232261130

17 22 0 3204 31 OUT

2007-10-23 19:45:00

3232261130 3232261331

17 8080 0 29920 20 OUT

2007-10-23 23:50:00

3403072384 3512041875

17 54 0 4792 5 OUT

2007-10-23 23:55:00

3232261139 3232261331

17 0 5432 621 1 IN

2007-10-24 17:45:00

3232261139 3512041875

17 2380 0 246 3 OUT

2007-10-24 19:30:00

3403072384 3232261331

17 22 0 31194 78 OUT

2007-10-23 21:15:00

3232261130 3403072384

17 0 2345 3204 31 IN

Tabla 3: Ejemplo base de datos de tráfico

Lo que realmente se hace es comprobar si el ancho de bando utilizado no supera un cierto umbral por arriba o por debajo. Este umbral es definido por el usuario.

2. Uso.

regex= ([\S]+) ([run | stop]+) (ok); \ classification.text=supervise service; \ revision=1; \ analyzer(0).name=msupervise; \ analyzer(0).manufacturer=http://www.eneotecnologia.com; \ analyzer(0).class=NIDS; \ assessment.impact.severity=low; \ assessment.impact.completion=succeeded; \ assessment.impact.type=other; \ assessment.impact.description=service: $1 execute: $2 status:$3.; \ source(0).node.address(0).category=ipv4-addr; \ source(0).service.name=service:$1 $2 and $3; \ last; regex= ([\S]+) ([run | stop]+) (ko); \ classification.text=supervise service; \ revision=1; \ analyzer(0).name=msupervise; \ analyzer(0).manufacturer=http://www.eneotecnologia.com; \ analyzer(0).class=NIDS; \ assessment.impact.severity=high; \ assessment.impact.completion=succeeded; \ assessment.impact.type=other; \ assessment.impact.description=service: $1 execute: $2 status:$3.; \ source(0).node.address(0).category=ipv4-addr; \ source(0).service.name=service:$1 $2 and $3; \ last;

Proyecto Fin de Carrera

80

El modo de uso del programa mflowalert te lo indica si ejecuta la ayuda con la opción –h.

mflowalert [-d] –f filter –p probes –t interval [-s severity] [-e email] [-i host] [-w password] [-b min_man]

[-d]: Para ejecutar el programa en modo depuración, la salida pasaría a la salida estándar en lugar de a un fichero de log.

[-f]: Filtro SQL que se le aplica a la base de datos, por ejemplo, puede interesar generar alertas si una determinada IP supera un cierto umbral, o se supera el umbral por un determinado puerto. Se utiliza por tanto para aplicar filtros.

[-p]: Para indicarle la sonda que quieres monitorizar.

[-t]: Intervalo de tiempo de monitorización. Período de tiempo en el cual se desea monitorizar la alerta.

[-s]: Gravedad de la alerta.

[-e]: Envía un email a la dirección de correo que se le pase.

[-i]: IP del servidor donde se encuentra la base de datos con información del tráfico.

[-w]: Contraseña del usuario administrador.

[-b]: Se le indica con el formato min_max (Ej. 0_99). El mínimo y el máximo ancho de banda en bytes/s en ese intervalo. 3. Código Fuente.

En primer lugar vamos a presentar el Makefile del programa. El programa está compilado para que incluya las librería de PosgreSQL con la opción –lpq.

Se deduce del fichero anterior los ficheros fuentes del programa mflowalert.

mflowalert.h: Fichero de cabecera.

mflowalert.c: Función principal del programa mflowalert.

COMPILE=gcc -g -Wall -c PROGRAM=mflowalert DOSYSLOG=dosyslog $(PROGRAM): $(PROGRAM).o $(DOSYSLOG).o gcc -g -Wall -o $(PROGRAM) $(PROGRAM).o $(DOSYSLOG).o -lpq $(PROGRAM).o: $(PROGRAM).c $(COMPILE) $(PROGRAM).c $(DOSYSLOG).o: $(DOSYSLOG).c $(COMPILE) $(DOSYSLOG).c clean: rm -f *.o rm -f $(PROGRAM) rm -f *.gch rm -f *~

Inventario de una red IP orientado en CMSI

81

dosyslog.h: Fichero de cabecera.

dosyslog.c: Función que escribe en los logs.

El código del fichero mflowalert.h se muestra a continuación:

El código del programa mflowalert.c es bastante extenso por lo que lo explicamos de una forma básica que es lo que hace. En primer lugar se conecta a la base de datos eneo_flow con la función PQconnectdb. Una vez conectado hace consultas SQL con la función PQexec y calcula el ancho de banda en el intervalo que se esté consultado. Una vez que se obtiene el valor se compara con los límites y si supera el umbral marcado se genera una alerta. 4. Log.

En cuanto a las líneas que inserta en los ficheros de logs, sería de la siguiente forma:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <libpq-fe.h> #define DEBUG_OFF 0 #define DEBUG_ON 1 #define ENABLED 1 #define DISABLED 0 #define LOW "low" #define MEDIUM "medium" #define HIGH "high" #define INFO "info" #define LOCALHOST "127.0.0.1" #define NONE "" #define DB "eneo_flow" #define USER "eneo" #define PASS "eneo" #define HOUR 0 #define SOURCEIP 1 #define DESTIP 2 #define PROTOCOL 3 #define SOURCEPORT 4 #define DESTPORT 5 #define BYTES 6 #define PKTS 7 #define EXPORTER 8 #define DIRECTION 9

PGresult * get_list_value(char * command, PGconn * conn, int * nrows); int compare (long int min, long int max, long int total); void alert (char * commandline, char * name, long int value, long int value_reg, int debug, char * severity, int flag, char * email); long int cal_seconds(PGconn * conn, char * interval, int debug);

Proyecto Fin de Carrera

82

#May 3 09:04:21 draco mflowalert: anomaly=bandwidth severity=info

value=6751, min=0, max=20 overflow=max

Definimos el fichero de regla /etc/prelude-lml/ruleset/mflowalert.rules para Prelude-LML de la siguiente forma.

Wdping

1. Introducción.

El objetivo de este programa es realizar peticiones ICMP a una lista de máquina. En el caso de que no sea accesible una de las máquinas se escribe el siguiente log:

# 17:21:23 wdping: 192.168.100.23 unreachable

Y si no se tiene acceso a ninguna de las máquinas que se pasa en una lista se puede configurar para que se reinicie la propia máquina. Ya que es muy posible que la interfaz de red se haya quedado bloqueada.

Si se quita el cable de red es posible que se reinicie la máquina, esto no tiene mucha lógica. Para nuestro caso en la cual el objetivo de cada máquina es tener un papel en la red, como puede ser un router, que se reinicie por no prestar servicio de red puede tener una cierta lógica.

2. Uso.

Si ejecutamos la ayuda del programa con el comando wdping –h podemos ver el modo de uso:

Usage: wdping [-d] [-t time_read_ip] [-p time_new_attemp] [-n n_attemps] [-f

ip_file] [-i ip1:ip2:ip3] [-s scripts] [-r] Vamos a ir describiendo cada una de las opciones:

[-d]: A igual que los programas anteriores, sirve para activar el modo depuración.

[-t]: Es el tiempo en segundos que tarda en hacer una petición ICMP a una cierta IP.

regex= anomaly=([\S]+) severity=(info|low|medium|high) value=([\d]+), min=([\d]+), max=([\d]+) overflow=(max|min); \ classification.text=flow anomaly; \ revision=1; \ analyzer(0).name=mflowalert; \ analyzer(0).manufacturer=http://www.eneotecnologia.com; \ analyzer(0).class=NIDS; \ assessment.impact.severity=$2; \ assessment.impact.completion=succeeded; \ assessment.impact.type=other; \ assessment.impact.description=anomaly=$1 value=$3, min=$4, max=$5 overflow=$6; \ source(0).node.address(0).category=ipv4-addr; \ source(0).service.name=anomaly=$1 value=$3, min=$4, max=$5 overflow=$6; \ last;

Inventario de una red IP orientado en CMSI

83

[-p]: Es el tiempo que deja transcurrir para hacer un nuevo reintento de petición ICMP.

[-n]: Es el número de intentos de peticiones ICMP que hace con cada IP.

Para pasarle una lista de IPs se puede pasar a través de un fichero con la opción –f. El fichero debe ser de la siguiente forma:

Hay que destacar que el orden de peticiones ICMP va de la primera línea al último del fichero.

O bien, se le puede pasar la lista de IPs a través de la línea de argumento con la

opción –i ip1:ip2:ip3, por ejemplo –i 192.168.1.1:127.0.0.1

[-s]: Sirve para ejecutar un script antes de que se reinicie la máquina. Por ejemplo un script que envíe un email al administrador, que genere una alarma, etc.

[-r]: Para reiniciar la máquina, en el caso de que no haga ping a ninguna de las IPs.

3. Log. Si por cualquier motivo no puede hacer ping a una máquina de la lista se insertaría con dosyslog un texto en los ficheros de logs.

dosyslog(debug, level, LOG_INFO, “%s unreachable”, ip_host); El log insertado sería por ejemplo: # Mar 30 09:59:22 drako wdping: 192.168.1.1 unreachable Nuestro fichero /etc/prelude-lml/ruleset/wdping.rules sería el siguiente: regex= ([\d.]+) unreachable; \ classification.text=host unreachable; \ revision=1; \ analyzer(0).name=wdping; \ analyzer(0).manufacturer=http://www.eneotecnologia.com; \ analyzer(0).class=NIDS; \ assessment.impact.severity=high; \ assessment.impact.completion=succeeded; \ assessment.impact.type=other; \ assessment.impact.description=host unreachable.; \ source(0).node.address(0).category=ipv4-addr; \ source(0).node.address(0).address=$1; \ source(0).service.name=host unreachable; \ last;

192.168.1.1 www.google.es127.0.0.1 #Comentarios

Proyecto Fin de Carrera

84

Mresourcealert

1. Introducción.

El sensor mresourcealert es el encargado de generar una alerta en el caso de que ciertos parámetros del sistema sobrepasen un cierto umbral definido por el usuario.

Los parámetros del sistema que se puede monitorizar con este sensor son los siguientes:

� Porcentaje de memoria RAM utilizada. � Carga de CPU. � Porcentaje de memoria Swap utilizada.

� Porcentaje de disco duro utilizado.

� Número de procesos en la máquina.

� Número de usuarios conectados a la máquina.

Se puede configurar de tal manera que genere una alerta si sobrepasa un

determinado umbral por arriba o por debajo.

2. Uso.

Si ejecutamos el programa con la opción de ayuda –h nos indica los siguientes valores: mresourcealert [-d] [-s severity] [-e email] [-i min_max] [-mcwhl]

Vamos a ir explicando cada una de las opciones más detenidamente.

[-d]: Funcionamiento en modo debug.

[-i min_max]: Para indicarle el rango de valores que no se debe sobrepasar en caso negativo se generará una alerta. Ej. –i 5_95 indicaría el rango [5-95].

[-s]: Para indicar la gravedad de la alerta. Ej. High, low, etc.

[-e]: Para enviar un email a la dirección de correo que se le pase por la línea de argumentos en el caso de que se produzca una alerta.

[-m]: Para monitorizar el porcentaje de memoria RAM del sistema utilizado.

[-c]: Para monitorizar el porcentaje de cpu utilizado.

[-w]: Para monitorizar el porcentaje de memoria swap utilizado.

[-l]: Para monitorizar el número de procesos que se está ejecutando en el sistema. [-u]: Para monitorizar el número de usuarios que están accediendo al sistema.

3. Log.

Inventario de una red IP orientado en CMSI

85

En el momento que se supere un determinado umbral se generará el siguiente log

con la función dosyslog:

dosyslog(debug, level, LOG_INFO, “anomaly=%s severity=%s value=%lf, min=%lf, max=%lf overflow=%s”, type_anomaly, severity, value, val_min, val_max, overflow);

Nuestro fichero /etc/prelude-lml/ruleset/mresourcealert.rules tendría el siguiente contenido.

Sensores independientes

Estos sensores envían directamente mensajes IDMEF al servidor de alertas. Por tanto no es necesario que se base en otro sensor como Prelude-LML.

En los tutoriales de Prelude te dan una pauta para desarrollar un sensor en C, Perl y Python. En nuestro caso lo vamos a desarrollar en C.

Los Pasos a seguir son los siguientes:

1- Inicializar la librería de Prelude, esto se realiza con la función prelude_init.

2- Crear un cliente Prelude, es decir, tenemos que crear un objeto prelude_client_t.Esto se hace con la función prelude_client_new() que es el encargado de ver si el perfil ha sido registrado.

regex= anomaly=(memory|cpu|swap|hard disk) severity=(info|low|medium|high) value=([\d]+), min=([\d]+), max=([\d]+) overflow=(max|min); \ classification.text=anomaly $1; \ revision=1; \ analyzer(0).name=mresourcealert; \ analyzer(0).manufacturer=http://www.eneotecnologia.com; \ analyzer(0).class=NIDS; \ assessment.impact.severity=$2; \ assessment.impact.completion=succeeded; \ assessment.impact.type=other; \ assessment.impact.description=anomaly=$1 value=$3, min=$4, max=$5 overflow=$6; \ source(0).node.address(0).category=ipv4-addr; \ source(0).service.name=anomaly=$1 value=$3, min=$4, max=$5 overflow=$6; \ last;

#include "prelude.h" int ret; ret = prelude_init(&argc, argv); if ( ret < 0 ) { prelude_perror(ret, "unable to initialize the prelude library"); return -1; }

Proyecto Fin de Carrera

86

3- Una vez que el cliente se ha creado necesitas iniciar tu cliente, esto se hace con la función prelude_client_start(). Esta función lanzará una conexión al Prelude-Manager configurado y enviará un mensaje especial llamado “heartbeat”.

La librería de Prelude registrará un temporizador interno que enviará mensajes heartbeat en un intervalo definido. El temporizador registrado por la librería será llamado automáticamente, siempre que PRELUDE_CLIENT_FLAGS_ASYNC_TIMER esté activado. Por tanto, si está desactivado tu programa es el responsable de enviar los mensajes “heartbeat” al Prelude-Manager. Tendríamos que llamar a la función prelude_timer_wakeup().

Assetscan

El sensor que vamos a desarrollar se denomina assetscan. Es un programa que realiza escaneo activos a un determinado host. El resultado de ese escaneo lo envía como una alerta IDMEF.

El programa que vamos a utilizar para realizar los escaneo activos es Nmap. Es un

programa muy conocido en el mundo de los hackers por tener muy buena precisión en los escaneos. A continuación vamos a comentar sobre el programa Nmap.

Nmap (“Mapeador de redes”) es una herramienta de código abierto para exploración de red y auditoría de seguridad. Se diseño para analizar rápidadmente grandes redes, aunque funciona muy bien contra equipos individuales. Nmap utiliza paquetes IP para determinar qué equipos se encuentran disponibles en una red, qué servicios (nombre) ofrecen, qué sistemas operativos (y sus versiones) ejecutan, qué tipo de filtros de paquetes o cortafuegos se está utilizando así como docenas de otras características.

ret = prelude_client_set_flags(client, PRELUDE_CLIENT_FLAGS_ASYNC_SEND|PRELUDE_CLIENT_FLAGS_ASYNC_TIMER); if ( ret < 0 ) { fprintf(stderr, "Unable to set asynchronous send and timer.\n"); return -1; }

ret = prelude_client_start(client); if ( ret < 0 ) { prelude_perror(ret, "Unable to start prelude client");

int ret; prelude_client_t *client; ret = prelude_client_new(&client, "my-analyzer"); if ( ! client ) { prelude_perror(ret, "Unable to create a prelude client object"); return -1; }

Inventario de una red IP orientado en CMSI

87

Aunque generalmente se utiliza Nmap en auditoría de seguridad, muchos

administradores de redes y sistemas lo encuentran útil para realizar tareas rutinarias, como puede ser la planificación de actualización de servicios, la monitorización del tiempo que los equipos o servicios se mantiene activos y el inventariado de la red.

La salida de Nmap es un listado de objetivos analizados, con información adicional para cada uno dependientes de las opciones utilizadas. La información primordial es la “tabla de puertos interesantes”. Dicha tabla lista el número de puerto y protocolo, el nombre más común del servicio, y su estado. El estado puede ser open (abierto), filtered (filtrado), closed(cerrado), o unfiltered (no filtrado). Abierto significa que la aplicación en la máquina destino se encuentra esperando conexiones o paquetes en ese puerto. Filtrado indica que un cortafuego, filtro, u otro obstáculo en la red está bloqueando el acceso a ese puerto, por lo que Nmap no puede saber si se encuentra abierto o cerrado. Los puertos cerrados indican que no tienen ninguna aplicación escuchando en los mismos, aunque podría abrirse en cualquier momento. Los clasificados como no filtrados son aquellos que responden a los sondeos de Nmap, pero para los que Nmap no puede determinar si se encuentra abiertos o cerrados. Nmap informa de las combinaciones de estado open|filtered y closed|filtered cuando no puede determinar en cual de los dos estados está un puerto. La tabla de puertos también puede incluir detalles de la versión de la aplicación cuando se ha solicitado detección de versiones.

Nmap ofrece información de los protocolos IP, soportados, en vez de puertos abiertos, cuando se solicita un análisis de protocolo IP con la opción (-sO).

Además de la tabla de puertos interesantes, Nmap puede dar información adicional sobre los objetivos, incluyendo el nombre de DNS según la resolución inversa de la IP, unlistado de sistemas operativos posibles, los tipos de dispositivo, y direcciones MAC.

Puede ver un análisis típico con Nmap en el siguiente ejemplo. Los únicos parámetros de Nmap que se utilizan en este ejemplo son la opción -A, que habilita la detección de sistema operativo y versión, y la opción -T4 que acelerar el proceso, y después el nombre de los dos objetivos.

Proyecto Fin de Carrera

88

El sensor assetscan lo que va a realizar es un parseo de la salida del programa Nmap. La salida de este programa se vuelca sobre una fifo. Los ficheros fifo o pipe son una vía de intercambio de datos entre programas. Se comporta como una cola, de tal forma que todo lo que sale de un programa hacia el fichero fifo pasa a la entrada de otro programa.

El programa de assetscan está constantemente leyendo del pipe. Una vez que se

vuelca la salida del Nmap al fichero pipe esta es procesada por el programa assetscan de tal forma que si la línea hace “match” con una determinada expresión regular se envía una alerta con la información parseada.

Hay que tener en cuenta que un escaneo activo puede saturar la red, por lo tanto para no estar constantemente escaneando la red lo que hacemos es escanear un equipo cuando este es detectado de forma pasiva, para obtener más información del que nos dispone la sonda pasiva. Con esto conseguimos no estar constantemente escaneando la red. Una sonda pasiva que no puede ser útil es arpwatch.

# nmap -A -T4 scanme.nmap.org saladejuegos Starting nmap ( http://www.insecure.org/nmap/ ) Interesting ports on scanme.nmap.org (205.217.153.62): (The 1663 ports scanned but not shown below are in state: filtered) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 3.9p1 (protocol 1.99) 53/tcp open domain 70/tcp closed gopher 80/tcp open http Apache httpd 2.0.52 ((Fedora)) 113/tcp closed auth Device type: general purpose Running: Linux 2.4.X|2.5.X|2.6.X OS details: Linux 2.4.7 - 2.6.11, Linux 2.6.0 - 2.6.11 Uptime 33.908 days (since Thu Jul 21 03:38:03 2005) Interesting ports on saladejuegos.nmap.org (192.168.0.40): (The 1659 ports scanned but not shown below are in state: closed) PORT STATE SERVICE VERSION 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn 389/tcp open ldap? 445/tcp open microsoft-ds Microsoft Windows XP microsoft-ds 1002/tcp open windows-icfw? 1025/tcp open msrpc Microsoft Windows RPC 1720/tcp open H.323/Q.931 CompTek AquaGateKeeper 5800/tcp open vnc-http RealVNC 4.0 (Resolution 400x250; VNC TCP port: 5900) 5900/tcp open vnc VNC (protocol 3.8) MAC Address: 00:A0:CC:63:85:4B (Lite-on Communications) Device type: general purpose Running: Microsoft Windows NT/2K/XP OS details: Microsoft Windows XP Pro RC1+ through final release Service Info: OSs: Windows, Windows XP Nmap finished: 2 IP addresses (2 hosts up) scanned in 88.392 seconds

Inventario de una red IP orientado en CMSI

89

Vamos a presentar parte del código de nuestro programa, empezamos por las funciones más importantes que utilizamos:

Empezamos por la función add_idmef_object, es el encargado de añadir cualquier

objeto a las librerías de Prelude para enviarlo como un mensaje IDMEF.

La función checkFifo se encarga de comprobar el estado del fichero pipe, si se ha roto el enlace o no existe:

La función create_idmef es la función encargada de rellenar los parámetros del mensaje IDMEF. Aquí ponemos la información que nos interesa para el inventario como puede ser el Sistema Operativo, los puertos abiertos, etc.

void checkFifo(char * fifo) { struct stat fifostat; stat(fifo, &fifostat); if (! (fifostat.st_mode & S_IFIFO)) { dosyslog(2, LOG_ERR, "wrong fifo file. Deleting"); if (fifostat.st_mode==S_IFDIR) { rmdir(fifo); } else { remove(fifo); }

}if (access(fifo, R_OK)==-1) {

dosyslog(2, LOG_INFO, "creating fifo: %s", fifo); mknod(fifo,S_IFIFO|0660,0); }}

static int add_idmef_object(idmef_message_t *message, const char *object, const char *value){

int ret; idmef_value_t *val; idmef_path_t *path;

// First, we need to create a path to the object we want to create ret = idmef_path_new(&path, object); if ( ret < 0 ) return -1; // Using the above, we just created a "pointer" to a given path in our idmef_message_t. // This path doesn't yet exist, but might be used to read, or to write a value. ret = idmef_value_new_from_path(&val, path, value); if ( ret < 0 ) { idmef_path_destroy(path); return -1; }

ret = idmef_path_set(path, message, val);

idmef_value_destroy(val); idmef_path_destroy(path); return 0; }

Proyecto Fin de Carrera

90

void create_idmef(idmef_message_t *idmef, prelude_client_t * client, char * ipsource, char * service, char * port, char * protocol, char * text, char * ipanalyzer, char * messlog){

time_t timeNow = time(NULL); char * timeNowStr = ctime(&timeNow); char * originallog;

*(timeNowStr+strlen(timeNowStr)-1)='\0'; //now originallog = (char *) calloc(strlen(messlog)+strlen(timeNowStr)+3, sizeof(char)); sprintf(originallog, "%s: %s", timeNowStr, messlog);

add_idmef_object(idmef, "alert.analyzer(0).name", "assetscan"); add_idmef_object(idmef, "alert.analyzer(0).manufacturer", "http://www.eneotecnologia.com"); add_idmef_object(idmef, "alert.analyzer(0).model", "Inventory"); add_idmef_object(idmef, "alert.analyzer(0).version", "0.1"); add_idmef_object(idmef, "alert.analyzer(0).class", "Inventory"); add_idmef_object(idmef, "alert.analyzer(0).ostype", "Linux"); add_idmef_object(idmef, "alert.analyzer(0).osversion", "2.6.14");

add_idmef_object(idmef, "alert.analyzer(0).node.category", "6"); add_idmef_object(idmef, "alert.analyzer(0).node.name", "assetscan");

if(ipanalyzer!=NULL){ add_idmef_object(idmef, "alert.analyzer(0).node.location", ipanalyzer); add_idmef_object(idmef, "alert.analyzer(0).node.address(0).address", ipanalyzer); }

add_idmef_object(idmef, "alert.analyzer(0).node.ident", "eneo_nodo"); add_idmef_object(idmef, "alert.source(0).process.pid", "0"); add_idmef_object(idmef, "alert.additional_data(0).type","string"); add_idmef_object(idmef, "alert.additional_data(0).meaning","Original Log"); add_idmef_object(idmef, "alert.additional_data(0).data", originallog);

if(text!=NULL) add_idmef_object(idmef, "alert.classification.text", text); add_idmef_object(idmef, "alert.classification.reference(0).origin", "1"); add_idmef_object(idmef, "alert.classification.reference(0).name", "url"); add_idmef_object(idmef, "alert.classification.reference(0).url", "http://www.eneotecnologia.com"); add_idmef_object(idmef, "alert.classification.reference(0).meaning", "meaning !?"); add_idmef_object(idmef, "alert.assessment.confidence.rating", "3"); add_idmef_object(idmef, "alert.assessment.confidence.confidence", "0.9"); add_idmef_object(idmef, "alert.assessment.impact.completion", "0"); add_idmef_object(idmef, "alert.assessment.impact.severity", "2"); add_idmef_object(idmef, "alert.assessment.impact.type", "3"); add_idmef_object(idmef, "alert.source(0).ident", "eneo"); add_idmef_object(idmef, "alert.source(0).spoofed", "1"); add_idmef_object(idmef, "alert.source(0).node.category", "6");

if(ipsource!=NULL){ add_idmef_object(idmef, "alert.source(0).node.location", ipsource); add_idmef_object(idmef, "alert.source(0).node.address(0).address", ipsource); }

add_idmef_object(idmef, "alert.source(0).node.address(0).category", "6"); add_idmef_object(idmef, "alert.source(0).user.category", "1"); add_idmef_object(idmef, "alert.source(0).user.user_id(0).name", "eneo"); add_idmef_object(idmef, "alert.source(0).process.name", "nmapidmef"); add_idmef_object(idmef, "alert.source(0).service.ident", "serviceident"); add_idmef_object(idmef, "alert.source(0).service.ip_version", "4"); if(service!=NULL) add_idmef_object(idmef, "alert.source(0).service.name", service); if(port!=NULL)

Inventario de una red IP orientado en CMSI

91

En la función principal hacemos uso de la librería pcre que es la encargada de aplicar expresiones regulares en C. Hay que tener en cuenta que hay que compilar el programa con la flag –pcre.

Parseamos las líneas de salida del programa Nmap para ver si nos aporta información de los puertos abiertos, o bien del sistema operativo del equipo que estamos escaneando. Y enviamos una alerta haciendo uso de las librerías de Prelude.

Una vez que tenemos realizado el programa que envía alertas IDMEF al Prelude-Manager es necesario registrar dicha sonda. Necesitamos autenticarnos para que se acepte los mensajes en el colector de alertas.

El procedimiento a seguir para registrar una sonda assetscan en Prelude-Manager

con IP 192.168.100.72 es el siguiente: En la consola del sensor escribimos lo siguiente:

En la consola del servidor de registro, Prelude -Manager ejecutamos el siguiente comando:

Volvemos a la consola del sensor assetscan para pegar la contraseña generada por el servidor de registro y luego asentimos (“y”= yes) en la consola del servidor.

Una vez que hemos realizado esta operación ya podemos enviar alertas con nuestra

sonda assetscan al servidor Prelude-Manager.

Colector de alertas

Una vez que tenemos todas las sondas enviando información a un colector de alerta, en nuestro caso Prelude-Manager, ya disponemos de una gran fuente de información para inventario. Podemos hacer consultas SQL y clasificarla en nuestra base de datos de inventario. Hay que tener en cuenta que la información que se aporta a partir de las alertas es muy diversa y enriquecida.

Podemos obtener información tales como los puertos abiertos que tiene un equipo, el sistema operativo, los programas que están ejecutándose, las anomalías de la red, los equipos a los que no se le puede hacer ping, etc.

Un ejemplo de la base de datos PostgreSQL que tiene información de alertas es el siguiente:

$ prelude-adduser register assetscan “idmef:w admin:r” 192.168.100.72 –uid 0 –gid 0

$ prelude-adduser registration –server prelude-manager

Proyecto Fin de Carrera

92

time Gmt ident message sev Mac srcIP tgtIp sensor

2007-10-24 03:00:02

2 9189 Logfile deletion

high 00:23:34:F1:23:C1 32122 23542 Prelude LML

2007-10-24 03:00:05

2 9190 Admin Login failed

low 00:23:34:F1:00:DF 54321 32122 Prelude LML

2007-10-24 03:00:07

2 9191 Admin Login successful

high 00:23:34:F1:00:DF 54321 32122 Prelude LML

2007-10-24 03:00:08

2 9192 ssh open high 00:23:34:F1:23:C1 32122 54321 Prelude LML

Tabla 4: Ejemplo de la base de datos de alerta

Bibliografía

Las fuentes consultadas para este capítulo son: � Wikipedia

http://www.wikipedia.com

� Web oficial de Prelude.http://www.prelude-ids.org

� Web oficial de Nmap.http://insecure.org/nmap