¿Cuáles son mis opciones para analizar los registros de AWS WAF almacenados en CloudWatch o Amazon S3?

Última actualización: 11-07-2022

Estoy almacenando mis registros de AWS WAF en Amazon CloudWatch, Amazon Simple Storage Solution (Amazon S3) o Amazon S3 como destino de mi flujo de entrega de Amazon Kinesis Data Firehose. ¿Qué opciones tengo para analizar mis registros de acceso a AWS WAF?

Resolución

Para analizar y filtrar solicitudes de registro específicas, utilice la información de Amazon CloudWatch Logs para los registros de CloudWatch o los registros de Amazon Athena para Amazon S3.

Análisis de los registros de acceso de AWS WAF con información de CloudWatch Logs

  1. Abra la consola de Amazon CloudWatch.
  2. En el panel de navegación, elija Logs (Registros) y, a continuación, Log Insights (Información de registros).
  3. En Select log group(s) (Seleccionar grupo[s] de registro), elija uno o más grupos de registros para consultar que consistan en registros de acceso de AWS WAF.
  4. (Opcional) Elija un intervalo de tiempo para el período que desea consultar.
  5. Utilice la sintaxis de consultas para diseñar consultas.
  6. Elija Run ( Ejecutar) para ver los resultados del grupo de registro.

A continuación, se muestran ejemplos de consultas que puede utilizar para filtrar información específica de CloudWatch Logs Insights:

Filter on a specific string (Filtrar por una cadena específica)

Ejecute esta consulta para filtrar el registro en función de una cadena específica:
Nota: Sustituya la cadena {jndi:ldap. por la cadena en la que desee buscar.

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

Filter by host (Filtrar por host)

Ejecute esta consulta para filtrar por host:
Nota: Reemplace el valor de host www.example.com por el host en el que desea buscar.

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

Filter on POST requests (Filtrar en solicitudes POST)

Ejecute esta consulta para aislar cualquier solicitud POST:

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

Filter on UserAgent (Filtrar en UserAgent)

Ejecute esta consulta para filtrar por UserAgent:
Nota: Sustituya User-Agent-Value por su valor para UserAgent.

parse @message /\{"name":"[Uu]ser\-[Aa]gent\",\"value\"\:\"(?<UserAgent>[^"}]*)/
| filter UserAgent like "<User-Agent-Value>"
| fields terminatingRuleId as Rule, action, httpRequest.country as Country, httpRequest.clientIp as ClientIP, httpRequest.uri as URI

Filter requests not originating from a country (Filtrar solicitudes que no se originan en un país)

Ejecute esta consulta para filtrar las solicitudes que no se originan en un país específico:

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

Filter for cross-site scripting or SQL injection (Filtrar por scripting entre sitios o inyección de código SQL)

Ejecute esta consulta para filtrar por scripting entre sitios o inyección de código SQL:

fields @timestamp, terminatingRuleId, action, httpRequest.clientIp as ClientIP, httpRequest.country as Country, terminatingRuleMatchDetails.0.conditionType as ConditionType, terminatingRuleMatchDetails.0.location as Location, terminatingRuleMatchDetails.0.matchedData.0 as MatchedData
| filter ConditionType in["XSS","SQL_INJECTION"]

Time series based on a terminating rule (Series temporales basadas en una regla de terminación)

Ejecute esta consulta para filtrar una serie temporal en función de una regla de terminación:

#Time Series by Terminating Rule
filter terminatingRuleId = "AWS-AWSManagedRulesCommonRuleSet"
| stats count(*) as requestCount by bin(30m)

Summarize blocked requests by ClientIP, country, URI, and rule (Resumir las solicitudes bloqueadas por información de cliente, país, URI y regla)

Ejecute esta consulta para resumir las solicitudes bloqueadas por ClientIP, país, URI y regla:

fields httpRequest.clientIp as ClientIP, httpRequest.country as Country, httpRequest.uri as URI, terminatingRuleId as Rule
| filter action = "BLOCK"
| stats count(*) as RequestCount by Country, ClientIP, URI, Rule
| sort RequestCount desc

Top client IPs (IP de clientes principales)

Ejecute esta consulta para contar las IP de los principales clientes:

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

Top countries (Principales países)

Ejecute esta consulta para contar los principales países:

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

Top hosts (Hosts principales)

Ejecute esta consulta para contar los hosts principales:

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

Top methods (Métodos principales)

Ejecute esta consulta para contar los métodos principales:

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

Top terminating rules (Reglas de terminación principales)

Ejecute esta consulta para contar las reglas de terminación principales:

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

Top UserAgents (UserAgents principales)

Ejecute esta consulta para contar los principales UserAgents:

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

Request not terminated by Default_Action or rules with action ALLOW (Solicitud no finalizada por Default_Action o reglas con acción ALLOW)

