ModSecurity es un módulo para servidores HTTP cuyo propósito es reforzar la seguridad de las aplicaciones Web. Es efectivamente un sistema de prevención y detección de intrusos para servidores Web.



Técnicamente hablando, ModSecurity es un firewall a nivel aplicación (WAF, web application firewall) implementado como un módulo para diferentes servidores HTTP (Apache, NGINX y Microsoft IIS) multiplataforma de código abierto (open source). Esta herramienta permite ganar visibilidad dentro del tráfico HTTP(S) y provee un lenguaje de reglas y una API para implementar protecciones avanzadas. Esto significa que es posible filtrar tráfico HTTP, directamente en el servidor Web, según el contenido de las peticiones de los clientes, lo cual permite detectar y bloquear ataques de tipo XSS (Cross Site Scripting), SQLi (SQL injection), session hijacking, etc.

Las características principales de ModSecurity son su capacidad de log y filtrado. El log de auditoría permite almacenar el detalle de cada petición en un archivo de log, incluyendo los payloads de los POST HTTP. Los pedidos entrantes a su vez pueden ser analizados, y los pedidos ofensivos rechazados (o simplemente registrados en el log, de acuerdo a cómo se configure). De esta forma es posible incluso permitir que se ejecuten aplicaciones inseguras en nuestros servidores Web (en caso de que no quede otra alternativa claro está, los sysadmins conocen bien este tipo de escenarios) ya que están siendo protegidas por ModSecurity.

Hands on

Como menciona el título, este artículo está orientado a servidores Debian. Entonces, partiendo de un servidor Web Debian con Apache instalado y configurado, en funcionamiento, El primer paso consiste en instalar el módulo de Apache ModSecurity. Tarea sencilla, sólo es necesario instalar el paquete libapache2-modsecurity y dejar que APT se encargue de instalar las dependencias necesarias:

# apt-get install libapache2-modsecurity

Si el servidor en cuestión posee un nombre de host que no resuelve a una dirección IP (por ejemplo, cuando se trata de un servidor que maneja muchos VirtualHosts y no se ha asignado un nombre de host válido para el servidor) se producirá el siguiente error y Apache fallará al intentar reiniciar (tarea que se lleva a cabo automáticamente cada vez que APT instala un nuevo módulo de Apache):

(EAI 5)No address associated with hostname: mod_unique_id: unable to find IPv4 address of

Esto es a causa de que ModSecurity requiere del módulo mod_unique_id el cual construye magic tokens a partir del hostname (entre otras cosas). Si se deshabilita el módulo mod_unique_id (a2dismod unique_id && service apache2 start), el servidor Apache inicia normalmente, pero por supuesto es necesario mantener este módulo habilitado para poder utilizar ModSecurity.

Para solucionar este problema existen dos alternativas: asignar un nombre de host que resuelva a una dirección IP; o hacer que el nombre de host resuelva a una dirección IP. Para que el nombre de host actual resuelva a una dirección IP no es necesario meter mano en servidores DNS, sólo basta con que el nombre de host resuelva localmente. Para ello basta con fijar la dirección IPv4 del host en la tabla de configuración estática de búsqueda para nombres de host (dentro del archivo /etc/hosts):

# vi /etc/hosts

Por ejemplo, si el nombre de host inválido es "mywebserver", fijarlo para que resuelva a localhost:

127.0.0.1 localhost mywebserver

Luego iniciar Apache:

# service apache2 start
root@debian7# apachectl -M 2>/dev/null | grep security
 security2_module (shared)

En este punto queda ModSecurity correctamente instalado. Ahora resta configurarlo y ponerlo en funcionamiento, la parte más difícil. Tal como mencioné al comienzo del artículo, ModSecurity trabaja utilizando reglas para la detección y filtrado de diferentes tipos de ataques, las cuales se definen utilizando un lenguaje propio. Por defecto incluye un conjunto de reglas genéricas mantenidas por la comunidad OWASP, las cuales son liberadas de manera gratuita y protegen contra los ataques básicos. Pero también existen reglas comerciales desarrolladas por Trustwave SpiderLabs que protegen contra ataques más avanzados, como Botnets, DoS y backdoors, entre otros. Por supuesto es posible desarrollar nuestras propias reglas a medida, pero para ello es necesario contar con un elevado conocimiento sobre ataques y protocolos.

Configuración de ModSecurity en un entorno de prueba

Es conocido que ModSecurity genera muchos inconvenientes debido a falsos positivos con la mayoría de los gestores de contenido (CMS) más utilizados, tales como Wordpress, Joomla!, phpBB, Drupal y otros. Por esta razón mi idea en un comienzo fue habilitarlo sólo en un entorno de testing, de a una regla por vez, y en modo de sólo detección (sin filtrado para no generar inconvenientes con los desarrolladores). Y por supuesto deshabilitarlo completamente en producción para no generar sobrecarga (ya que el log de auditoría puede crecer desmesuradamente).

El módulo mod-security posee un archivo de configuración mod-security.conf dentro del directorio /etc/apache2/mod-available/, el cual incluye todo archivo con extensión .conf que se encuentre dentro del directorio /etc/modsecurity/:

root@debian7# cat /etc/apache2/mods-available/mod-security.conf 
<IfModule security2_module>
        # Default Debian dir for modsecurity's persistent data
        SecDataDir /var/cache/modsecurity

        # Include all the *.conf files in /etc/modsecurity.
        # Keeping your local configuration in that directory
        # will allow for an easy upgrade of THIS file and
        # make your life easier
        Include "/etc/modsecurity/*.conf"
</IfModule>

