Forense y caza de amenazas en la nube
Consultar CloudTrail con Athena y CloudTrail Lake, reconstruir la línea de tiempo de un atacante, y la detección como código (Sigma, consultas guardadas) frente a la caza proactiva de una hipótesis.
Cuando salta una alerta, ya sabes qué buscar. El forense y la caza empiezan donde la alerta no llega: tienes millones de eventos de CloudTrail y la sospecha de que algo pasó, pero ninguna regla preexistente te lo va a señalar. El trabajo es convertir ese ruido en una narrativa: quién entró, qué miró, qué se llevó y cuándo. Esta nota es sobre las herramientas (Athena, CloudTrail Lake, Sigma) y, sobre todo, sobre la mentalidad.
Paso 1 de 7Ruido
CloudTrail registra millones de eventos legítimos. Mirar la lista cruda no te dice nada: el rastro de un atacante está ahí, disuelto entre la actividad normal.
Responder a una alerta no es cazar#
Son dos actividades distintas y las necesitas ambas:
- Responder es reactivo. Una detección salta (
Exfiltration:S3/AnomalousBehavior) y ejecutas el playbook. El punto de partida te lo da la herramienta. - Cazar es proactivo y parte de una hipótesis tuya: “si nos hubieran robado una clave de CI, veríamos reconocimiento multiservicio seguido de descargas de S3 desde una IP nueva”. Escribes una consulta para confirmarla o descartarla. Encuentras lo que ninguna regla estaba buscando, y lo haces sin esperar a que el daño dispare una alerta.
La cazaThreat huntingBúsqueda proactiva de actividad maliciosa a partir de una hipótesis, sin esperar a que salte una alerta. tiene un retorno compuesto: cada hipótesis que resulta cierta se convierte en una detección guardada. Lo que hoy cazas a mano, mañana lo detecta una regla.
El terreno: consultar CloudTrail#
Dos formas de hacer SQL sobre CloudTrail, según dónde vivan tus logs:
Un event data storeCloudTrail LakeAlmacén gestionado de eventos de CloudTrail que se consulta con SQL (dialecto basado en Trino), pensado para investigación y auditoría. gestionado, consultable con SQL (dialecto basado en Trino) durante años, sin montar tú tablas ni particiones. Ideal para investigación puntual y auditoría. La consulta que reconstruye la actividad de una credencial:
SELECT eventTime, eventName, eventSource, sourceIPAddress, userAgent, errorCodeFROM <event-data-store-id>WHERE userIdentity.accessKeyId = 'AKIA...7QXZ' AND eventTime >= '2026-10-01 00:00:00' AND eventTime <= '2026-10-11 00:00:00'ORDER BY eventTime ASC;SQL (Trino/Presto) sobre los logs crudos de CloudTrail en S3. Más barato a gran escala y el camino natural si ya centralizas en Security Lake. Ojo: eventtime es una cadena ISO 8601, así que para comparar fechas se parsea con from_iso8601_timestamp.
SELECT useridentity.arn, sourceipaddress, count(*) AS calls, count_if(eventname LIKE 'List%' OR eventname LIKE 'Describe%') AS reconFROM cloudtrail_logsWHERE from_iso8601_timestamp(eventtime) > current_timestamp - interval '2' day AND useridentity.type = 'IAMUser'GROUP BY 1, 2HAVING count_if(eventname LIKE 'List%' OR eventname LIKE 'Describe%') > 50;Construir la línea de tiempo del atacante#
El forense no es una consulta, es un relato ordenado. El patrón de trabajo:
- Ancla en un indicador firme: una
accessKeyId, una IP, un ARN de rol asumido. - Expande a su alrededor: todo lo que hizo ese ancla, ordenado por
eventTime, y pivota a nuevos anclas que aparezcan (una clave que creó, un rol que asumió). - Clasifica cada evento por táctica (acceso inicial, descubrimiento, persistencia, exfiltración) hasta que la secuencia cuente una historia con principio y final.
Clasificar por táctica es justo lo que hace el explainer de arriba: eventos sueltos → ConsoleLogin y GetCallerIdentity (acceso inicial) → ListBuckets, DescribeInstances (descubrimiento) → GetObject masivo (exfiltración). El pivote más útil: cuando un evento revela un recurso nuevo (un rol asumido con AssumeRole), repites la consulta anclando en él.
Detección como código#
La consulta que te sirvió para cazar no se tira: se versiona, se revisa y se despliega como detección. Es el mismo salto que dio la infraestructura con IaC.
Reglas SigmaSigmaFormato abierto en YAML para escribir reglas de detección sobre logs, portable entre distintos SIEM y backends de consulta. expresan la detección en YAML portable, independiente del backend. El repositorio SigmaHQ trae reglas de CloudTrail que puedes traducir a tu SIEM, Athena u OpenSearch con sigma-cli:
title: Desactivación del registro de CloudTraillogsource: product: aws service: cloudtraildetection: selection: eventSource: cloudtrail.amazonaws.com eventName: - StopLogging - DeleteTrail - UpdateTrail condition: selectionlevel: highConsultas guardadas en Security Lake son el otro formato: la misma lógica contra datos ya normalizados a OCSF (Parquet), lista para ejecutarse de forma recurrente o en cuanto surja una nueva hipótesis. La centralización en OCSF es lo que te permite cazar cruzando CloudTrail, Flow Logs y DNS en una sola consulta; está en registro y Security Lake.
Errores habituales#
Tu turno
Caza una hipótesis en tu laboratorio
En una cuenta sandbox propia:
- Detona una cadena con Stratus Red Team (p. ej. backdoor de usuario + descarga de S3).
- Formula la hipótesis por escrito antes de consultar: ¿qué eventos esperarías ver y en qué orden?
- Escribe la consulta (Athena o CloudTrail Lake) que ancla en tu identidad de prueba y ordena por
eventTime. Reconstruye la línea de tiempo y clasifícala por táctica. - Convierte la consulta que funcionó en una regla Sigma y tradúcela con
sigma-cli.
Reto
Tu consulta de Athena filtra por fecha y no devuelve nada, aunque sabes que hay eventos. ¿Por qué?
▸Mostrar solución
Porque en la tabla cloudtrail_logs, eventtime es una cadena ISO 8601, no un timestamp.
Comparar eventtime > now() compara textos. Hay que parsearla:
from_iso8601_timestamp(eventtime) > current_timestamp - interval '1' day.
Reto
¿Cuál es la diferencia práctica entre responder y cazar?
▸Mostrar solución
Responder parte de una alerta que ya existe (reactivo); cazar parte de una hipótesis tuya y busca lo que ninguna regla señala (proactivo). La caza alimenta a la respuesta: cada hallazgo confirmado se convierte en una detección guardada que mañana saltará sola.
En resumen#
- Responder es reactivo (parte de una alerta); cazar es proactivo (parte de una hipótesis). Necesitas las dos.
- CloudTrail Lake (SQL Trino, retención larga, cero montaje) para investigación puntual; Athena sobre Security Lake para escala —recuerda parsear
eventtimeconfrom_iso8601_timestamp. - El forense es ordenar en una narrativa: ancla en un indicador, expande por
eventTime, pivota a nuevos anclas y clasifica por táctica. - Detección como código: reglas Sigma (YAML portable) y consultas guardadas en Security Lake (OCSF). La caza de hoy es la alerta automática de mañana.
- Sin retención, sin eventos de datos y sin logs inmutables, no hay forense posible.