Eventos de CloudTrail que vigilar, mapeados a MITRE ATT&CK
Los eventos de CloudTrail que todo analista de respuesta en AWS debe conocer, del reconocimiento al impacto, con sus campos de evidencia y sus técnicas ATT&CK.
En resumen. No hace falta conocer miles de nombres de API de AWS. Una cincuentena de nombres de eventos cubren la ruta de ataque habitual en AWS: GetCallerIdentity y ráfagas de List/Describe (reconocimiento), CreateUser / CreateAccessKey / CreateLoginProfile (persistencia), AttachUserPolicy con AdministratorAccess (escalada de privilegios), StopLogging / DeleteDetector (evasión de defensas), ráfagas de GetObject / ModifySnapshotAttribute (exfiltración), RunInstances de GPU / ScheduleKeyDeletion (impacto). Las tablas siguientes indican, para cada uno, el origen del evento, los campos que contienen la evidencia y la técnica de MITRE ATT&CK correspondiente.
Cada tabla de este artículo corresponde a una regla del conjunto de reglas abierto del analizador, de modo que lo que lee aquí es exactamente lo que comprueba la herramienta. Las tablas están organizadas por táctica, en el orden en que suele desarrollarse una intrusión.
Campos que se leen en cada evento
| Campo | Qué le indica |
|---|---|
eventTime | Hora UTC de la solicitud |
eventSource / eventName | Servicio y API, por ejemplo iam.amazonaws.com / CreateUser |
userIdentity.type | Root, IAMUser, AssumedRole, FederatedUser, AWSService… |
userIdentity.arn, accessKeyId | Quién y con qué credencial (AKIA de larga duración, ASIA temporal) |
sourceIPAddress, userAgent | Desde dónde y con qué cliente |
errorCode, errorMessage | Ausentes cuando la llamada tuvo éxito |
requestParameters, responseElements | Qué se pidió y qué se creó |
awsRegion, recipientAccountId | Dónde ocurrió |
AWS documenta el esquema completo en la referencia del contenido de los registros de CloudTrail y en la del elemento userIdentity.
Acceso inicial y abuso de credenciales
| Evento | Evidencia que leer | ATT&CK |
|---|---|---|
Cualquier llamada con una clave AKIA desde una IP nueva | accessKeyId, sourceIPAddress, userAgent | T1078.004, T1552.001 |
Cualquier llamada con userIdentity.type = Root | IP de origen; el usuario raíz casi nunca debería actuar | T1078.004 |
ConsoleLogin (signin) | responseElements.ConsoleLogin = Success/Failure, additionalEventData.MFAUsed | T1078.004 |
Fallos repetidos de ConsoleLogin desde una misma IP | Recuento por IP cada 15 min | T1110 |
Descubrimiento
| Evento | Evidencia que leer | ATT&CK |
|---|---|---|
sts:GetCallerIdentity con una clave de larga duración | Primera llamada desde una dirección nueva | T1087.004 |
Muchos List* / Describe* / Get* distintos en pocos minutos | Recuento de eventName distintos por clave | T1580, T1526 |
iam:GetAccountAuthorizationDetails | Volcado completo de IAM en una sola llamada | T1087.004 |
Ráfaga de AccessDenied / UnauthorizedOperation | errorCode por principal | T1069.003 |
GetCallerIdentity no requiere permisos y la propia CLI la invoca, así que por sí sola tiene una gravedad baja. Adquiere importancia cuando es el primer evento procedente de una dirección desconocida.
Persistencia
| Evento | Evidencia que leer | ATT&CK |
|---|---|---|
iam:CreateUser | requestParameters.userName | T1136.003 |
iam:CreateAccessKey para otro usuario | requestParameters.userName ≠ quien llama; nueva clave en responseElements.accessKey.accessKeyId | T1098.001 |
iam:CreateLoginProfile / UpdateLoginProfile | Contraseña de consola en un usuario | T1098 |
iam:UpdateAssumeRolePolicy | Nuevos principales en los que confía un rol | T1098 |
iam:CreateSAMLProvider, CreateOpenIDConnectProvider, UpdateOpenIDConnectProviderThumbprint | Nueva relación de confianza de federación | T1484.002 |
lambda:AddPermission con principal *, CreateFunctionUrlConfig con authType: NONE | Función de puerta trasera pública | T1546, T1648 |
ec2:ModifyInstanceAttribute con userData | Script que se ejecuta en el siguiente arranque | T1059 |
ec2:CreateKeyPair / ImportKeyPair | Acceso SSH a instancias nuevas | T1098.004 |
Escalada de privilegios
| Evento | Evidencia que leer | ATT&CK |
|---|---|---|
AttachUserPolicy / AttachRolePolicy / AttachGroupPolicy | policyArn que termina en AdministratorAccess o IAMFullAccess | T1098.003 |
PutUserPolicy / PutRolePolicy / CreatePolicyVersion | Documento de política con "Action": "*" sobre "Resource": "*" | T1098.003 |
AddUserToGroup | Nombre de grupo que sugiere permisos de administrador | T1098 |
Evasión de defensas
| Evento | Evidencia que leer | ATT&CK |
|---|---|---|
cloudtrail:StopLogging, DeleteTrail | Nombre del trail, región | T1562.008 |
cloudtrail:UpdateTrail, PutEventSelectors | Destino o selectores modificados | T1562.008 |
guardduty:DeleteDetector, UpdateDetector (desactivado), CreateIPSet, filtros de archivado | ID del detector, región | T1562.001 |
config:StopConfigurationRecorder, DeleteDeliveryChannel | Región | T1562.001 |
securityhub:DisableSecurityHub, macie2:DisableMacie, inspector2:Disable, detective:DeleteGraph | Servicio | T1562.001 |
s3:PutBucketLogging sin destino | Registro de acceso desactivado | T1562.008 |
ec2:DeleteFlowLogs | Registro de red eliminado | T1562.008 |
logs:DeleteLogGroup / DeleteLogStream | Evidencias destruidas | T1070 |
ec2:AuthorizeSecurityGroupIngress con 0.0.0.0/0 | Cortafuegos abierto | T1562.007 |
| Escrituras en una región no utilizada antes | awsRegion | T1535 |
El artículo sobre evasión de defensas explica cómo interpretar el hueco que deja un StopLogging.
Acceso a credenciales y exfiltración
| Evento | Evidencia que leer | ATT&CK |
|---|---|---|
secretsmanager:GetSecretValue / BatchGetSecretValue sobre muchos secretos | secretId distintos por principal | T1555.006 |
Ráfagas de s3:GetObject (evento de datos) | Recuento por principal y bucket; additionalEventData.bytesTransferredOut | T1530 |
s3:PutBucketPolicy con Principal: "*", PutBucketAcl con AllUsers | Bucket hecho público | T1530 |
DeleteBucketPublicAccessBlock / PutPublicAccessBlock debilitado | Barrera de protección eliminada | T1530 |
ec2:ModifySnapshotAttribute, ModifyImageAttribute, rds:ModifyDBSnapshotAttribute | createVolumePermission / restore compartido con una cuenta ajena o con all | T1537 |
GetObject es un evento de datos: solo aparece si el trail se configuró para registrarlo. Consulte las evidencias de exfiltración de datos de S3.
Impacto
| Evento | Evidencia que leer | ATT&CK |
|---|---|---|
ec2:RunInstances con tipos de instancia p* / g* | instanceType, awsRegion | T1496 |
servicequotas:RequestServiceQuotaIncrease | quotaCode, región | T1496 |
Muchos Delete* / Terminate* de un mismo principal | Recuento cada 10 min | T1485 |
kms:ScheduleKeyDeletion, DisableKey | ID de la clave | T1485, T1486 |
Convertir la lista en alertas
La recomendación de la propia AWS es enviar el trail a CloudWatch Logs y crear filtros de métricas y alarmas sobre eventos como estos (guía de re:Post); las reglas de EventBridge también sirven. Para una investigación a posteriori basta con filtrar las exportaciones, o bien soltarlas en el analizador, que evalúa estas reglas sobre cada registro y vincula cada hallazgo con sus técnicas de ATT&CK. La guía de análisis paso a paso muestra cómo confirmarlos.