Durante la instalación de ModSecurity se incluye un archivo de configuración de ejemplo, modsecurity.conf-recommended,dentro de este directorio /etc/modsecurity/, el cual inicialmente no es incluido por no tener extensión .conf:

root@debian7# ls -l /etc/modsecurity/
total 8
-rw-r--r-- 1 root root 7453 Jul 25  2014 modsecurity.conf-recommended

Copiar el archivo de configuración de ejemplo:

# cd /etc/modsecurity/
# cp modsecurity.conf-recommended modsecurity.conf

Luego, editar el archivo:

# vi mod-security.conf

Por defecto, deshabilitar ModSecurity completamente (SecRuleEngine Off), ya que sólo será habilitado en VirtualHosts específicos:

#SecRuleEngine DetectionOnly
SecRuleEngine Off

Las reglas genéricas (OWASP ModSecurity CRS) que se incluyen con el paquete se encuentran en el directorio /usr/share/modsecurity-crs/:

# cd /usr/share/modsecurity-crs/

Dentro del mismo existen subdirectorios que organizan las reglas en diferentes tipos (base, activadas, experimentales, etc.). El directorio activated_rules está pensado para trabajar con links simbólicos de la misma forma que los directorios mods-enabled y sites-enabled de Apache (en Debian y derivados).

Pero, para diferenciar las reglas en testing de las reglas en producción (pensando a futuro), es necesario crear un directorio aparte para las reglas en testing:

# cp -a activated_rules/ activated_rules-testing

Para habilitar una regla, basta entonces con crear un enlace simbólico en activated_rules (producción) o activated_rules-testing (testing). Habilitar la regla de detección de ataques SQLi en testing para probar ModSecurity:

# cd activated_rules-testing/
# ln -s ../base_rules/modsecurity_crs_41_sql_injection_attacks.conf .

Hasta este punto, a pesar de que el módulo mod-security está habilitado, ModSecurity está configurado como apagado (SecRuleEngine Off). El siguiente paso consiste en editar el VirtualHost de testing a fin de habilitar ModSecurity en modo "DetectionOnly" (sólo en testing, de esta forma seguirá deshabilitado en producción):

# nano /etc/apache2/sites-available/testing.linuxito.com

Agregar el siguiente contenido dentro de la definición del VirtualHost:


        # ModSecurity
        <IfModule security2_module>
		SecRuleEngine DetectionOnly
		Include "/usr/share/modsecurity-crs/*.conf"
		Include "/usr/share/modsecurity-crs/activated_rules-testing/*.conf"
        </IfModule>

La primera línea de configuración habilita ModSecurity en modo "DetectionOnly". Esto significa que los ataques son detectados y registrados en el log de auditoría, pero no son bloqueados/filtrados.

La siguiente línea se utiliza para incluir el archivo /usr/share/modsecurity-crs/modsecurity_crs_10_setup.conf, el cual posee las directivas de configuración que controlan al conjunto de reglas genéricas de OWASP ModSecurity CRS.

Por último, se incluyen todos los archivos dentro del directorio que contienen las reglas /usr/share/modsecurity-crs/activated_rules-testing/, los cuales son links simbólicos a reglas habilitadas.

Finalmente, se debe recargar la configuración de Apache para que estas modificaciones surjan efecto:

# service apache2 reload

Prueba de ModSecurity

Teniendo ModSecurity habilitado en testing en modo "DetectionOnly", realizar una prueba simple de SQLi para verificar su funcionamiento (es decir, que se registre en el log de auditoría el intento de ataque). A modo de ejemplo, el vector de ataque que utilizo es simplemente:

http://testing.linuxito.com/?var=1' or '1'='1

En el archivo de configuración de ejemplo de ModSecurity se indica que el archivo de log de auditoría es /var/log/apache2/modsec_audit.log. Seguir las modificaciones sobre dicho archivo con la herramienta tail:

# tail -f /var/log/apache2/modsec_audit.log

Se observa que, luego de enviar el vector de ataque desde un navegador, se registra el siguiente evento:

Message: Rule 7f548f412280 [id "950901"][file "/usr/share/modsecurity-crs/activated_rules-testing/modsecurity_crs_41_sql_injection_attacks.conf"][line "77"] - Execution error - PCRE limits exceeded (-8): (null).
Message: Warning. Pattern match "(?i:([\\s'\"`\xc2\xb4\xe2\x80\x99\xe2\x80\x98\\(\\)]*)?([\\d\\w]+)([\\s'\"`\xc2\xb4\xe2\x80\x99\xe2\x80\x98\\(\\)]*)?(?:=|<=>|r?like|sounds\\s+like|regexp)([\\s'\"`\xc2\xb4\xe2\x80\x99\xe2\x80\x98\\(\\)]*)?\\2|([\\s'\"`\xc2\xb4\xe2\x80\x99\xe2\x80\x98\ ..." at ARGS:var. [file "/usr/share/modsecurity-crs/activated_rules-testing/modsecurity_crs_41_sql_injection_attacks.conf"] [line "77"] [id "950901"] [rev "2.2.5"] [msg "SQL Injection Attack"] [data " '1'='1"] [severity "CRITICAL"] [tag "WEB_ATTACK/SQL_INJECTION"] [tag "WASCTC/WASC-19"] [tag "OWASP_TOP_10/A1"] [tag "OWASP_AppSensor/CIE1"] [tag "PCI/6.5.2"]

Se ha detectado efectivamente el intento de inyección de código SQL.

Referencias

ModSecurity Reference Manual

libapache2-modsecurity

How To Set Up mod_security with Apache on Debian/Ubuntu


Tal vez pueda interesarte


Compartí este artículo