Saltar al contenido

¿Cómo analizo los registros de AWS WAF en CloudWatch?

7 minutos de lectura
0

Quiero analizar y filtrar los registros de AWS WAF que almaceno en Amazon CloudWatch.

Resolución

Para analizar y filtrar solicitudes de registro específicas de AWS WAF en CloudWatch, utiliza Información de registros de CloudWatch o el generador de consultas de CloudWatch.

Uso de Información de registros de CloudWatch

Puedes usar Información de registros de CloudWatch en la consola de CloudWatch o en la consola de AWS WAF.

Consola de AWS WAF

Sigue estos pasos:

  1. Abre la consola de AWS WAF.
  2. En el panel de navegación, elige Paquetes de protección (ACL web).
  3. Selecciona tu paquete de protección.
  4. Elige Ver panel, registros y solicitudes de muestra.
  5. En el explorador de registros, elige Ver en CloudWatch.
  6. En el editor de consultas, introduce la consulta. Utiliza la sintaxis de consulta para diseñar las consultas. También puedes elegir consultas de la lista Consultas utilizadas con más frecuencia.
  7. Selecciona Ejecutar consulta.

Consola de CloudWatch

Sigue estos pasos:

  1. Abre la consola de CloudWatch.
  2. En el panel de navegación, en Registros, selecciona Información de registros.
  3. En Criterios de selección, selecciona uno o más grupos de registro para consultar. O bien, selecciona Examinar grupos de registro y, a continuación, selecciona tus grupos de registro.
  4. (Opcional) Elige un intervalo de tiempo para la consulta.
  5. Utiliza la sintaxis de consulta para diseñar las consultas.
  6. Para ver los resultados, selecciona Ejecutar consulta.

Uso del generador de consultas de CloudWatch

Para usar el lenguaje natural para generar consultas y analizar los registros de acceso, ejecuta el generador de consultas en CloudWatch.

Consultas de ejemplo 

Para filtrar información específica con Información de registros de CloudWatch, utiliza los siguientes ejemplos de consultas.

Principales direcciones IP de los clientes

Para contar las principales direcciones IP de los clientes que acceden a tu aplicación, ejecuta la siguiente consulta:

stats count(*) as requestCount by httpRequest.clientIp
| sort requestCount desc

Principales países

Para contar los principales países de origen que realizan solicitudes a tu aplicación, ejecuta la siguiente consulta:

stats count(*) as RequestCount by httpRequest.country as Country
| sort RequestCount desc

Principales métodos HTTP

Para contar los principales métodos HTTP que acceden a tu aplicación, ejecuta la siguiente consulta:

stats count(*)as RequestCount by httpRequest.httpMethod as Method
| sort RequestCount desc

Principales reglas de terminación

Para contar las principales reglas de terminación de tus registros, ejecuta la siguiente consulta:

stats count(*) as RequestCount by terminatingRuleId
| sort RequestCount desc

Principales hosts

Para contar los principales hosts que acceden a tu aplicación, ejecuta la siguiente consulta:

parse @message /\{"name":"[Hh]ost","value":"(?<Host>[^"]*)"/
| stats count(*) as RequestCount by Host
| sort RequestCount desc

Principales agentes de usuario

Para contar los principales agentes de usuario que acceden a tu aplicación, ejecuta la siguiente consulta:

parse @message /\{"name":"[Uu]ser\-[Aa]gent","value":"(?<UserAgent>[^"]*)"/  
| stats count(*) as RequestCount by UserAgent
| sort RequestCount desc

Principales X-forwarded-Ips

Para contar las principales direcciones IP XFF que realizan solicitudes a tu aplicación, ejecuta la siguiente consulta:

parse @message /\{"name":"[Xx]-[Ff]orwarded-[Ff]or","value":"(?<XFF_IP>[^"}]*)/
| stats count(*) as RequestCount by XFF
| sort RequestCount desc

Principales direcciones IP bloqueadas por la regla basada en tarifas

Para encontrar direcciones IP que superen el umbral y, en caso de que se produzca un ataque DDoS por inundación de HTTP, ejecuta la siguiente consulta:

fields httpRequest.clientIp
| filter terminatingRuleType = "RATE_BASED" ## and webaclId = "<Webacl ARN>" ## uncomment to filter for specific WebACL|
| stats count(*) as requestCount by httpRequest.clientIp, httpRequest.country
| sort requestCount desc
| limit 100

Filtrar por solicitudes bloqueadas

Para filtrar por todas las solicitudes bloqueadas y su regla de terminación, ruta de URI y dirección IP del cliente, ejecuta la siguiente consulta:

fields @timestamp, httpRequest.clientIp as ClientIP, httpRequest.uri as URI, terminatingRuleId as rule
| filter action = "BLOCK"
| sort @timestamp desc

Filtrar por host

Para filtrar los registros por un host específico, ejecuta la siguiente consulta:

fields terminatingRuleId as Rule, action, httpRequest.country as Country, httpRequest.clientIp as ClientIP, httpRequest.uri as URI
| parse @message /\{"name":"[Hh]ost","value":"(?<Host>[^"]*)"/  
| filter Host = "www.example.com"

Nota: Sustituye www.example.com por el nombre de tu host.

Filtrar por una cadena específica

Para filtrar los registros por una cadena específica, ejecuta la siguiente consulta:

