Reforzando la Seguridad con un WAF Open Source, primera linea de defensa.

Reforzando la Seguridad con un WAF Open Source, primera linea de defensa.

Proteger los problemas conocidos de una web, se puede. Para ello usamos un WAF

¿Cuántas veces escuchamos? Salimos así, después lo solucionamos. O cuando está en marcha, ¿Pero solo se explota de manera interna o externa también? Algo que podemos utilizar es un Web Application Firewall, que nos servirá para ganar tiempo, mientras solucionamos la causa raíz.

¿Qué es un WAF? No es ni más ni menos que un tipo de firewall que supervisa, filtra o bloquea el tráfico HTTP hacia y desde una aplicación web. Se diferencia de un firewall normal en que puede filtrar el contenido de aplicaciones web específicas, mientras que un firewall de red protege el tráfico entre los servidores.

Para está prueba de concepto vamos a utilizar Nginx que es un servidor web Open Source conocido y ampliamente utilizado que se puede utilizar como un servidor proxy, proxy inverso.

Normalmente, el servidor Nginx se despliega en una red pública y se utiliza un proxy inverso que enruta el tráfico procedente de los clientes a la red interna donde se encuentran las aplicaciones web reales.

Tener las aplicaciones en una red interna es una buena práctica, no está de más agregar una capa más de seguridad con un WAF que protege las aplicaciones de vulnerabilidades potenciales. Lo que vamos a utilizar es Nginx con ModSecurity como proxy inverso agregando el paquete de reglas de owasp-modsecurity y así proteger una aplicación vulnerable como juice-shop.

Si te seguís preguntando ¿Que es ModSecurity? Es un firewall de aplicaciones web de código abierto diseñado para aumentar la seguridad de los servidores web al protegerlos contra una variedad de ataques y vulnerabilidades comunes en las aplicaciones web. Actúa como una capa de seguridad entre las aplicaciones web y el servidor web, analizando el tráfico entrante y saliente en busca de patrones sospechosos o maliciosos. ModSecurity puede detectar y bloquear intentos de inyección SQL, cross-site scripting (XSS), ataques de fuerza bruta y otros tipos de ataques dirigidos a aplicaciones web. Se configura mediante reglas personalizables que permiten adaptar su comportamiento a las necesidades específicas de cada sitio web.

Prueba de Concepto

Vamos a pullear las imágenes de Nginx+ModSecurity, para luego agregar la configuración, y la de Juice Shop. Y creamos una red, en nuestro ambiente docker.

# Imagen de Nginx con ModSecurity
docker pull owasp/modsecurity-crs:3.3.5-nginx-202308071108
# Imagen de Aplicativo
docker pull bkimminich/juice-shop
# Creacion de Red
docker network create backend --subnet 10.10.10.0/24

Generamos nuestro archivo de configuración default.conf, para buildear nuestra imagen productiva.

# Nginx configuration for both HTTP and SSL
map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

server {
    listen 80 default_server;

    server_name localhost;
    set $upstream http://owaspjuice.shop:3000; # Change this
    set $always_redirect off;
    location / {
        client_max_body_size 0;

        if ($always_redirect = on) {
            return 301 https://$host$request_uri;
        }

        include includes/proxy_backend.conf;

        index index.html index.htm;
        root /usr/share/nginx/html;
    }

    include includes/location_common.conf;
    #include includes/custom_locations.conf;

}

server {
    listen 443 ssl;

    server_name localhost;
    set $upstream http://localhost:80;

    ssl_certificate /etc/nginx/conf/server.crt;
    ssl_certificate_key /etc/nginx/conf/server.key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:MozSSL:10m;
    ssl_session_tickets off;

    ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    ssl_stapling off;
    ssl_stapling_verify off;

    ssl_verify_client off;

    location / {
        client_max_body_size 0;

        include includes/proxy_backend.conf;

        index index.html index.htm;
        root /usr/share/nginx/html;
    }
    include includes/location_common.conf;
    #include includes/custom_locations.conf;
}

Ya tenemos la imagen del servidor y el archivo de configuración. Nos resta el Dockerfile y ejecutar la construcción de la imagen. La llamaremos nginx-modsec.

#Dockerfile
FROM owasp/modsecurity-crs:3.3.5-nginx-202308071108
COPY default.conf /etc/nginx/templates/conf.d/default.conf.template

Buildeamos

docker build -t nginx-modsec .

Vamos a echar a correr los containers.

docker run -it --name juice_shop --hostname owaspjuice.shop --network backend --ip 10.10.10.100 -p 3000:3000 bkimminich/juice-shop
docker run -it --name nginx-modsec --network backend --ip 10.10.10.200 -p 80:80 nginx-modsec

Como pueden ver en la imagen tenemos los dos servicios corriendo y conocemos sus direcciones para comenzar las pruebas. Podemos pegarle directo a JuiceShop puerto 3000 o ir atraves del Proxy. Vamos a realizar un ataque para mostrar como el WAF hace su trabajo.

Vamos a ver si la aplicaciones vulnerable a inyección. Primero lo haremos directo a la aplicación, donde hacemos la inyección y obtenemos el token.

Ahora vamos a pasar a traves del WAF y veremos como el mensaje cambia a 403 Forbidden.

Los mensajes son parametrizables, en las reglas. Aca les dejo una colección de reglas para que agreguen. No se recomienda poner un WAF en producción sin antes observar que es lo que pasa, por ello se puede configurar en /etc/modsecurity/modsecurity.conf para poner en modo monitor e investigar los logs que nos entrega en SecAuditLog. Importante re dirigir los logs al SIEM para sumarizar y sacar el mejor tunning.

Referencias

https://www.nginx.com/https://zeyad-abulaban.medium.com/dockerized-mod-security-waf-c3e7233be002

https://www.linuxbabe.com/security/modsecurity-apache-debian-ubuntuhttps://github.com/coreruleset/coreruleset/blob/v4.0/dev/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example