Por que falar de GuardDuty ETD agora

Segurança em nuvem não é só “alerta na tela”. O que separa maturidade de tentativa é entender o encadeamento de eventos e responder automaticamente.
O Amazon GuardDuty Extended Threat Detection (ETD) correlaciona múltiplos sinais (APIs, logs, achados) para identificar sequências de ataque (attack sequences) e gerar um finding único e crítico que representa a história completa do ataque.

O que é o ETD, em 30 segundos

  • Detecta ataques multiestágio (ex.: credenciais comprometidas → mudança de políticas → exfiltração S3).
  • Correlaciona sinais entre fontes fundamentais (CloudTrail, VPC Flow Logs, DNS) e planos de proteção (S3, EKS, Runtime), quando habilitados.
  • Gera achados “AttackSequence:*” (ex.: AttackSequence:S3/CompromisedData, AttackSequence:IAM/CompromisedCredentials, AttackSequence:EKS/CompromisedCluster) todos com criticidade “Critical”.

Importante: ao habilitar o GuardDuty em uma Região, o ETD já vem habilitado por padrão e sem custo adicional; habilitar S3/EKS/Runtime amplia a cobertura ao adicionar mais sinais.

Casos de uso que importam pra você

  1. Compromisso de credenciais (IAM) → Enumeração, elevação e movimentação lateral culminando em acesso indevido. ETD consolida a sequência.
  2. Compromisso de dados em S3 → De permissividade indevida a exfiltração; com S3 Protection o ETD reconhece a cadeia completa.
  3. Compromisso de EKS → Da exploração de um container à persistência/crypto-mineração; com EKS Protection/Runtime Monitoring o ETD gera AttackSequence:EKS/CompromisedCluster.

Ative a base e amplie cobertura (passo a passo)

  1. Habilite o GuardDuty (por conta/Região ou via Organizations).
  2. (Opcional, recomendado) Habilite planos de proteção para mais sinais e sequências:
    • S3 Protection (dados/S3).
    • EKS Protection e/ou Runtime Monitoring (controle + runtime).
    • Malware/RDS/Lambda conforme seu escopo.

No console: GuardDuty → Extended Threat Detection (você verá Status: Enabled por padrão), e EKS Protection / Runtime / S3 Protection → Enable.

Gere achados de exemplo (útil para testar automações)

Console: Settings → Sample findings → Generate.
CLI: (exemplo de um tipo qualquer)

# Descobrir seu detector
aws guardduty list-detectors

# Gerar um sample finding específico
aws guardduty create-sample-findings \
  --detector-id <DETECTOR_ID> \
  --finding-types AttackSequence:S3/CompromisedData

Conecte com resposta automática (EventBridge + Lambda)

1) Regra do EventBridge filtrando AttackSequence

{
  "source": ["aws.guardduty"],
  "detail-type": ["GuardDuty Finding"],
  "detail": {
    "findings": {
      "type": [{ "prefix": "AttackSequence:" }],
      "severity": [{ "numeric": [">=", 7] }]
    }
  }
}

2) Lambda (Python/boto3): exemplo para credenciais comprometidas (IAM)

import json, os
import boto3

iam = boto3.client("iam")
sns = boto3.client("sns")

TOPIC_ARN = os.environ["TOPIC_ARN"]

def handler(event, context):
    detail = event["detail"]
    finding = detail["findings"][0]
    ftype = finding["type"]

    principal_arns = []
    for res in finding.get("resources", []):
        if res.get("type") == "AwsIamAccessKey":
            arn = res.get("details", {}).get("awsIamAccessKey", {}).get("principalArn")
            if arn: principal_arns.append(arn)

    for arn in set(principal_arns):
        if ":user/" in arn:
            user = arn.split(":user/")[1]
            for meta in iam.list_access_keys(UserName=user)["AccessKeyMetadata"]:
                if meta["Status"] == "Active":
                    iam.update_access_key(UserName=user,
                                          AccessKeyId=meta["AccessKeyId"],
                                          Status="Inactive")

    sns.publish(TopicArn=TOPIC_ARN,
                Subject=f"[GuardDuty ETD] Ação tomada para {ftype}",
                Message=json.dumps(finding, indent=2))
    return {"ok": True}

3) Lambda: exemplo para S3/CompromisedData

import json
import boto3

s3control = boto3.client("s3control")
account_id = boto3.client("sts").get_caller_identity()["Account"]

def handler(event, context):
    finding = event["detail"]["findings"][0]
    buckets = []
    for res in finding.get("resources", []):
        if res.get("type") == "AwsS3Bucket":
            name = res.get("id") or res.get("resourceDetails", {}).get("s3BucketDetails", [{}])[0].get("name")
            if name: buckets.append(name)

    for bucket in set(buckets):
        s3control.put_public_access_block(
            AccountId=account_id,
            PublicAccessBlockConfiguration={
                "BlockPublicAcls": True,
                "IgnorePublicAcls": True,
                "BlockPublicPolicy": True,
                "RestrictPublicBuckets": True
            }
        )
    return {"quarantined_buckets": list(set(buckets))}

Conclusão

  • Habilite o GuardDuty (ETD já vem junto) e amplie cobertura com S3/EKS/Runtime.
  • Automatize respostas para reduzir MTTD/MTTR.
  • Eduque o time: um único AttackSequence conta a história do ataque e orienta a resposta.