fields terminatingRuleId as Rule, action, httpRequest.country as Country, httpRequest.clientIp as ClientIP, httpRequest.httpMethod as Method,httpRequest.uri as URI
| parse @message /\{"name":"[Hh]ost","value":"(?<Host>[^"]*)"/
| parse @message /\{"name":"[Uu]ser\-[Aa]gent","value":"(?<UserAgent>[^"]*)"/  
| filter @message like "{jndi:ldap"
| sort action, URI desc

Nota: Sustituye {jndi:ldap por tu cadena.

Filtrar por solicitudes POST

Para filtrar por las solicitudes POST, ejecuta la siguiente consulta:

fields terminatingRuleId as Rule, action, httpRequest.country as Country, httpRequest.clientIp as ClientIP, httpRequest.httpMethod as Method, httpRequest.uri as URI
| parse @message /\{"name":"[Uu]ser\-[Aa]gent","value":"(?<UserAgent>[^"]*)"/  
| parse @message /\{"name":"[Hh]ost","value":"(?<Host>[^"]*)"/  
| filter httpRequest.httpMethod ="POST"
| display Rule, action, Country, ClientIP, Method, URI, Host, UserAgent
| sort Rule, action desc

NOTA: Puedes usar la consulta anterior para filtrar por otros métodos HTTP. Sustituye POST or GET, Head u otros métodos HTTP.

Inyección de código SQL o XSS

Para encontrar los patrones que provocan scripting entre sitios (XSS) o la inyección de código SQL en la regla de terminación de una regla personalizada o grupos de reglas administradas de AWS, ejecuta la siguiente consulta:

fields @timestamp  
| parse @message ',"terminatingRuleMatchDetails":[*],' as terminatingRuleMatchData  
| filter (terminatingRuleMatchData like /XSS/ or terminatingRuleMatchData like /SQL/)  
| display @timestamp, httpRequest.clientIp, httpRequest.country, terminatingRuleMatchData, httpRequest.requestId

La consulta muestra entradas con una marca de tiempo, la dirección IP del cliente, el país de origen, los detalles de la coincidencia y el ID de la solicitud.

Filtrar por país

Para filtrar las solicitudes que no se originan en un país específico, ejecuta la siguiente consulta:

fields terminatingRuleId as Rule, action, httpRequest.country as Country, httpRequest.clientIp as ClientIP, httpRequest.uri as URI
| parse @message /\{"name":"[Uu]ser\-[Aa]gent","value":"(?<UserAgent>[^"]*)"/  
| parse @message /\{"name":"[Hh]ost","value":"(?<Host>[^"]*)"/
| filter Country != "US"
| sort Country, action desc

Nota: Sustituye US por el código de país que quieras filtrar.

Filtrar por solicitudes contadas según una regla específica en un grupo de reglas

Para filtrar las entradas de registro para las solicitudes que una regla específica de un grupo de reglas cuenta y termina de forma predeterminada, ejecuta la siguiente consulta:

fields @timestamp
| filter (@message like 'excludedRules":[{"exclusionType":"EXCLUDED_AS_COUNT","ruleId":"NoUserAgent_HEADER"}]}' and @message like 'terminatingRuleId":"Default_Action"')
| parse @message '"ruleId":*}]}' as ruleMatchDetails
| display @timestamp, httpRequest.clientIp, httpRequest.country, ruleMatchDetails, httpRequest.requestId

Nota: Sustituye ruleId por el ID de tu regla.

Filtrar por solicitudes con un CAPTCHA que no es válido

Para filtrar las 100 solicitudes principales con un CAPTCHA que no es válido, ejecuta la siguiente consulta:

fields @timestamp, httpRequest.clientIp, httpRequest.requestId, captchaResponse.failureReason, @message
| filter captchaResponse.failureReason ='TOKEN_MISSING'
| sort @timestamp desc| limit 100

Nota: Sustituye 100 en la cláusula de límite por el número de solicitudes por las que deseas filtrar.

Esta consulta muestra la hora de la solicitud, la dirección IP, el ID de la solicitud, el código de respuesta y el mensaje completo.

Filtrar todas las solicitudes detectadas por reglas administradas de AWS de ABC, ATP, ACFP y AntiDDoS

Para filtrar las 100 solicitudes principales que coincidan con las etiquetas de reglas administradas de AWS de ABC, ATP, ACFP o AntiDDoS, ejecuta la siguiente consulta:

fields @timestamp
| filter @message like 'awswaf:managed:aws:bot-control'
| display @timestamp,httpRequest.clientIp, httpRequest.uri,Labels, @message
| sort @timestamp desc
| limit 100

Nota: Sustituye 100 en la cláusula de límite por el número de solicitudes por las que deseas filtrar. Sustituye awswaf:managed:aws:bot-control por la etiqueta del grupo de reglas. Para el grupo de reglas ATP, usa awswaf:managed:aws:atp. Para el grupo de reglas ACFP, usa awswaf:managed:aws:acfp. Para el grupo de reglas AntiDDOS AMR, usa awswaf:managed:aws:anti-ddos.

Para filtrar los registros con una etiqueta específica, incluye la siguiente línea en la consulta anterior:

| filter @message like 'awswaf:managed:aws:bot-control:signal:non_browser_user_agent'