
- Artículo para Security Art Work de S2Grupo
La mayoría de vosotros ya sabréis que OSSEC es un sistema de detección de intrusos basado en host (HIDS). Si aun no lo conocéis, os recomiendo echarle un vistazo a la entrada “OSSEC como herramienta de Incident Handling”.
En esta entrada vamos a comentar la capacidad de monitorizar en tiempo real las salidas de comandos personalizados en un sistema Linux. Esta utilidad se configura en el fichero ossec.conf, entre etiquetas «<localfile>» y «<command>». Si miráis este fichero, podéis ver como ya existen algunos preestablecidos, como df, netstat o last. Nosotros podemos añadir los que queramos y sean de utilidad para nuestro entorno. Por ejemplo, un comando netstat más personalizado o un listado de los módulos cargados en el kernel de Linux con lsmod. En nuestro ejemplo, proponemos el siguiente comando personalizado de netstat:
1 |
<span style="font-family: terminal, monaco, monospace;">netstat -antupd |sort |awk 'BEGIN{printf "%-8s %-20s %-20s %-20s %-10s","PROTO", "IP/PUERTO_LOCAL", "IP/PUERTO_REMOTO", "ESTADO_CONEXION", "PROCESO_LOCAL"}/ESTABLISHED/{printf "%-8s %-20s %-20s %-20s %-10s", $1,$4,$5,$6,$7}'|uniq</span> |
La salida del comando anterior muestra un listado de las conexiones establecidas en el equipo. Hemos utilizado awk para crear un encabezado y filtrar algunas columnas para que solo muestre las que nos interesan. La salida de la ejecución del comando anterior es:
1 2 3 |
<span style="font-family: terminal, monaco, monospace;">PROTO IP/PUERTO_LOCAL IP/PUERTO_REMOTO ESTADO_CONEXION PROCESO_LOCAL tcp 127.0.0.1:3306 127.0.0.1:40146 ESTABLISHED 3192/mysqld tcp 127.0.0.1:40146 127.0.0.1:3306 ESTABLISHED 3992/ossec-dbd</span> |
El comando habrá que definirlo en el fichero de configuración ossec.conf para que sea ejecutado por el agente de OSSEC:
1 2 3 4 5 6 |
<span style="font-family: terminal, monaco, monospace;"><localfile> <log_format>full_command</log_format> <frequency>60</frequency> <command>netstat -antupd |sort |awk 'BEGIN{printf "%-8s %-20s %-20s %-20s %-10s\n","PROTO","IP/PUERTO_LOCAL","IP/PUERTO_REMOTO","ESTADO_CONEXION","PROCESO_LOCAL"}/ESTABLISHED/{printf "%-8s %-20s %-20s %-20s %-10s\n",$1,$4,$5,$6,$7}'|uniq </command> </localfile> </span> |
En las opciones de configuración del comando hemos indicado el tipo de formato de log, así como la frecuencia de repetición en segundos, por lo que se ejecutará cada minuto.
El siguiente paso es crear las reglas para que se disparen cuando se den las condiciones que deseamos. En nuestro caso, la regla que generaremos en el servidor es la siguiente:
1 2 3 4 5 6 |
<span style="font-family: terminal, monaco, monospace;"><rule id="100006" level="7"> <if_sid>530</if_sid> <match>ossec: output: 'netstat -antupd</match> <check_diff /> <description>Mi netstat personalizado.</description> </rule></span> |
La regla se disparará cuando detecte el patrón contenido entre las etiquetas <match>, comprobará la salida de este comando en el log con el generado anteriormente y, en el caso de que no coincidan, generará una alerta indicando que ha ocurrido algún cambio en las conexiones. Los resultados de cada ejecución los guarda en ficheros en el directorio /var/ossec/queue/diff/.
Para comprobar la correcta monitorización de las conexiones abrimos una conexión, podemos hacerlo con la herramienta ncat:
1 |
<span style="font-family: terminal, monaco, monospace;">$ ncat -l 50000 | ncat 127.0.0.1 50000</span> |
Ahora podemos ver las alertas generadas en el log /var/ossec/logs/alerts/alerts.log:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<span style="font-family: terminal, monaco, monospace;">** Alert 1407164058.25113: mail - ossec, 2014 Aug 04 16:54:18 debian->netstat -antupd ... Rule: 100006 (level 7) -> 'Mi netstat personalizado.' ossec: output: 'netstat -antupd … : PROTO IP/PUERTO_LOCAL IP/PUERTO_REMOTO ESTADO_CONEXION PROCESO_LOCAL tcp 127.0.0.1:3306 127.0.0.1:40297 ESTABLISHED 3192/mysqld tcp 127.0.0.1:40297 127.0.0.1:3306 ESTABLISHED 9986/ossec-dbd tcp 127.0.0.1:45827 127.0.0.1:50000 ESTABLISHED 10093/ncat tcp 127.0.0.1:50000 127.0.0.1:45827 ESTABLISHED 10092/ncat Previous output: ossec: output: 'netstat -antupd … : PROTO IP/PUERTO_LOCAL IP/PUERTO_REMOTO ESTADO_CONEXION PROCESO_LOCAL tcp 127.0.0.1:3306 127.0.0.1:40293 ESTABLISHED 3192/mysqld tcp 127.0.0.1:40293 127.0.0.1:3306 ESTABLISHED 9986/ossec-dbd </span> |
Hasta aquí todo funciona correctamente, pero el problema ocurre cuando utilizamos bases de datos para almacenar las alertas. Hemos configurado una base de datos MySQL para almacenar la información de OSSEC.
El problema es que cuando se genera la alerta, ésta se almacena en una tabla de la base de datos pero, debido a la sintaxis del comando personalizado que hemos utilizado, la base de datos genera un error. Esto es a causa de la existencia de comillas en el comando, las cuales provocan una ruptura en la sentencia de inserción de la query, generando un error de sintaxis. Este error lo podéis ver en /var/ossec/logs/ossec.log.
1 2 |
<span style="font-family: terminal, monaco, monospace;">2014/08/04 16:54:21 ossec-dbd(5203): ERROR: Error executing query 'INSERT INTO location(server_id, name) VALUES ('1', 'debian->netstat -antupd |sort |awk 'BEGIN{...}'|uniq')'. Error: 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'BEGIN...' at line 1'. </span> |
¿Como podemos solucionarlo? Muy fácil, basta con ejecutar el comando a través de un script. De esta forma se almacenará el nombre del script en la base de datos en lugar del comando problemático. Los cambios ha realizar quedarían del siguiente modo:
- Crear el script con el comando y almacenarlo en el equipo donde se encuentra el agente de OSSEC, por ejemplo en /bin/minetstat.sh:
12<span style="font-family: terminal, monaco, monospace;">#!/bin/bashnetstat -antupd |sort |awk 'BEGIN{printf "%-8s %-20s %-20s %-20s %-10s\n","PROTO", "IP/PUERTO_LOCAL","IP/PUERTO_REMOTO", "ESTADO_CONEXION","PROCESO_LOCAL"}/ESTABLISHED/{printf "%-8s %-20s %-20s %-20s %-10s\n",$1,$4,$5,$6,$7}'|uniq</span> - Cambiar la configuración del agente para que ejecute el script (ossec.conf):
123456<span style="font-family: terminal, monaco, monospace;"><localfile><log_format>full_command</log_format><frequency>60</frequency><command>/bin/minetstat.sh</command></localfile></span> - Modificar la regla en el servidor para que detecte la nueva entrada del log:
1234567<span style="font-family: terminal, monaco, monospace;"><rule id="100006" level="7"><if_sid>530</if_sid><match>ossec: output: '/bin/minetstat.sh</match><check_diff/><description>Mi netstat personalizado.</description></rule></span>
A continuación podemos ver como se ha sustituido el comando original por la ruta del script y ver como el problema con MySQL ha sido resuelto.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<span style="font-family: terminal, monaco, monospace;">** Alert 1407167245.40847: mail - ossec, 2014 Aug 04 17:47:25 debian->/bin/minetstat.sh Rule: 100006 (level 7) -> 'Mi netstat personalizado.' ossec: output: '/bin/minetstat.sh': PROTO IP/PUERTO_LOCAL IP/PUERTO_REMOTO ESTADO_CONEXION PROCESO_LOCAL tcp 127.0.0.1:3306 127.0.0.1:40344 ESTABLISHED 3192/mysqld tcp 127.0.0.1:40344 127.0.0.1:3306 ESTABLISHED 12223/ossec-dbd tcp 127.0.0.1:45873 127.0.0.1:50000 ESTABLISHED 12274/ncat tcp 127.0.0.1:50000 127.0.0.1:45873 ESTABLISHED 12273/ncat Previous output: ossec: output: '/bin/minetstat.sh': PROTO IP/PUERTO_LOCAL IP/PUERTO_REMOTO ESTADO_CONEXION PROCESO_LOCAL tcp 127.0.0.1:3306 127.0.0.1:40344 ESTABLISHED 3192/mysqld tcp 127.0.0.1:40344 127.0.0.1:3306 ESTABLISHED 12223/ossec-dbd </span> |
Con estos pasos espero haber ayudado a aquellos que alguna vez se han encontrado con este problema. Además, ejecutar los comandos a través de scripts nos permite desarrollar funcionalidades mas avanzadas y mantenerlas al margen de los ficheros de configuración de reglas, facilitándonos la compresión y edición de los scripts.
Hay que tener en cuenta que estos scripts deben tener los permisos y restricciones adecuados al entorno con el fin de evitar brechas de seguridad en el sistema.
¡Hasta la próxima!