Ejecute esta consulta para filtrar por solicitudes no finalizadas por Default_Action o reglas con una acción ALLOW:

fields @timestamp, terminatingRuleId, action, @message
| filter terminatingRuleId != 'Default_Action' and action != 'ALLOW'
| sort @timestamp desc

Request with invalid Captcha token (Solicitud con token de Captcha no válido)

Ejecute esta consulta para filtrar por solicitudes con un token Captcha no válido:

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

Request block by rate-based rule (Solicitud de bloqueo por regla basada en tasas)

Ejecute esta consulta para filtrar por solicitudes bloqueadas por una regla basada en tasas:

fields @timestamp, httpRequest.clientIp, terminatingRuleId, httpRequest.country,@message
| filter terminatingRuleType ="RATE_BASED" ## and webaclId = "arn:aws:wafv2:us-east-1:xxxxxxxx:regional/webacl/waf-test/abcdefghijkl" ## uncomment to filter for specific WebACL
| sort requestCount desc

Filter all request detected by AWS Bot Control (ABC) (Filtrar todas las solicitudes detectadas por AWS Bot Control [ABC])

Ejecute esta consulta para filtrar todas las solicitudes detectadas por ABC:

fields @timestamp, @message
|filter @message like 'awswaf:managed:aws:bot-control'
| parse @message '"labels":[*]' as Labels
| sort @timestamp desc

Análisis de los registros de acceso de AWS WAF con Amazon Athena

Puede activar el registro de acceso de AWS WAF directamente en un bucket de Amazon S3. O bien, puede usar el flujo de entrega de Amazon Kinesis Data Firehose para entregar sus registros de acceso de AWS WAF a un bucket de Amazon S3. Para almacenar registros en Amazon S3, consulte How do I configure AWS WAF comprehensive logging to store logs in Amazon S3? (¿Cómo debo configurar el registro integral de AWS WAF para almacenar registros en Amazon S3?)

Cuando los registros de acceso estén en el bucket de Amazon S3, cree la tabla de AWS WAF para usar Amazon Athena y consultar registros y filtrar diversos detalles.

Estas consultas son ejemplos que puede utilizar para consultar los registros de AWS WAF con Athena:

Blocked request with AWS WAF rule information (Solicitudes bloqueadas con información de reglas de AWS WAF)

Ejecute esta consulta de Athena para enumerar todas las solicitudes bloqueadas con la regla de AWS WAF:

SELECT timestamp,
    action,
    httpsourcename,
    httpsourceid,
    httprequest.requestID,
    httprequest.clientip,
    webaclid,
    terminatingruleid,
    terminatingruletype,
    rulegrouplist,
    terminatingrulematchdetails
FROM "wafv2"."waf_logs"
WHERE ("action" LIKE 'BLOCK')

Request User Agent (Solicitar agente de usuario)

Ejecute esta consulta de Athena para solicitar el agente de usuario:
Nota: Sustituya User-Agent por su valor para UserAgent.

select n.value, count(n.value) as count
from waf_logs
cross join
unnest(
  cast(
    httprequest.headers as ARRAY(ROW(name VARCHAR, value VARCHAR))
    )
  ) as x(n)
where n.name = 'User-Agent'
group by n.value
ORDER BY count(n.value) DESC

Request URI (URI de solicitud)

Ejecute esta consulta de Athena para comprobar el URI de la solicitud:

SELECT
"httprequest"."uri"
, "count"(*) "count"
FROM
  waf_logs
WHERE ("action" LIKE 'BLOCK')
GROUP BY "httprequest"."uri"
ORDER BY "count" DESC

Count blocked requests based on ClientIP (Contar las solicitudes bloqueadas según la ClientIP)

Ejecute esta consulta de Athena para ver el recuento de solicitudes bloqueadas según el valor de ClientIP y el país:

SELECT
  "httprequest"."clientip"
, "count"(*) "count"
, "httprequest"."country"
FROM
waf_logs
WHERE ("action" LIKE 'BLOCK')
GROUP BY "httprequest"."clientip", "httprequest"."country"
ORDER BY "count" DESC

Ver recuento de solicitudes

Ejecute esta consulta de Athena para ver el recuento de solicitudes:

SELECT 
  "httprequest"."clientip"
, "count"(*) "count"
,"httprequest"."country"
FROM
 waf_logs
WHERE ("action" LIKE
'BLOCK')
GROUP BY
"httprequest"."clientip", "httprequest"."country"
ORDER BY "count" DESC

Para ver ejemplos adicionales de consultas de Athena, consulte Example queries for AWS WAF logs (Consultas de ejemplo para los registros de AWS WAF).


¿Le resultó útil este artículo?


¿Necesita asistencia técnica o con la facturación?