XUT_ / COURSES / PENETRATION TESTER

Introduction to Rules

En el corazón de cada WAF vive el conjunto de reglas: una colección de declaraciones condicionales que definen cuándo es permitido, registrado o bloqueado el tráfico. Estas reglas son legibles para los humanos.


Ejemplo Real de Regla

La mejor manera de aprender sobre estas reglas es profundizar sobre una. La siguiente regla es para SQLi y es del OWASP CRS v3.3.7:

SecLang
SecRule REQUEST_BASENAME "@detectSQLi" \
    "id:942101,\
    phase:2,\
    block,\
    capture,\
    t:none,t:utf8toUnicode,t:urlDecodeUni,t:removeNulls,\
    msg:'SQL Injection Attack Detected via libinjection',\
    logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
    tag:'application-multi',\
    tag:'language-multi',\
    tag:'platform-multi',\
    tag:'attack-sqli',\
    tag:'OWASP_CRS',\
    tag:'capec/1000/152/248/66',\
    tag:'PCI/6.5.2',\
    tag:'paranoia-level/3',\
    ver:'OWASP_CRS/3.3.7',\
    severity:'CRITICAL',\
    setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\
    setvar:'tx.anomaly_score_pl3=+%{tx.critical_anomaly_score}'"

El trigger: SecRule REQUEST_BASENAME "@detectSQLi"

En la primera linea, tenemos lo siguiente:

  • SecRule: Directiva de ModSecurity estándar para definir una regla.
  • REQUEST_BASENAME: Esta variable se refiere al nombre del archivo o endpoint en la ruta URL. Por ejemplo, en /api/user/123 el basename es 123.
  • "@detectSQLi": Es una llamada a libinjection, una librería C especializada diseñada sólo para detectar inyecciones SQL.

Rule Metadata: Identity, Context, and Compliance En las siguientes cuatro lineas tenemos lo siguiente:

  • id:942101: Identificador único (parte del esquema de numeración CRS).
  • phase:2: Corre durante el procesado del body de la petición (después de los headers, antes de la lógica de la app).
  • block: Toma acción: rechaza la petición.
  • capture: Guarda el payload con coincidencia para registro (%{TX.0}).

Input Normalisation: Seeing Through the Noise Antes de que @detectSQLi corra, el input es normalizado a través de una pipeline de transformaciones:

  • t:none: Comienza con input crudo.
  • t:utf8toUnicode: Convierte las secuencias UTF-8 a Unicode para prevenir bypass vía encoding.
  • t:urlDecodeUni: Realiza decoding recursivo de la URL (%2527 se decodea en %27 que se decodea en ').
  • t:removeNulls: Corta bytes nulos (%00), normalmente usados para terminar strings en parsers basados en C.

Es crucial decodear los contenidos antes de comprobar, de otra forma, sería fácil perderse amenazas encodeadas.

Logging and Attribution: Making Incidents Actionable En las siguientes dos líneas, registramos una alerta legible por humanos:

SecLang
msg:'SQL Injection Attack Detected via libinjection',\
logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
  • msg: Alerta humanamente legible que se muestra en logs y SIEM.
  • logdata: Detalle forense rico.
    • %{TX.0}: El payload exacto que disparó la regla.
    • %{MATCHED_VAR_NAME}: Qué variable fue inspeccionada.
    • %{MATCHED_VAR}: El valor completo de la variable.

Tags: Connecting to Standards and Strategy Ahora es hora de etiquetar el tráfico. Los tags no son sólo etiquetas, sino que son ganchos operacionales. Considera el siguiente ejemplo:

SecLang
tag:'attack-sqli'
tag:'OWASP_CRS'
tag:'capec/1000/152/248/66'
tag:'PCI/6.5.2'
tag:'paranoia-level/3'

Las lineas de arriba indican lo siguiente:

  • capec/1000/152/248/66: Se relaciona con CAPEC (Common Attack Pattern Enumeration).
  • PCI/6.5.2: Hace referencia a PCI DSS requirement para proteger contra debilidades de inyección.
  • paranoia-level/3: CRS usa cuatro niveles de paranoia. PL3 es más estricto y bloquea más, pero tiene más falsos positivos.

Scoring and Telemetry: Feeding the Anomaly Engine Finalmente, podemos usar el tráfico detectado para actualizar nuestra puntuación de riesgos. Echa un vistazo más cercano a las siguientes dos lineas:

SecLang
setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'
setvar:'tx.anomaly_score_pl3=+%{tx.critical_anomaly_score}'

Hacen lo siguiente:

  • tx.sql_injection_score: Rastrea riesgo acumulativo SQLi a lo largo de múltiples reglas.
  • tx.anomaly_score_pl3: Le da al CRS la puntuación con nivel de paranoia 3.